Windows Credential Providers V2 C# 多用户凭据显示问题求助
问题分析与解决方案
核心问题在于你使用**单个变量_pCredential**存储凭据实例,循环中每次创建新的CSharpSampleCredential都会覆盖之前的实例,最终系统只能识别到最后一个用户的凭据。要为每个用户生成独立凭据,需要用集合存储所有实例,并适配Windows凭据提供者的接口方法。
步骤1:替换单个变量为集合
在你的凭据提供者类中,将单个_pCredential变量替换为一个集合,用于存储所有用户的凭据:
// 替换原有的单个_pCredential变量 private List<ICredentialProviderCredential> _credentials = new List<ICredentialProviderCredential>();
步骤2:修改EnumerateCredentials方法
修改循环逻辑,将每个初始化成功的凭据添加到集合中,而不是覆盖单个变量:
int EnumerateCredentials() { Log.LogMethodCall(); int hr = HResultValues.E_UNEXPECTED; // 清空旧凭据集合 _credentials.Clear(); if (_pCredProviderUserArray != null) { uint dwUserCount = 0; _pCredProviderUserArray.GetCount(out dwUserCount); if (dwUserCount > 0) { for (uint i = 0; i < dwUserCount; i++) { ICredentialProviderUser pCredUser; hr = _pCredProviderUserArray.GetAt(i, out pCredUser); if (hr >= 0) { var credential = new CSharpSampleCredential(); if (credential != null) { hr = credential.Initialize(_cpus, Field.s_rgCredProvFieldDescriptors, Field.s_rgFieldStatePairs, pCredUser); if (hr >= 0) { // 初始化成功,将凭据加入集合 _credentials.Add(credential); } else { // 初始化失败,释放资源 var intPtr = Marshal.GetIUnknownForObject(credential); Marshal.Release(intPtr); } } else { hr = HResultValues.E_OUTOFMEMORY; } // 释放用户对象资源 var userPtr = Marshal.GetIUnknownForObject(pCredUser); Marshal.Release(userPtr); } // 中途出错则终止循环 if (hr < 0) break; } // 所有用户处理完成后返回成功状态 if (hr >= 0) hr = HResultValues.S_OK; } } return hr; }
步骤3:适配凭据提供者接口方法
需要修改GetCredentialCount和GetCredentialAt方法,让系统能从集合中获取所有凭据:
修改GetCredentialCount
int ICredentialProvider.GetCredentialCount(out uint pdwCount, out uint pdwDefault, out int pbAutoLogonWithDefault) { pdwCount = (uint)_credentials.Count; pdwDefault = 0; // 设置默认选中的凭据索引(比如第一个用户) pbAutoLogonWithDefault = 0; // 关闭默认自动登录 return HResultValues.S_OK; }
修改GetCredentialAt
int ICredentialProvider.GetCredentialAt(uint dwIndex, out ICredentialProviderCredential ppCredential) { ppCredential = null; // 索引超出范围返回错误 if (dwIndex >= _credentials.Count) return HResultValues.E_INVALIDARG; ppCredential = _credentials[(int)dwIndex]; return HResultValues.S_OK; }
关键说明
- 集合会保留每个用户对应的凭据实例,避免被覆盖
- 接口方法通过索引从集合中取出对应凭据,让系统能显示所有用户的登录项
- 注意资源释放:初始化失败的凭据要及时释放COM引用,避免内存泄漏
内容的提问来源于stack exchange,提问作者Jose alberto
相关产品推荐
相关产品推荐

