Зарегистрируйте dll в GAC - но тогда он не появится в окне сборки

2

У меня есть этот код для регистрации DLL в мой gac

 Assembly asm = Assembly.LoadFrom(argument);
    RegistrationServices regAsm = new RegistrationServices();
    bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);

и это работает отлично, я получаю true для bResult, но когда я открываю окно GAC, я ожидал увидеть там DLL, но это не так. Может ли кто-нибудь объяснить мне, почему?

Когда я бросаю dll в окно GAC, я вижу его там.

Теги:

3 ответа

1
Лучший ответ

Ваш код не регистрирует сборку в GAC, но, как объяснено здесь,

Регистрирует классы в управляемом сборка для создания с COM.

который не является тем же.

  • 0
    так что правильный способ регистрации - это regasm.exe? потому что я тоже попробовал это, но все еще не видел это в окне GAC.
  • 2
    Правильный путь - gacutil, а не regasm (для регистрации сборок .NET для создания COM).
17

Странно, что это не оболочка .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 в окне проводника, чтобы обновить представление, если вы добавляете и удаляете сборки с этим кодом.

  • 1
    Я думаю, что это уже обернуто в System.EnterpriseServices.dll просто вызовите new System.EnterpriseServices.Internal.Publish().GacInstall(assemblyPath); или new System.EnterpriseServices.Internal.Publish().GacRemove(assemblyPath)
  • 1
    @ScottLerch К сожалению, это слишком хорошо оборачивается - нет никакого способа узнать результат того, удалась ли деинсталляция или нет. В GacRemove () результат UninstallAssembly () отбрасывается; вы получаете журнал событий, но исключение никогда не всплывает в вызывающем коде.
1

Используемый вами метод предназначен для регистрации COM. Официального способа сделать это не существует.

У Microsoft есть база знаний о том, как использовать недокументированный API GAC

надеюсь, что это поможет,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню