Hello,
The best way to get all assemblies from the GAC is to use Fusion
first approch: The following code snippet shows how to achieve your goal:
internal class GacApi
{
[DllImport("fusion.dll")]
internal static extern IntPtr CreateAssemblyCache(
out IAssemblyCache ppAsmCache,
int reserved);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
internal interface IAssemblyCache
{
int Dummy1();
[PreserveSig()]
IntPtr QueryAssemblyInfo(int flags, [MarshalAs(UnmanagedType.LPWStr)] String assemblyName, ref ASSEMBLY_INFO assemblyInfo); int Dummy2(); int Dummy3(); int Dummy4();
}
[StructLayout(LayoutKind.Sequential)]
internal struct ASSEMBLY_INFO
{
public int cbAssemblyInfo;
public int assemblyFlags;
public long assemblySizeInKB;
[MarshalAs(UnmanagedType.LPWStr)]
public String currentAssemblyPath;
public int cchBuf;
}
class Program
{
static void Main()
{
try
{
Console.WriteLine(QueryAssemblyInfo("System"));
}
catch(System.IO.FileNotFoundException e)
{
Console.WriteLine(e.Message);
}
}
public static String QueryAssemblyInfo(String assemblyName)
{
ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO ();
assembyInfo.cchBuf = 512;
assembyInfo.currentAssemblyPath = new String('\0', assembyInfo.cchBuf) ;
IAssemblyCache assemblyCache = null;
IntPtr hr = GacApi.CreateAssemblyCache(out assemblyCache, 0);
if (hr == IntPtr.Zero)
{
hr = assemblyCache.QueryAssemblyInfo(1, assemblyName, ref assembyInfo);
if(hr != IntPtr.Zero)
Marshal.ThrowExceptionForHR(hr.ToInt32());
}
else
Marshal.ThrowExceptionForHR(hr.ToInt32());
return assembyInfo.currentAssemblyPath;
}
}
second approach: The GAC directory (%systemroot%\assembly for default installations) is a standard directory like any other directory and you should be able to loop through the directory, load the assemblies and retrieve type information of all types within the assembly.
Edit: The code for the easiest way:
List<string> dirs = new List<string>() {
"GAC", "GAC_32", "GAC_64", "GAC_MSIL",
"NativeImages_v2.0.50727_32",
"NativeImages_v2.0.50727_64",
"NativeImages_v4.0.50727_32",
"NativeImages_v4.0.50727_64"
};
string baseDir = @"c:\windows\assembly";
int i = 0;
foreach (string dir in dirs)
if (Directory.Exists(Path.Combine(baseDir, dir)))
foreach (string assemblyDir in Directory.GetFiles(Path.Combine(baseDir, dir), "*.dll", SearchOption.AllDirectories))
Console.WriteLine(assemblyDir);
More information about Fusion.dll can be found at:
http://support.microsoft.com/kb/317540
@ codymanix - Let me know if you have other questions