12

I will have a list of dll's in a folder, I want to check a dll for a application exists or not. If so i want to add that application name in grid.Can any one tell how to do it programmatically. Thanks in Advance

Gokulakrishnan
  • 227
  • 1
  • 2
  • 12
  • 3
    If you have a list of DLLs in a folder, it is very unlikely that folder happens to be part of the GAC. – Hans Passant Jul 28 '10 at 19:06
  • Very closely releated: https://stackoverflow.com/questions/1933947/check-gac-for-an-assembly – sɐunıɔןɐqɐp Jan 21 '21 at 11:35
  • And also: https://stackoverflow.com/questions/19456547/how-to-programmatically-determine-if-net-assembly-is-installed-in-gac – sɐunıɔןɐqɐp Jan 21 '21 at 11:36
  • Does this answer your question? [How to programmatically determine if .NET assembly is installed in GAC?](https://stackoverflow.com/questions/19456547/how-to-programmatically-determine-if-net-assembly-is-installed-in-gac) – divyang4481 May 30 '21 at 06:23

6 Answers6

15

Do an assembly.LoadFrom and check GlobalAssemblyCache

testAssembly = Assembly.LoadFrom(dllname);

if (!testAssembly.GlobalAssemblyCache)
{
  // not in gac
}
dvallejo
  • 1,033
  • 11
  • 25
  • I see no reason for a downvote. To me, this seems like the most elegant answer so far, since it doesn't require complex stuff with Fusion/COM. This should also work if you're loading assemblies in the [reflection-only context](http://msdn.microsoft.com/en-us/library/ms172331.aspx) – derabbink Jun 14 '13 at 08:58
9

I think the proper way is Fusion COM API.

Here how to use it :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace IsAssemblyInGAC
{
    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     
    [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 
        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;
        }
    }
}

Use QueryAssemblyInfo method.

Incognito
  • 16,567
  • 9
  • 52
  • 74
3

Here's the documentation for the undocumented GAC API: DOC: Global Assembly Cache (GAC) APIs Are Not Documented in the .NET Framework Software Development Kit (SDK) Documentation.

This API is designed to be used from native code, so this article might help you program it from C#.

If you're after a quick solution, gacutil /l works.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
0

I know this is an old question, but for sake of new travellers...

We have a (free) fusion library available for download at http://dilithium.co.za/info/products/gac-api/ which does exactly this. Disclosure: Yes, I'm affiliated. No, I won't get money if you download. ;-)

PL-Li2
  • 21
  • 1
0

Usually people make the assumption that the GAC is located in c:<windir>\assembly, which is 99% true. So you could write code to iterate through the files found in that folder.

The more orthodox way would be to use the Fusion API, which is COM-based. A managed wrapper is available on this blog site:

Link

The site also contains sample managed code showing how to use the Fusion API to enumerate the installed assemblies - the code is pretty much written out for you, so just ctrl+c and then ctrl+v... :)

Link

HTH...

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
code4life
  • 15,655
  • 7
  • 50
  • 82
0

You can load dotnet exe as and find their dependecy as follows :

var applicationExeWithPath ="C:\.......\someapplicaiton.exe" 

var assemblies = Assembly.LoadFile(applicationExeWithPath ).GetReferencedAssemblies();

then iterate over those assembly and check if they exist in GAC or not

public static class GacUtil
{
    public static bool IsAssemblyInGAC(string assemblyFullName)
    {
        try
        {
            return Assembly.ReflectionOnlyLoad(assemblyFullName)
                           .GlobalAssemblyCache;
        }
        catch
        {
            return false;
        }
    }

    public static bool IsAssemblyInGAC(Assembly assembly)
    {
        return assembly.GlobalAssemblyCache;
    }
}
divyang4481
  • 1,584
  • 16
  • 32