【问题标题】:DirectoryEntry.MoveTo exceptions: Abstracted by UnsafeNativeMethods but not documentedDirectoryEntry.MoveTo 异常:由 UnsafeNativeMethods 抽象但未记录
【发布时间】:2018-12-19 19:20:14
【问题描述】:

System.DirectoryServices 包含类/方法DirectoryEntry.MoveTo(..)。如果目标 DirectoryEntry 不是容器,则唯一记录的异常是 InvalidOperationException。我预计会有各种其他潜在的例外情况,尤其是在权限方面。

在后台,.MoveTo() 调用

DirectoryEntry.ContainerObject.MoveHere(this.Path, newName);

DirectoryEntry 是新的目标位置。哪个调用:

internal class UnsafeNativeMethods
{
    [Guid("001677D0-FD16-11CE-ABC4-02608C9E7553")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComImport]
    public interface IAdsContainer
    {
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Interface)]
        object MoveHere([MarshalAs(UnmanagedType.BStr), In] string sourceName, [MarshalAs(UnmanagedType.BStr), In] string newName);
        ...
    }
    ...
}

有问题的 GUID 指的是 activeds.tlb 类型库。该库将IADsContainer.MoveHere 定义为

[id(0x00000009)]
HRESULT MoveHere(
                [in] BSTR SourceName, 
                [in] BSTR NewName, 
                [out, retval] IDispatch** ppObject);

断开连接是activeds.dll返回一个HRESULT,并通过out参数给调用者一个指向对象的指针。但是 .NET 包装器具有不同的签名,并且没有 HRESULT。

两个问题:

  1. UnsafeNativeMethods.IAdsContainer.MoveHere 如何映射到具有不同签名的 COM 接口?
  2. HRESULT 发生了什么?

关于 #2... 如果中间有一个对象调用 MoveHere 的 HRESULT 版本,则该对象可能会检查结果并引发异常或返回它实例化的 IAdsContainer。但我不知道中间可能是什么对象,.NET 框架代码和 .tlb 文件都没有给我任何线索。它抛出的任何异常都没有记录。

【问题讨论】:

    标签: c# active-directory pinvoke comexception directoryentry


    【解决方案1】:

    它采用最后一个参数[out, retval] IDispatch** ppObject 并将其作为返回值,并解释返回的HRESULT 并在需要时抛出COMException。我只是还没有看到执行此操作的实际代码。

    我怀疑是 [ComImport] 属性告诉 .NET 以不同的方式对待它。

    事实上,源代码确实显示了由于该属性而进行了一些特殊处理,尽管我不会假装我完全理解发生了什么。

    例如,采用GetCustomMarshaledCOMObject 方法。 It calls GetIUnknown 并在返回 false 时发挥一些特殊的作用。

    GetIUnknown 方法专门检查 ComImportAttribute,如果存在则返回 false

    即使the method that calls GetCustomMarshaledCOMObject 说:

    // Check for COMObject & do some special custom marshaling
    

    【讨论】:

    • 这是有道理的。我希望我能更好地理解这些函数是如何映射的——从我正在阅读的内容来看,它甚至可能没有调用 activeds.dll?尽管.tlb。无论如何,我按照你的线索,认为我有答案,谢谢。将用详细信息更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多