Oui, c'est un problème. Vous devez utiliser l'API COM de bas niveau, en ignorant complètement DirectoryEntry
. Voici comment je l'ai fait:
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();
}
}
Il est ennuyeux que DirectoryEntry
API est cassé pour cette propriété particulière. Quoi qu'il en soit, plus d'aide sur l'API COM de bas niveau est ici - http://support.microsoft.com/kb/313624/en-US
Bien sûr, vous aurez besoin de la déclaration .NET de la classe COM MSAdminBase_W
. Au moment où j'ai écrit ce code, je n'ai rien trouvé de prêt, alors j'ai juste ouvert "c: \ Programmes \ Microsoft SDKs \ Windows \ v7.1 \ Include \ Iadmw.h" et extrait toutes les pièces à partir de là. Ici, il est, pour vous de copier et profiter:
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);
}
}
Ensuite, la partie facile - types .NET auxiliaires pour mettre en œuvre une version C# de 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
}
C'est tout. Travaille pour moi.
Lorsque vous parcourez le code, obtenez-vous des valeurs dans 'website.Properties [" SecureBindings "] .Add (": 443: localhost ");'? – MethodMan
regardez cet article il devrait vous donner et idée de ce que vous pouvez faire comme alternative http://stackoverflow.com/questions/10384996/nullreferenceexception-in-microsoft-web-administration-when-adding-https-binding – MethodMan
@ DJKRAZE oui, après avoir parcouru, nous pouvons voir 443 liaison dans le Gestionnaire des services Internet. – paxglobal