DirectoryEntry.MoveTo异常:由UnsafeNativeMethods抽象但未记录

时间:2018-12-19 19:20:14

标签: c# active-directory pinvoke comexception directoryentry

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 ...如果中间有一个对象调用HRESULT版本的MoveHere,则该对象很可能会检查结果并引发异常或返回实例化的IAdsContainer。但是我不知道中间可能有什么对象,.NET框架代码和.tlb文件都没有提供任何线索。它引发的任何异常都没有记录。

1 个答案:

答案 0 :(得分: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