Determine if assembly is installed in the GAC

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Cramer

    Determine if assembly is installed in the GAC

    I'm wondering if there is an easy way to programmaticall y 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(pa th)) - but for an assembly, of a particular version, etc in
    the GAC.

    I have googled this and failed to find anything useful.

    Thanks



  • Willy Denoyette [MVP]

    #2
    Re: Determine if assembly is installed in the GAC

    "Cramer" <A@B.comwrote in message
    news:upVDbjipIH A.3960@TK2MSFTN GP02.phx.gbl...
    I'm wondering if there is an easy way to programmaticall y 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(pa th)) - 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("fusi on.dll")]
    internal static extern IntPtr CreateAssemblyC ache(
    out IAssemblyCache ppAsmCache,
    int reserved);

    }
    // GAC Interfaces - IAssemblyCache. As a sample, non used vtable entries
    declared as dummy.
    [ComImport, InterfaceType(C omInterfaceType .InterfaceIsIUn known),
    Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
    internal interface IAssemblyCache
    {
    int Dummy1();
    [PreserveSig()]
    IntPtr QueryAssemblyIn fo(
    int flags,
    [MarshalAs(Unman agedType.LPWStr )]
    String assemblyName,
    ref ASSEMBLY_INFO assemblyInfo);
    int Dummy2();
    int Dummy3();
    int Dummy4();
    }
    [StructLayout(La youtKind.Sequen tial)]
    internal struct ASSEMBLY_INFO
    {
    public int cbAssemblyInfo;
    public int assemblyFlags;
    public long assemblySizeInK B;
    [MarshalAs(Unman agedType.LPWStr )]
    public String currentAssembly Path;
    public int cchBuf;
    }

    class Program
    {
    static void Main()
    {
    try
    {
    Console.WriteLi ne(QueryAssembl yInfo("System") );
    }
    catch(System.IO .FileNotFoundEx ception e)
    {
    Console.WriteLi ne(e.Message);
    }
    }
    // If assemblyName is not fully qualified, a random matching may be
    returned!!!!
    public static String QueryAssemblyIn fo(String assemblyName)
    {
    ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO ();
    assembyInfo.cch Buf = 512;
    assembyInfo.cur rentAssemblyPat h = new String('\0',
    assembyInfo.cch Buf) ;
    IAssemblyCache assemblyCache = null;
    // Get IAssemblyCache pointer
    IntPtr hr = GacApi.CreateAs semblyCache(out assemblyCache, 0);
    if (hr == IntPtr.Zero)
    {
    hr = assemblyCache.Q ueryAssemblyInf o(1, assemblyName, ref
    assembyInfo);
    if(hr != IntPtr.Zero)
    Marshal.ThrowEx ceptionForHR(hr .ToInt32());
    }
    else
    Marshal.ThrowEx ceptionForHR(hr .ToInt32());
    return assembyInfo.cur rentAssemblyPat h;
    }
    }
    }

    Willy.

    Comment

    • Cramer

      #3
      Re: Determine if assembly is installed in the GAC

      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


      "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
      news:OeqsHKjpIH A.3568@TK2MSFTN GP04.phx.gbl...
      "Cramer" <A@B.comwrote in message
      news:upVDbjipIH A.3960@TK2MSFTN GP02.phx.gbl...
      >I'm wondering if there is an easy way to programmaticall y 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(p ath)) - 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("fusi on.dll")]
      internal static extern IntPtr CreateAssemblyC ache(
      out IAssemblyCache ppAsmCache,
      int reserved);
      >
      }
      // GAC Interfaces - IAssemblyCache. As a sample, non used vtable
      entries declared as dummy.
      [ComImport, InterfaceType(C omInterfaceType .InterfaceIsIUn known),
      Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
      internal interface IAssemblyCache
      {
      int Dummy1();
      [PreserveSig()]
      IntPtr QueryAssemblyIn fo(
      int flags,
      [MarshalAs(Unman agedType.LPWStr )]
      String assemblyName,
      ref ASSEMBLY_INFO assemblyInfo);
      int Dummy2();
      int Dummy3();
      int Dummy4();
      }
      [StructLayout(La youtKind.Sequen tial)]
      internal struct ASSEMBLY_INFO
      {
      public int cbAssemblyInfo;
      public int assemblyFlags;
      public long assemblySizeInK B;
      [MarshalAs(Unman agedType.LPWStr )]
      public String currentAssembly Path;
      public int cchBuf;
      }
      >
      class Program
      {
      static void Main()
      {
      try
      {
      Console.WriteLi ne(QueryAssembl yInfo("System") );
      }
      catch(System.IO .FileNotFoundEx ception e)
      {
      Console.WriteLi ne(e.Message);
      }
      }
      // If assemblyName is not fully qualified, a random matching may be
      returned!!!!
      public static String QueryAssemblyIn fo(String assemblyName)
      {
      ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO ();
      assembyInfo.cch Buf = 512;
      assembyInfo.cur rentAssemblyPat h = new String('\0',
      assembyInfo.cch Buf) ;
      IAssemblyCache assemblyCache = null;
      // Get IAssemblyCache pointer
      IntPtr hr = GacApi.CreateAs semblyCache(out assemblyCache, 0);
      if (hr == IntPtr.Zero)
      {
      hr = assemblyCache.Q ueryAssemblyInf o(1, assemblyName, ref
      assembyInfo);
      if(hr != IntPtr.Zero)
      Marshal.ThrowEx ceptionForHR(hr .ToInt32());
      }
      else
      Marshal.ThrowEx ceptionForHR(hr .ToInt32());
      return assembyInfo.cur rentAssemblyPat h;
      }
      }
      }
      >
      Willy.
      >
      >


      Comment

      • Ignacio Machin ( .NET/ C# MVP )

        #4
        Re: Determine if assembly is installed in the GAC

        On Apr 24, 12:32 pm, "Cramer" <A...@B.comwrot e:
        I'm wondering if there is an easy way to programmaticall y 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(pa th)) - but for an assembly, of a particular version, etc in
        the GAC.
        >
        I have googled this and failed to find anything useful.
        >
        Thanks
        Hi,

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

        Comment

        • Willy Denoyette [MVP]

          #5
          Re: Determine if assembly is installed in the GAC

          "Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin @gmail.comwrote in
          message
          news:e63b059c-0512-40de-a491-9a484a37204f@y3 8g2000hsy.googl egroups.com...
          On Apr 24, 12:32 pm, "Cramer" <A...@B.comwrot e:
          I'm wondering if there is an easy way to programmaticall y 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(pa th)) - but for an assembly, of a particular version, etc in
          the GAC.
          >
          I have googled this and failed to find anything useful.
          >
          Thanks
          Hi,

          IT should be simple, first you need a reference to the assembly (you
          can use Assembly.GetAss embly(typeof( XXXX ) ); where XXXX is defined
          in that assembly)
          Then using Assembly.Locati on 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.

          Comment

          • parez

            #6
            Re: Determine if assembly is installed in the GAC

            On Apr 24, 12:32 pm, "Cramer" <A...@B.comwrot e:
            I'm wondering if there is an easy way to programmaticall y 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(pa th)) - but for an assembly, of a particular version, etc in
            the GAC.
            >
            I have googled this and failed to find anything useful.
            >
            Thanks
            Try Assembly.LoadWi thPartialName(" SomeName");

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

            that mite work..

            Comment

            • Cramer

              #7
              Re: Determine if assembly is installed in the GAC

              RE:
              IT should be simple, first you need a reference to the assembly (you
              can use Assembly.GetAss embly(typeof( XXXX ) ); where XXXX is defined
              in that assembly)
              Then using Assembly.Locati on should be enough.

              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



              Comment

              • parez

                #8
                Re: Determine if assembly is installed in the GAC

                On Apr 24, 5:15 pm, "Cramer" <A...@B.comwrot e:
                RE:
                >
                IT should be simple, first you need a reference to the assembly (you
                can use Assembly.GetAss embly(typeof( XXXX ) ); where XXXX is defined
                in that assembly)
                Then using Assembly.Locati on should be enough.
                >
                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
                Try Assembly.LoadWi thPartialName(" SomeName");

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

                that mite work..

                Comment

                Working...