"Cramer" <A@B.comwrote in message
news:up**************@TK2MSFTNGP02.phx.gbl...
I'm wondering if there is an easy way to programmatically determine if an
assembly is installed in the GAC.
This would be similar to our ability to easily determine if a file exists
(File.Exists(path)) - but for an assembly, of a particular version, etc in
the GAC.
I have googled this and failed to find anything useful.
Thanks
You'll have to cal into the fusion API's (native code API's and COM).
Here is a completes sample that illustrates how one can retrieve the path of
an assembly in the GAC.
// Note that this requires V2 of the framework!!!!.
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace GacStuff
{
internal class GacApi
{
[DllImport("fusion.dll")]
internal static extern IntPtr CreateAssemblyCache(
out IAssemblyCache ppAsmCache,
int reserved);
}
// GAC Interfaces - IAssemblyCache. As a sample, non used vtable entries
declared as dummy.
[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);
}
}
// If assemblyName is not fully qualified, a random matching may be
returned!!!!
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;
// Get IAssemblyCache pointer
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;
}
}
}
Willy.