Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 255
metalcam Avatar asked May 25 '11 07:05

metalcam


People also ask

How to get the assembly name in c#?

If you know the assembly's file system path, you can call the static (C#) or Shared (Visual Basic) AssemblyName. GetAssemblyName method to get the fully qualified assembly name.

How to get assembly fully qualified name?

A better way to get the fully qualified name of an assembly is to use the AssemblyName class: AssemblyName assemblyName = AssemblyName. GetAssemblyName(@"C:\MyAssembly. dll"); string name = assemblyName.

What is assembly loader?

Loads the assembly with a common object file format (COFF)-based image containing an emitted assembly, optionally including symbols and specifying the source for the security context. The assembly is loaded into the application domain of the caller. Load(Byte[], Byte[], Evidence)


1 Answers

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);
like image 94
Simon Mourier Avatar answered Sep 20 '22 06:09

Simon Mourier