2010-11-09 42 views
9

Tôi muốn nhận thông tin xác thực đăng nhập mạng từ người dùng.Hiển thị hộp thoại Xác thực trong C# cho windows Vista/7

Tôi đang sử dụng .NET 3.5 với C#. Cho đến bây giờ tôi sử dụng CredUIPromptForCredentials gọi (một liên kết rất hữu ích về cách sử dụng nó có thể được tìm thấy here)

Vấn đề của tôi là cuộc gọi API CredUIPromptForCredentials cho thấy các cửa sổ cũ 2.000 hộp thoại thông tin/XP và không phải là mới Vista/7.

Tôi đã đọc trên msdn rằng tôi nên sử dụng chức năng CredUIPromptForWindowsCredentials.

Ai đó có thể đăng một ví dụ về cách sử dụng nó với C# không? Tôi cũng cần có khả năng nhận thông tin đăng nhập đã được nhập.

Trả lời

18

tôi quản lý để thực hiện một giải pháp mà đang làm việc cho tôi.

Đây là mã nguồn:

[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; 
    } 

tôi vẫn cần phải làm việc ra các chi tiết tốt như thế nào để nhớ các thông tin mới nhất được nhập vào vv ...

Nhưng các công trình phần lớn .

+0

Tôi thấy bạn đã gọi hàm của bạn là 'GetCredentialsVistaAndUp', điều này có làm việc cho xp hay không bạn đã thử nghiệm chưa? –

+1

@ChrisjanLodewyks - Nó không hoạt động với XP. XP không hỗ trợ hộp thoại này. Nó chỉ có thể được sử dụng, giống như tên gợi ý của phương thức tại, trên Vista và lên. – codekaizen

+0

Tôi tiếp tục nhận được một mã trở lại bí ẩn của 0x1F/thập phân 31. Hóa ra tôi đã phải đặt CharSet = CharSet.Unicode cho tất cả mọi thứ, sau đó nó làm việc tuyệt vời. –

2

Dưới đây là một số mã để đi trên extracted from bytes.com post:

[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 . 
     // ... 
    } 
    } 
} 
+0

Tôi đã xem bài đăng này. vấn đề là tôi cần trích xuất thông tin đăng nhập được nhập trong hộp thoại. Tôi nghĩ rằng nó đòi hỏi việc sử dụng các cuộc gọi api CredUnPackAuthenticationBuffer. – Rubinsh

Các vấn đề liên quan