开发者

Is it possible to Load an assembly from the GAC without the FullName?

开发者 https://www.devze.com 2023-03-08 17:01 出处:网络
I know how to load an assembly from a filename, and also from the GAC. As My .msi file will put a dll project into the GAC, I\'m wondering if it\'s 开发者_运维知识库possible to load it from the GAC un

I know how to load an assembly from a filename, and also from the GAC. As My .msi file will put a dll project into the GAC, I'm wondering if it's 开发者_运维知识库possible to load it from the GAC unknowing the FullName (I mean just with the assembly name, or even the dll filename), because I have to Load this assembly from another project.


Here is a piece of code that allows to do this, and an exemple:

    string path = GetAssemblyPath("System.DirectoryServices");
    Assembly.LoadFrom(path);

Note if you need a specific processor architecture, since it supports partial name, you can write this kind of things:

    // load from the 32-bit GAC
    string path = GetAssemblyPath("Microsoft.Transactions.Bridge.Dtc, ProcessorArchitecture=X86");

    // load from the 64-bit GAC
    string path = GetAssemblyPath("Microsoft.Transactions.Bridge.Dtc, ProcessorArchitecture=AMD64");

This is the implementation:

    /// <summary>
    /// Gets an assembly path from the GAC given a partial name.
    /// </summary>
    /// <param name="name">An assembly partial name. May not be null.</param>
    /// <returns>
    /// The assembly path if found; otherwise null;
    /// </returns>
    public static string GetAssemblyPath(string name)
    {
        if (name == null)
            throw new ArgumentNullException("name");

        string finalName = name;
        AssemblyInfo aInfo = new AssemblyInfo();
        aInfo.cchBuf = 1024; // should be fine...
        aInfo.currentAssemblyPath = new String('\0', aInfo.cchBuf);

        IAssemblyCache ac;
        int hr = CreateAssemblyCache(out ac, 0);
        if (hr >= 0)
        {
            hr = ac.QueryAssemblyInfo(0, finalName, ref aInfo);
            if (hr < 0)
                return null;
        }

        return aInfo.currentAssemblyPath;
    }


    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
    private interface IAssemblyCache
    {
        void Reserved0();

        [PreserveSig]
        int QueryAssemblyInfo(int flags, [MarshalAs(UnmanagedType.LPWStr)] string assemblyName, ref AssemblyInfo assemblyInfo);
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct AssemblyInfo
    {
        public int cbAssemblyInfo;
        public int assemblyFlags;
        public long assemblySizeInKB;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string currentAssemblyPath;
        public int cchBuf; // size of path buf.
    }

    [DllImport("fusion.dll")]
    private static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, int reserved);


Yes, this is the whole point of the GAC. The runtime will look in the GAC first, before even looking in the current directory.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号