Groups | Blog | Home
all groups > c# > april 2008 >

c# : Determine if assembly is installed in the GAC



Cramer
4/24/2008 9:32:55 AM
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


Cramer
4/24/2008 10:51:48 AM
Thanks for the code! I never would have had the time to come up with this
and instead documented assumptions my code would have instead have made
about the existance of the assembly in the GAC. Now it will be able to test
and report on those assumptions when invalid, before choking. I'll give it a
whirl.

-Cramer


[quoted text, click to view]


Ignacio Machin ( .NET/ C# MVP )
4/24/2008 11:30:52 AM
[quoted text, click to view]

Hi,

IT should be simple, first you need a reference to the assembly (you
can use Assembly.GetAssembly(typeof( XXXX ) ); where XXXX is defined
in that assembly)
Cramer
4/24/2008 2:15:33 PM
RE:
[quoted text, click to view]


I should have been more specific. I want to know if an assembly is
installed in the GAC *before* attempting to load it. This would be akin to
using File.Exists() before attempting to open a file.

Your approach assumes that the assembly is already loaded, which it is not
in my case. In my case I want to determine if an assembly of a particular
version etc is in the GAC, then load it if it's there, or write the fact to
a log if it's not in the GAC.

-Cramer


parez
4/24/2008 2:17:22 PM
[quoted text, click to view]

Try Assembly.LoadWithPartialName("SomeName");

if returned value is null then it is not in gac..
if you get a non null value , then check the GlobalAssemblyCache.

parez
4/24/2008 2:44:34 PM
[quoted text, click to view]

Try Assembly.LoadWithPartialName("SomeName");

if returned value is null then it is not in gac..
if you get a non null value , then check the GlobalAssemblyCache.

Willy Denoyette [MVP]
4/24/2008 7:42:10 PM
[quoted text, click to view]

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.
Willy Denoyette [MVP]
4/24/2008 10:05:13 PM
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin@gmail.com> wrote in
message
news:e63b059c-0512-40de-a491-9a484a37204f@y38g2000hsy.googlegroups.com...
[quoted text, click to view]

Hi,

IT should be simple, first you need a reference to the assembly (you
can use Assembly.GetAssembly(typeof( XXXX ) ); where XXXX is defined
in that assembly)
Then using Assembly.Location should be enough.


But this won't return the GAC location, nor will it tell you whether the
assembly is actually stored in the GAC.

Willy.
AddThis Social Bookmark Button