# 云歌 Credential Provider 测试操作手册

> 适用环境：Windows 10（服务器虚拟化虚拟机）x64，虚拟机工作目录 `C:\Users\Tom\Desktop\`
> 组件版本：第一阶段（认证码演示规则：`123456`）
> CLSID：`{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}`
> DLL 名称：`SampleV2CredentialProvider.dll`（必须放 `C:\Windows\System32\`）

---

## 0. 环境准备检查（一次性）

```powershell
# 管理员 PowerShell 中逐项确认
[Environment]::Is64BitOperatingSystem          # 必须 True
$PSVersionTable.PSVersion                      # 确认是 64 位 PowerShell（见下方说明）

# 确认使用的是 64 位 PowerShell（32 位会写错注册表视图！）
# 正确的启动方式：
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

# DLL 是否就位
Test-Path C:\Windows\System32\SampleV2CredentialProvider.dll
```

⚠️ **测试前必须确认虚拟机当前账户的密码是已知的**（用例 4 需要真实密码）。
若新建虚拟机时没有设置密码，请先设置：`net user 你的用户名 你的密码`

---

## 1. 部署（每次更新 DLL 后重复）

```powershell
# 1) 复制 DLL（先把它拷到虚拟机桌面，再替换进 System32）
Copy-Item "C:\Users\Tom\Desktop\SampleV2CredentialProvider.dll" "C:\Windows\System32\" -Force

# 2) 注册（方式 A：有 reg 文件）
regedit /s "C:\Users\Tom\Desktop\register.reg"

# 2) 注册（方式 B：纯命令行，与 register.reg 等价）
$guid = "{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}"
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$guid" /ve /d "YungeCredentialProvider" /f
reg add "HKCR\CLSID\$guid" /ve /d "YungeCredentialProvider" /f
reg add "HKCR\CLSID\$guid\InprocServer32" /ve /d "SampleV2CredentialProvider.dll" /f
reg add "HKCR\CLSID\$guid\InprocServer32" /v ThreadingModel /d "Apartment" /f
```

> 无需 `regsvr32`。凭据提供者纯靠注册表被 LogonUI 加载，`InprocServer32` 只写文件名即代表 System32 目录。

### 部署后自检（三条都必须有输出）

```powershell
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}"
reg query "HKCR\CLSID\{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}\InprocServer32"
Test-Path C:\Windows\System32\SampleV2CredentialProvider.dll
```

---

## 2. 进入登录界面

```powershell
shutdown /l        # 注销（推荐，无需重启）
# shutdown /r /f   # 若注销后磁贴没出现，再重启排除缓存因素
# 锁屏测试场景：Win + L（provider 同样支持解锁）
```

---

## 3. 测试用例清单

| # | 操作 | 预期结果 | 验证点 | 结果 |
|---|------|---------|--------|------|
| 1 | 进入登录界面观察 | "Yunge Authentication" 磁贴**默认放大选中**；字段：用户名(预填 `机器名\账户名`)、云歌认证码(自动聚焦)、密码、登录按钮；原生密码磁贴仍在 | 界面接管 + 默认入口 | ☐ |
| 2 | 认证码留空或 `123`，密码任意 → 登录 | 显示 **"云歌认证失败：认证码需为 6 位数字"**，不发起系统登录 | 自定义拦截 | ☐ |
| 3 | 认证码 `111111` → 登录 | 显示 **"云歌认证失败：认证码无效"** | 认证规则 | ☐ |
| 4 | 认证码 `123456` + 正确密码 → 登录 | 正常进入桌面 | 通过后交还 Windows 建立会话 | ☐ |
| 5 | 认证码 `123456` + 错误密码 → 登录 | 显示 **"用户名或密码错误。"**，密码框被清空 | ReportResult 回传 | ☐ |
| 6 | 选其他磁贴再切回 | 认证码与密码框均已清空 | SetDeselected 清理 | ☐ |
| 7 | Win+L 锁屏后重复用例 2/4 | 行为与登录界面一致 | 解锁场景 | ☐ |

---

## 4. 查看内部调试日志（可选）

登录界面无法直接看输出，用 Sysinternals DebugView：

1. 下载 DebugView（x64 版），**以管理员身份运行**；
2. Options → 勾选 `Capture Win32` 和 `Capture Global Win32`；
3. 注销前保持 DebugView 运行（Global 抓取需要服务级权限，登录界面侧输出有限，能看到多少算多少）；
4. 认证码错误时应出现：
   ```
   Yunge CredentialProvider: custom authentication rejected the logon attempt.
   ```

更可靠的方式是观察磁贴上的中文错误文案，它直接来自认证模块返回值。

---

## 5. 更新 DLL 的推荐流程（反复优化时用）

```text
桌面改代码 → 重新编译(Release x64) → 拷入虚拟机
→ 在虚拟机桌面替换 System32 的 DLL（此刻 LogonUI 未持有旧实例可成功）
   若提示"文件正在使用"：说明上次有 LogonUI 残留，重启虚拟机后第一时间替换
→ 注销 → 测试
```

替换命令：

```powershell
Copy-Item "C:\Users\Tom\Desktop\SampleV2CredentialProvider.dll" "C:\Windows\System32\" -Force
```

> 注册表信息不随 DLL 内容变化，重复测试**不需要**反复注册/反注册，只换 DLL 文件即可。

---

## 6. 回退 / 卸载

### 仅回退（保留 DLL 文件）

```powershell
$guid = "{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}"
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$guid" /f
reg delete "HKCR\CLSID\$guid" /f
shutdown /l    # 注销后磁贴消失，恢复原生登录
```

或使用文件：`regedit /s Unregister.reg`（效果相同）

### 彻底卸载

```powershell
# 先执行上面的回退，然后删除 DLL（若被占用则重启后再删）
Remove-Item C:\Windows\System32\SampleV2CredentialProvider.dll -Force
```

### 验证已干净

```powershell
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}"   # 应报"找不到"
Test-Path C:\Windows\System32\SampleV2CredentialProvider.dll   # 彻底卸载后应为 False
```

---

## 7. 常见问题排查

| 现象 | 最可能原因 | 处理 |
|------|-----------|------|
| 磁贴完全不出现 | 注册表写进了 32 位视图 | 用 64 位 PowerShell 重新执行第 1 步注册命令；`reg query "HKLM\SOFTWARE\Classes\CLSID\{A1F3C6D2-...}"` 应能查到 |
| 磁贴完全不出现 | DLL 位数不对（放了 Win32 产物） | 确认编译选择的是 **x64** 平台；虚拟机系统是 64 位 |
| 磁贴出现但字段/文案是旧版 | System32 里还是旧 DLL | 第 5 节流程重新替换 + 重启一次 |
| 登录后提示"登录信息已过时" | LogonUI 缓存旧 DLL | 重启虚拟机 |
| 中文显示为乱码 | 源文件编码被改动后重编译 | 保持工程文件原始 UTF-8 编码重新编译（本项目中文均用 `\u` 转义，正常不会发生） |
| 把自己锁在外面 | 理论不会（原生磁贴保留） | 用原生密码磁贴登录；无法进桌面时用虚拟机快照回滚 |
| 虚拟机反复测试想快速还原 | — | **建议对虚拟机打快照**：注册前打一个"干净快照"，每轮破坏性测试后直接回滚 |

---

## 8. 关键标识速查

```text
CLSID        {A1F3C6D2-7B54-4E9A-B8C1-3D6E2F0A97B5}
CP 注册键     HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{CLSID}
COM 注册键    HKCR\CLSID\{CLSID}\InprocServer32 = SampleV2CredentialProvider.dll (Apartment)
DLL 位置      C:\Windows\System32\SampleV2CredentialProvider.dll
演示认证码     123456（6 位数字规则，见 Authenticator.cpp）
```
