У меня есть этот код для регистрации DLL в мой gac
Assembly asm = Assembly.LoadFrom(argument);
RegistrationServices regAsm = new RegistrationServices();
bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
и это работает отлично, я получаю true для bResult, но когда я открываю окно GAC, я ожидал увидеть там DLL, но это не так. Может ли кто-нибудь объяснить мне, почему?
Когда я бросаю dll в окно GAC, я вижу его там.
Ваш код не регистрирует сборку в GAC, но, как объяснено здесь,
Регистрирует классы в управляемом сборка для создания с COM.
который не является тем же.
Странно, что это не оболочка .NET framework. Необходимые декларации о слиянии легко доступны. Этот код работал хорошо:
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
static class GacUtil {
public static void InstallAssembly(string path, bool forceRefresh) {
IAssemblyCache iac = null;
CreateAssemblyCache(out iac, 0);
try {
uint flags = forceRefresh ? 2u : 1u;
int hr = iac.InstallAssembly(flags, path, IntPtr.Zero);
if (hr < 0) Marshal.ThrowExceptionForHR(hr);
}
finally {
Marshal.FinalReleaseComObject(iac);
}
}
public static void UninstallAssembly(string displayName) {
IAssemblyCache iac = null;
CreateAssemblyCache(out iac, 0);
try {
uint whatHappened;
int hr = iac.UninstallAssembly(0, displayName, IntPtr.Zero, out whatHappened);
if (hr < 0) Marshal.ThrowExceptionForHR(hr);
switch (whatHappened) {
case 2: throw new InvalidOperationException("Assembly still in use");
case 5: throw new InvalidOperationException("Assembly still has install references");
case 6: throw new System.IO.FileNotFoundException(); // Not actually raised
}
}
finally {
Marshal.FinalReleaseComObject(iac);
}
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
internal interface IAssemblyCache {
[PreserveSig]
int UninstallAssembly(uint flags, [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, IntPtr pvReserved, out uint pulDisposition);
[PreserveSig]
int QueryAssemblyInfo(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, IntPtr pAsmInfo);
[PreserveSig]
int CreateAssemblyCacheItem(/* arguments omitted */);
[PreserveSig]
int CreateAssemblyScavenger(out object ppAsmScavenger);
[PreserveSig]
int InstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath, IntPtr pvReserved);
}
[DllImport("mscorwks.dll", PreserveSig = false)] // NOTE: use "clr.dll" in .NET 4+
internal static extern void CreateAssemblyCache(out IAssemblyCache ppAsmCache, int reserved);
}
Не забудьте нажать F5 в окне проводника, чтобы обновить представление, если вы добавляете и удаляете сборки с этим кодом.
System.EnterpriseServices.dll
просто вызовите new System.EnterpriseServices.Internal.Publish().GacInstall(assemblyPath);
или new System.EnterpriseServices.Internal.Publish().GacRemove(assemblyPath)
Используемый вами метод предназначен для регистрации COM. Официального способа сделать это не существует.
У Microsoft есть база знаний о том, как использовать недокументированный API GAC
надеюсь, что это поможет,