2016-06-26 17 views
3

Active Directoryオブジェクトピッカー(IDsObjectPicker)に資格情報をc#に設定する必要があります。 しかし、私はIDObjectPickerCredentialsを動作させることはできません。 私は同じことをC++(msdn example)で作ってあり、うまくいきます。c#IDsObjectPickerCredentialsが失敗する

私は私が間違ってやっているものを私に教えてくださいここComInterop.cs and StructsFlags.cs

から「ヘッダ」を使用。 IDsObjectPickerCredentialsインターフェースはIDsObjectPickerから派生

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using Tulpep.ActiveDirectoryObjectPicker; 

namespace cred 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string szTargetComputer = @"10.0.9.115"; 
      string szUser = @"TST\test"; 
      string szPassword = @"123qazWSX"; 

      DSObjectPicker picker = new DSObjectPicker(); 
      IDsObjectPicker ipicker = (IDsObjectPicker)picker; 

      int res = InitObjectPicker(ipicker, szTargetComputer); 

      if (res == (int)HRESULT.S_OK) 
      { 
       try 
       { 
        // !!! HERE !!! 
        IDsObjectPickerCredentials cred = (ipicker as IDsObjectPickerCredentials); 
        res = cred.SetCredentials(szUser, szPassword); 

        // c++ like variant 
        // res = InitCredentials(ipicker, szUser, szPassword); 

        if (res != (int)HRESULT.S_OK) Console.WriteLine("SetCredentials Fail : 0x{0}", res.ToString("X4")); // On Win32 I get 0x80070057 - looks like E_INVALIDARG 

        IntPtr hwndParent = Process.GetCurrentProcess().MainWindowHandle; 
        IDataObject dataObj = null; 
        int hresult = ipicker.InvokeDialog(hwndParent, out dataObj); 

        Console.WriteLine(hresult == (int)HRESULT.S_OK ? "OK" : "Cancel"); 
        Console.ReadKey(); 
       } 
       finally 
       { 
        Marshal.ReleaseComObject(ipicker); 
       } 
      } 
     } 


     [ComImport, Guid("E2D3EC9B-D041-445A-8F16-4748DE8FB1CF"), 
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
     internal interface IDsObjectPickerCredentials 
     { 
      [PreserveSig()] 
      int SetCredentials(
       [In, MarshalAs(UnmanagedType.LPWStr)] string szUserName, 
       [In, MarshalAs(UnmanagedType.LPWStr)] string szPassword); 
     } 

     static int InitObjectPicker(IDsObjectPicker ipicker, string szTargetComputer) 
     {   
      int res = (int)HRESULT.S_FALSE; 

      DSOP_SCOPE_INIT_INFO[] aScopeInit = new DSOP_SCOPE_INIT_INFO[1]; 

      DSOP_INIT_INFO InitInfo = new DSOP_INIT_INFO(); 

      aScopeInit[0].cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)); 

      aScopeInit[0].flType = 
       DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | 
       DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN; 

      aScopeInit[0].FilterFlags.Uplevel.flBothModes = 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_COMPUTERS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_USERS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_WELL_KNOWN_PRINCIPALS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_BUILTIN_GROUPS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_WELL_KNOWN_PRINCIPALS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_INCLUDE_ADVANCED_VIEW; 

      aScopeInit[0].FilterFlags.flDownlevel = 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_COMPUTERS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_USERS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_WELL_KNOWN_PRINCIPALS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_BUILTIN_GROUPS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_WELL_KNOWN_PRINCIPALS | 
       DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_INCLUDE_ADVANCED_VIEW; 

      IntPtr refScopeInitInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * aScopeInit.Length); 
      try 
      { 
       // Marshal structs to pointers 
       for (int index = 0; index < aScopeInit.Length; index++) 
       { 
        Marshal.StructureToPtr(aScopeInit[index], (IntPtr)((int)refScopeInitInfo + index * Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO))), false); 
       } 

       InitInfo.cbSize = (uint)Marshal.SizeOf(typeof(DSOP_INIT_INFO)); 
       InitInfo.cDsScopeInfos = (uint)aScopeInit.Length; //sizeof(aScopeInit)/sizeof(DSOP_SCOPE_INIT_INFO); 
       InitInfo.aDsScopeInfos = refScopeInitInfo; 
       InitInfo.flOptions = DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT; 
       InitInfo.pwzTargetComputer = szTargetComputer; 

       res = ipicker.Initialize(ref InitInfo); 
      } 
      finally 
      { 
       Marshal.FreeHGlobal(refScopeInitInfo); 
      } 

      return res; 
     } 

     static int InitCredentials(IDsObjectPicker ipicker, string User, string Password) 
     { 
      IntPtr ptr = IntPtr.Zero; 

      Guid IID_IDsObjectPickerCredentials = new Guid("E2D3EC9B-D041-445A-8F16-4748DE8FB1CF"); 

      IntPtr pIUnk = Marshal.GetIUnknownForObject(ipicker);   

      int hr = Marshal.QueryInterface(pIUnk, ref IID_IDsObjectPickerCredentials, out ptr); 

      if (hr == HRESULT.S_OK) 
      { 
       try 
       { 
        IDsObjectPickerCredentials cred = (IDsObjectPickerCredentials)Marshal.GetObjectForIUnknown(ptr); 

        hr = cred.SetCredentials(User, Password); 
        if (hr != HRESULT.S_OK) 
        { 
         System.Diagnostics.Debugger.Break(); // Fail 
         return (int)HRESULT.S_FALSE; 
        } 
       } 
       catch (Exception ex) 
       { 
        return (int)HRESULT.S_FALSE; 
       } 
       finally 
       { 
        Marshal.Release(ptr); 
       } 
      } 
      return (int)HRESULT.S_OK; 
     } 
    } 
} 

答えて

1

IDsObjectPickerCredentials.SetCredentialsを呼び出す方法。あなたのサンプルは実際にSetCredentialsではなく、ユーザー名とパスワードを使用してInitializeメソッドを呼び出します。ここで

が正しい宣言です:

[ComImport, Guid("e2d3ec9b-d041-445a-8f16-4748de8fb1cf"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
interface IDsObjectPickerCredentials 
{ 
    [PreserveSig] 
    int Initialize(ref DSOP_INIT_INFO pInitInfo); 
    [PreserveSig] 
    int InvokeDialog(IntPtr HWND, out IDataObject lpDataObject); 
    [PreserveSig] 
    int SetCredentials(string userName, string password); 
} 

代わりIDsObjectPicker由来の、コードが同じ順序で、そのメソッドを複製しますのでご注意ください。これは.NET COM Interopに必要です。

QueryInterface/Releaseの電話番号はvar cred = (IDsObjectPickerCredentials)iobjectpicker;で十分です。

SetCredentialsは、Initializeメソッドの前に呼び出す必要があります。

+0

ありがとうございました。 100%正しい。私はテストしました - SetCredentialsはどちらの場合もOKです:Initializeの前後。 (x86 | x64) –

関連する問題