在C#中为Windows Vista / 7显示身份validation对话框

我想从用户那里获得网络登录凭据。

我正在使用带有C#的.NET 3.5。 到目前为止,我使用了CredUIPromptForCredentials调用(关于如何使用它的一个非常有用的链接可以在这里找到)

我的问题是CredUIPromptForCredentials API调用显示旧的Windows 2000 / XP凭据对话框而不是新的Vista / 7。

我在msdn上看到我应该使用CredUIPromptForWindowsCredentials函数。

有人可以发布一个如何在C#中使用它的例子吗? 我还需要能够获得输入的凭据。

我设法实现了一个适合我的解决方案。

这是源代码:

  [DllImport("ole32.dll")] public static extern void CoTaskMemFree(IntPtr ptr); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct CREDUI_INFO { public int cbSize; public IntPtr hwndParent; public string pszMessageText; public string pszCaptionText; public IntPtr hbmBanner; } [DllImport("credui.dll", CharSet = CharSet.Auto)] private static extern bool CredUnPackAuthenticationBuffer(int dwFlags, IntPtr pAuthBuffer, uint cbAuthBuffer, StringBuilder pszUserName, ref int pcchMaxUserName, StringBuilder pszDomainName, ref int pcchMaxDomainame, StringBuilder pszPassword, ref int pcchMaxPassword); [DllImport("credui.dll", CharSet = CharSet.Auto)] private static extern int CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere, int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer, out uint refOutAuthBufferSize, ref bool fSave, int flags); public static void GetCredentialsVistaAndUp(string serverName, out NetworkCredential networkCredential) { CREDUI_INFO credui = new CREDUI_INFO(); credui.pszCaptionText = "Please enter the credentails for " + serverName; credui.pszMessageText = "DisplayedMessage"; credui.cbSize = Marshal.SizeOf(credui); uint authPackage = 0; IntPtr outCredBuffer = new IntPtr(); uint outCredSize; bool save = false; int result = CredUIPromptForWindowsCredentials(ref credui, 0, ref authPackage, IntPtr.Zero, 0, out outCredBuffer, out outCredSize, ref save, 1 /* Generic */); var usernameBuf = new StringBuilder(100); var passwordBuf = new StringBuilder(100); var domainBuf = new StringBuilder(100); int maxUserName = 100; int maxDomain = 100; int maxPassword = 100; if (result == 0) { if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword)) { //TODO: ms documentation says we should call this but i can't get it to work //SecureZeroMem(outCredBuffer, outCredSize); //clear the memory allocated by CredUIPromptForWindowsCredentials CoTaskMemFree(outCredBuffer); networkCredential = new NetworkCredential() { UserName = usernameBuf.ToString(), Password = passwordBuf.ToString(), Domain = domainBuf.ToString() }; return; } } networkCredential = null; } 

我仍然需要弄清楚如何记住输入的最后一个凭证等细节…

但主要部分有效。

以下是从bytes.compost中提取的一些代码:

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct _CREDUI_INFO { public int cbSize; public IntPtr hwndParent; public string pszMessageText; public string pszCaptionText; public IntPtr hbmBanner; } class Program { [DllImport("credui.dll", CharSet=CharSet.Unicode)] internal static extern uint CredUIPromptForWindowsCredentials(ref _CREDUI_INFO notUsedHere, int authError, ref uint authPackage, IntPtr InAuthBuffer, uint InAuthBufferSize, out IntPtr refOutAuthBuffer, out uint refOutAuthBufferSize, ref bool fSave, int flags); const int CREDUIWIN_AUTHPACKAGE_ONLY = 0x10; static void Main() { _CREDUI_INFO credui = new _CREDUI_INFO(); credui.cbSize = Marshal.SizeOf(credui); credui.pszCaptionText = "Testje"; credui.pszMessageText = "Message"; uint authPackage = 0; IntPtr outCredBuffer; uint outCredSize; bool save = false; uint ret = CredUIPromptForWindowsCredentials(ref credui, 0, ref authPackage, IntPtr.Zero, 0, out outCredBuffer, out outCredSize, ref save, CREDUIWIN_AUTHPACKAGE_ONLY); if(ret != 0) { // failed to load function... // ... } else { // extract credentials from the buffer returned, using more // credui.dll API's . // ... } } }