我必须记住 wpf 应用程序中的用户名和密码以及 Ipaddress,并且我尝试按照以下链接中给出的方式使用凭据管理器进行操作: 在 WPF 应用程序中加密凭据
它可以很好地记住用户名和密码,但从不记住我想记住的 Ipaddres。另一个问题是当我打开电脑的第二天,它甚至忘记了用户名和密码的记忆。它应该永远记住它。
我的代码在这里:
将凭据写入 COM :
public static int WriteCredential(string applicationName, string userName, string secret,string ipAddress)
{
byte[] byteArray = Encoding.Unicode.GetBytes(secret);
if (byteArray.Length > 512)
throw new ArgumentOutOfRangeException("secret", "The secret message has exceeded 512 bytes.");
CREDENTIAL credential = new CREDENTIAL(); //see below my credential structure
credential.AttributeCount = 0;
credential.Attributes = IntPtr.Zero;
credential.Comment = IntPtr.Zero;
credential.TargetAlias = IntPtr.Zero;
credential.Type = CredentialType.Generic;
credential.Persist = (UInt32)CredentialPersistence.Session;
credential.CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length;
credential.TargetName = Marshal.StringToCoTaskMemUni(applicationName);
credential.CredentialBlob = Marshal.StringToCoTaskMemUni(secret);
credential.UserName = Marshal.StringToCoTaskMemUni(userName ?? Environment.UserName);
credential.IpAddress= Marshal.StringToCoTaskMemUni(ipAddress);
bool written = CredWrite(ref credential, 0);
int lastError = Marshal.GetLastWin32Error();
Marshal.FreeCoTaskMem(credential.TargetName);
Marshal.FreeCoTaskMem(credential.CredentialBlob);
Marshal.FreeCoTaskMem(credential.UserName);
Marshal.FreeCoTaskMem(credential.IpAddress);
if (written)
return 0;
throw new Exception(string.Format("CredWrite failed with the error code {0}.", lastError));
}
凭证结构:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct CREDENTIAL
{
public UInt32 Flags;
public CredentialType Type;
public IntPtr TargetName;
public IntPtr Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public IntPtr CredentialBlob;
public UInt32 Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public IntPtr TargetAlias;
public IntPtr UserName;
public IntPtr IpAddress;
}
从 COM 读取:
public static Credential ReadCredential(string applicationName)
{
IntPtr nCredPtr;
bool read = CredRead(applicationName, CredentialType.Generic, 0, out nCredPtr);
if (read)
{
using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr))
{
CREDENTIAL cred = critCred.GetCredential(); //cred.IpAddress gives me null here whereas it is not null in case of UserName and CredentialBlob
return ReadCredential(cred);
}
}
return null;
}
如何解决这两个问题:
(1) 如何记忆IP地址
(2) 如何在下一台电脑开机后的第二天记忆数据
我找到了第二个问题的答案:CRED_PERSIST_LOCAL_MACHINE 但不是第一个问题,我能找到的第二个问题的另一个解决方案是“CredentialManager.WriteCredential("Application", userName + "+" + ipAddress, passWord);" 然后在 '+' 上阅读时拆分。如果有人知道更好的解决方案?