2013-03-20 2 views
1

Ниже приведен код на C#, где я пытаюсь добавить привязку SSL существующего сертификата к «Default Website» на сервере IIS. Но я получаюSystem.Runtime.InteropServices.COMException (0x8000500C) при выполнении изменений в DirectoryEntry в .Net

System.Runtime.InteropServices.COMException (0x8000500C) в заявлении "website.Properties [" SSLCertHash "] Добавить (x509.GetCertHash());.".

Знаете ли вы, почему?

string defaultWebsite = "Default Web Site"; 

foreach (DirectoryEntry website in sites) 
{ 
    if (website.Properties["ServerComment"] != null) 
    { 
     if (website.Properties["ServerComment"].Value != null) 
     { 
      SrmLogManager.logMessage(SrmLogMgrLevel.SRM_LOGMGR_LEVEL_INFO, funcName + "Website found" + website.Properties["ServerComment"].Value.ToString()); 

       PropertyCollection pc = website.Properties; 
       IDictionaryEnumerator ide = pc.GetEnumerator(); 
       ide.Reset(); 
       while (ide.MoveNext()) 
       { 
        PropertyValueCollection pvc = ide.Entry.Value as PropertyValueCollection; 

        // Dump out the website properties into the log, can be removed in future 
        SrmLogManager.logMessage(SrmLogMgrLevel.SRM_LOGMGR_LEVEL_INFO,"Name: "+ ide.Entry.Key.ToString()); 
        SrmLogManager.logMessage(SrmLogMgrLevel.SRM_LOGMGR_LEVEL_INFO,"Value: " + pvc.Value); 
       } 
       // Add the Secure (https) binding to port 443 at hostname = localhost 
       website.Properties["SecureBindings"].Clear(); 
       website.Properties["SecureBindings"].Add(":443:localhost"); 

       // Bind the AppAssure certificate 
       website.Properties["SSLCertHash"].Clear(); 
       website.Properties["SSLCertHash"].Add(x509.GetCertHash()); 
       website.CommitChanges(); 

      if (string.Compare(website.Properties["ServerComment"].Value.ToString(), defaultWebsite) == 0) 
      { 
       SrmLogManager.logMessage(SrmLogMgrLevel.SRM_LOGMGR_LEVEL_INFO, funcName + "Default Website is : " + website.Properties["ServerComment"].Value.ToString()); 

      } 
     } 
    } 
} 

Вот исключение я получаю:

Возникло исключение при связывании AA CERT System.Runtime.InteropServices.COMException (0x8000500C): Исключение из HRESULT: 0x8000500C в System.DirectoryServices.Interop .UnsafeNativeMethods.IAds.PutEx (Int32 lnControlCode, String bstrName, Object vProp) в System.DirectoryServices.PropertyValueCollection.OnInsertComplete (индекс Int32, значение объекта) в System.Collections.CollectionBase.System.Collections.IList.Add (значение объекта) на System.Dir ectoryServices.PropertyValueCollection.Add (значение объекта) at AAA.Web.Controllers.Global.importAppAssureSoftwareCert() в c: \ Users \ Administrator \ Documents \ AppAssureAppliance2.0 \ SRMWebClient \ AAA.Web \ Controllers \ Global.cs: строка 80

+0

Когда вы проходите через код, вы получаете значения в 'website.Properties [" SecureBindings "]. Добавить (": 443: localhost ");'? – MethodMan

+0

посмотрите на это сообщение, он должен дать вам представление о том, что вы можете сделать в качестве альтернативы http://stackoverflow.com/questions/10384996/nullreferenceexception-in-microsoft-web-administration-when-adding-https-binding – MethodMan

+0

@ DJKRAZE, да, после прохождения через мы можем видеть привязку 443 в диспетчере IIS. – paxglobal

ответ

0

Да, это проблема. Вы должны использовать COM API низкого уровня, полностью обходя DirectoryEntry. Это, как я это сделал:

private static void SetSslCertHash(string siteId, byte[] hash) 
    { 
    using (var adminBase = TemporaryComObject.Wrap(new MSAdminBase_W())) 
    using (var ptrHash = new AllocHGlobal(hash)) 
    { 
     using (var siteKey = new AdminBaseKey(adminBase.Com, adminBase.Com.OpenKey(METADATA_MASTER_ROOT_HANDLE, "/LM/W3SVC/" + siteId, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 1000))) 
     { 
     var record = new METADATA_RECORD 
     { 
      dwMDIdentifier = SslCertHashCode, 
      dwMDAttributes = METADATA_INHERIT, 
      dwMDUserType = IIS_MD_UT_SERVER, 
      dwMDDataType = BINARY_METADATA, 
      pbMDData = ptrHash.Buffer, 
      dwMDDataLen = hash.Length 
     }; 
     adminBase.Com.SetData(siteKey.Handle, string.Empty, ref record); 
     } 
     adminBase.Com.SaveData(); 
    } 
    } 

Это раздражает, что DirectoryEntry API сломана для данного свойства. В любом случае, дополнительная помощь на низком уровне COM API находится здесь - http://support.microsoft.com/kb/313624/en-US

Конечно, вам понадобится объявление .NET класса COM MSAdminBase_W. В то время, когда я написал этот код, я не смог найти ничего готового, поэтому я только что открыл «c: \ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Include \ Iadmw.h» и извлек все части оттуда. Здесь, для Вас, чтобы скопировать и наслаждаться:

using System; 
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices; 

namespace MSAdminBaseLib 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct _FILETIME 
    { 
    public uint dwLowDateTime; 
    public uint dwHighDateTime; 
    } 

    [ComImport, Guid("70B51430-B6CA-11D0-B9B9-00A0C922E750"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    public interface IMSAdminBase_W 
    { 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void AddKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void DeleteKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void DeleteChildKeys([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void EnumKeys([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 0x100)] ushort[] szMDName, [In] int dwMDEnumObjectIndex); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void CopyKey([In] int hMDSourceHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDSourcePath, [In] int hMDDestHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDDestPath, [In] int bMDOverwriteFlag, [In] int bMDCopyFlag); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void RenameKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDNewName); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void SetData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] ref METADATA_RECORD pmdrMDData); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, Out] ref METADATA_RECORD pmdrMDData, out int pdwMDRequiredDataLen); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void DeleteData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDIdentifier, [In] int dwMDDataType); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void EnumData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, Out] ref METADATA_RECORD pmdrMDData, [In] int dwMDEnumDataIndex, out int pdwMDRequiredDataLen); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetAllData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDAttributes, [In] int dwMDUserType, [In] int dwMDDataType, out int pdwMDNumDataEntries, out int pdwMDDataSetNumber, [In] int dwMDBufferSize, out byte pbMDBuffer, out int pdwMDRequiredBufferSize); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void DeleteAllData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDUserType, [In] int dwMDDataType); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void CopyData([In] int hMDSourceHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDSourcePath, [In] int hMDDestHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDDestPath, [In] int dwMDAttributes, [In] int dwMDUserType, [In] int dwMDDataType, [In] int bMDCopyFlag); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetDataPaths([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDIdentifier, [In] int dwMDDataType, [In] int dwMDBufferSize, out ushort pszBuffer, out int pdwMDRequiredBufferSize); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    int OpenKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDAccessRequested, [In] int dwMDTimeOut); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void CloseKey([In] int hMDHandle); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void ChangePermissions([In] int hMDHandle, [In] int dwMDTimeOut, [In] int dwMDAccessRequested); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void SaveData(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetHandleInfo([In] int hMDHandle, out METADATA_HANDLE_INFO pmdhiInfo); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetSystemChangeNumber(out int pdwSystemChangeNumber); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetDataSetNumber([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, out int pdwMDDataSetNumber); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void SetLastChangeTime([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] ref _FILETIME pftMDLastChangeTime, [In] int bLocalTime); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void GetLastChangeTime([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, out _FILETIME pftMDLastChangeTime, [In] int bLocalTime); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    void KeyExchangePhase1(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    void KeyExchangePhase2(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void Backup([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion, [In] int dwMDFlags); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void Restore([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion, [In] int dwMDFlags); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void EnumBackups([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 0x100)] ushort[] szMDBackupLocation, out int pdwMDVersion, out _FILETIME pftMDBackupTime, [In] int dwMDEnumIndex); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void DeleteBackup([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    void UnmarshalInterface([MarshalAs(UnmanagedType.Interface)] out MSAdminBase_W piadmbwInterface); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    void GetServerGuid(); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct METADATA_HANDLE_INFO 
    { 
    public int dwMDPermissions; 
    public int dwMDSystemChangeNumber; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct METADATA_RECORD 
    { 
    public int dwMDIdentifier; 
    public int dwMDAttributes; 
    public int dwMDUserType; 
    public int dwMDDataType; 
    public int dwMDDataLen; 
    public IntPtr pbMDData; 
    public int dwMDDataTag; 
    } 

    [ComImport, Guid("70B51430-B6CA-11D0-B9B9-00A0C922E750"), CoClass(typeof(MSAdminBase_WClass))] 
    public interface MSAdminBase_W : IMSAdminBase_W 
    { 
    } 

    [ComImport, TypeLibType(TypeLibTypeFlags.FCanCreate), ClassInterface(ClassInterfaceType.None), Guid("A9E69610-B80D-11D0-B9B9-00A0C922E750")] 
    public class MSAdminBase_WClass : MSAdminBase_W 
    { 
    // Methods 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void AddKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void Backup([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion, [In] int dwMDFlags); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void ChangePermissions([In] int hMDHandle, [In] int dwMDTimeOut, [In] int dwMDAccessRequested); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void CloseKey([In] int hMDHandle); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void CopyData([In] int hMDSourceHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDSourcePath, [In] int hMDDestHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDDestPath, [In] int dwMDAttributes, [In] int dwMDUserType, [In] int dwMDDataType, [In] int bMDCopyFlag); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void CopyKey([In] int hMDSourceHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDSourcePath, [In] int hMDDestHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDDestPath, [In] int bMDOverwriteFlag, [In] int bMDCopyFlag); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void DeleteAllData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDUserType, [In] int dwMDDataType); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void DeleteBackup([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void DeleteChildKeys([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void DeleteData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDIdentifier, [In] int dwMDDataType); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void DeleteKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void EnumBackups([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 0x100)] ushort[] szMDBackupLocation, out int pdwMDVersion, out _FILETIME pftMDBackupTime, [In] int dwMDEnumIndex); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void EnumData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, Out] ref METADATA_RECORD pmdrMDData, [In] int dwMDEnumDataIndex, out int pdwMDRequiredDataLen); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void EnumKeys([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, SizeConst = 0x100)] ushort[] szMDName, [In] int dwMDEnumObjectIndex); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetAllData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDAttributes, [In] int dwMDUserType, [In] int dwMDDataType, out int pdwMDNumDataEntries, out int pdwMDDataSetNumber, [In] int dwMDBufferSize, out byte pbMDBuffer, out int pdwMDRequiredBufferSize); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, Out] ref METADATA_RECORD pmdrMDData, out int pdwMDRequiredDataLen); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetDataPaths([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDIdentifier, [In] int dwMDDataType, [In] int dwMDBufferSize, out ushort pszBuffer, out int pdwMDRequiredBufferSize); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetDataSetNumber([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, out int pdwMDDataSetNumber); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetHandleInfo([In] int hMDHandle, out METADATA_HANDLE_INFO pmdhiInfo); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetLastChangeTime([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, out _FILETIME pftMDLastChangeTime, [In] int bLocalTime); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    public virtual extern void GetServerGuid(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void GetSystemChangeNumber(out int pdwSystemChangeNumber); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    public virtual extern void KeyExchangePhase1(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), TypeLibFunc(TypeLibFuncFlags.FRestricted)] 
    public virtual extern void KeyExchangePhase2(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern int OpenKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] int dwMDAccessRequested, [In] int dwMDTimeOut); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void RenameKey([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDNewName); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void Restore([In, MarshalAs(UnmanagedType.LPWStr)] string pszMDBackupLocation, [In] int dwMDVersion, [In] int dwMDFlags); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void SaveData(); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void SetData([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] ref METADATA_RECORD pmdrMDData); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void SetLastChangeTime([In] int hMDHandle, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMDPath, [In] ref _FILETIME pftMDLastChangeTime, [In] int bLocalTime); 
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 
    public virtual extern void UnmarshalInterface([MarshalAs(UnmanagedType.Interface)] out MSAdminBase_W piadmbwInterface); 
    } 
} 

Далее, легкая часть - вспомогательные типы .NET реализовать C# версии RAII:

TemporaryComObject:

public class TemporaryComObject 
    { 
    public static TemporaryComObject<T> Wrap<T>(T com) where T : class 
    { 
     return new TemporaryComObject<T>(com); 
    } 
    } 

    public class TemporaryComObject<T> : IDisposable where T : class 
    { 
    public TemporaryComObject(T com) 
    { 
     Com = com; 
    } 

    public T Com { get; private set; } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     if (Com != null) 
     { 
     Marshal.FinalReleaseComObject(Com); 
     Com = null; 
     } 
    } 

    #endregion 
    } 

AllocHGlobal :

public class AllocHGlobal : IDisposable 
    { 
    public readonly IntPtr Buffer; 
    public AllocHGlobal(int len) 
    { 
     Buffer = Marshal.AllocHGlobal(len); 
    } 
    public AllocHGlobal(byte[] data) : 
     this(data.Length) 
    { 
     Marshal.Copy(data, 0, Buffer, data.Length); 
    } 

    #region Implementation of IDisposable 

    public void Dispose() 
    { 
     Marshal.FreeHGlobal(Buffer); 
    } 

    #endregion 
    } 

AdminBaseKey:

public class AdminBaseKey : IDisposable 
    { 
    private readonly IMSAdminBase_W m_adminBase; 
    public readonly int Handle; 

    public AdminBaseKey(IMSAdminBase_W adminBase, int handle) 
    { 
     m_adminBase = adminBase; 
     Handle = handle; 
    } 

    #region Implementation of IDisposable 

    public void Dispose() 
    { 
     m_adminBase.CloseKey(Handle); 
    } 

    #endregion 
    } 

Все. Работает на меня.

+0

Кстати, вы можете рассказать о моем собственном SO-вопросе по тому же вопросу - http://stackoverflow.com/questions/6690455/how-to-work-with-the-msadminbase-com-object-in-net – mark