首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c# IDsObjectPickerCredentials失败

c# IDsObjectPickerCredentials失败
EN

Stack Overflow用户
提问于 2016-06-26 10:27:55
回答 1查看 362关注 0票数 3

我必须将凭据设置为Active-Directory-Object-Picker (IDsObjectPicker) on c#.但我不能强迫IDsObjectPickerCredentials工作。我在c++ (msdn示例)上也做过同样的事情,而且效果很好。

我在这里使用了"headers“,ComInterop.cs和StructsFlags.cs

,请告诉我我做错了什么。如何调用IDsObjectPickerCredentials.SetCredentials

代码语言:javascript
运行
复制
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;
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-28 00:25:09

IDsObjectPickerCredentials接口来自于IDsObjectPicker。您的示例实际上使用用户名和密码来调用Initialize方法,而不是使用SetCredentials

以下是正确的声明:

代码语言:javascript
运行
复制
[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互操作是必要的。

您不需要手动QueryInterface/Release调用,var cred = (IDsObjectPickerCredentials)iobjectpicker;就足够了。

我还发现,SetCredentials应该在Initialize方法之前被调用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38037523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档