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.
来源:https://stackoverflow.com/questions/6121276/is-it-possible-to-load-an-assembly-from-the-gac-without-the-fullname