none
Fusion API issue moving from 1.1 to 3.5 RRS feed

Answers

  • The reason I asked what you were doing with reguards to the filepath was because I was concerned you might be trying to load the assembly from the codebase, which is actually a misuse of this API (that's the strong warning - to avoid manually binding based on this info). Enumerating the assemblies in the GAC, on the other hand, is a perfectly acceptable use of the API.

    To answer one of your questions, as far as I know, the properties in question are immutable after the assembly is actually written to disk. They can be used internally to set the information during the process of creating or transforming the assembly. For example, in the managed API, some AssemblyName members are only mutable if you are compiling or creating dynamic assemblies in memory. If you load the AssmblyName for an assembly on file, then some of the properties aren't filled in (like the key pair) or aren't mutable. I'd expect something similar in the case of the unmanaged API.

    If all you are looking for is the company name, then an alternative might be to use managed reflection, and call Assembly.ReflectionOnlyLoad(...) which allow you to perform reflection on the assembly types without actually having to fully load and initialize the assembly itself (you get only the metadata). Once you have the assembly in reflection, you can look for the AssemblyCompanyAttribute.
    -Rob Teixeira
    • Marked as answer by DlgProc Monday, December 1, 2008 4:03 PM
    Wednesday, November 26, 2008 10:35 PM

All replies

  • I don't believe the GAC persists the location of a private assembly. In other words, if you register an assembly with the GAC, the previous file location is no longer relevant - it could be moved, destroyed, etc. and has no impact on the GAC file itself. In the managed API, the CodeBase (if applied to a GAC-loaded assembly) is the path where the GAC has installed the assembly, not the location of the assembly as it was when it was still a private assembly. I'd expect the same behavior from the Fusion API, so that's not surprising.

    Second, what are you trying to do with this information? The reason I ask is that there's a rather important disclaimer about the unmanaged Fusion API (quoted from MS):

    "MORE INFORMATION
    CAUTION: Do not use these APIs in your application to perform assembly binds or to test for the presence of assemblies or other run time, development, or design-time operations. Only administrative tools and setup programs must use these APIs. If you use the GAC, this directly exposes your application to assembly binding fragility or may cause your application to work improperly on future versions of the .NET
    Framework.

    The GAC stores assemblies that are shared across all applications on a computer. The actual storage location and structure of the GAC is not documented and is subject to change in future versions of the .NET Framework and the Microsoft Windows operating system."


    -Rob Teixeira
    Tuesday, November 25, 2008 9:48 PM
  • Hi Rob,


    Thanks for replying.

    I’m trying to determine what libraries that belong to my company are installed in the GAC. In order to do this I was getting the location to the DLL and using the System.Diagnostics.FileVersionInfo.GetVersionInfo() method to look at the CompanyName property to see if it belonged to me. As far as the disclaimer goes, (which I’m assuming you quoted from http://support.microsoft.com/kb/317540), it goes on to state that:

     

    The only supported method to access assemblies in the GAC is through the APIs that are documented in this article.

     

    Most applications do not have to use these APIs because the assembly binding is performed automatically by the common language runtime. Only custom setup programs or management tools must use these APIs. Microsoft Windows Installer has native support for installing assemblies to the GAC.

     

    Use the GAC API in the following scenarios:

    • When you install an assembly to the GAC.
    • When you remove an assembly from the GAC.
    • When you export an assembly from the GAC.
    • When you enumerate assemblies that are available in the GAC.

     

    I’m trying to do that last item; enumerate assemblies that are available in the GAC and get some information about it after I find it. I consider this to be a “custom setup program” which, according to the disclaimer, falls under the list of valid uses of the API.

     

    In any event, I’d still like to know what the purpose of SetProperty is if the value I set doesn’t persist after the object is destroyed. Is it possible I’m missing a step to “save” or “commit” the property value after I use SetProperty?

     

    Thanks for your help.

    Wednesday, November 26, 2008 3:07 PM
  • The reason I asked what you were doing with reguards to the filepath was because I was concerned you might be trying to load the assembly from the codebase, which is actually a misuse of this API (that's the strong warning - to avoid manually binding based on this info). Enumerating the assemblies in the GAC, on the other hand, is a perfectly acceptable use of the API.

    To answer one of your questions, as far as I know, the properties in question are immutable after the assembly is actually written to disk. They can be used internally to set the information during the process of creating or transforming the assembly. For example, in the managed API, some AssemblyName members are only mutable if you are compiling or creating dynamic assemblies in memory. If you load the AssmblyName for an assembly on file, then some of the properties aren't filled in (like the key pair) or aren't mutable. I'd expect something similar in the case of the unmanaged API.

    If all you are looking for is the company name, then an alternative might be to use managed reflection, and call Assembly.ReflectionOnlyLoad(...) which allow you to perform reflection on the assembly types without actually having to fully load and initialize the assembly itself (you get only the metadata). Once you have the assembly in reflection, you can look for the AssemblyCompanyAttribute.
    -Rob Teixeira
    • Marked as answer by DlgProc Monday, December 1, 2008 4:03 PM
    Wednesday, November 26, 2008 10:35 PM
  • Thanks Rob,

    That’s good to know about the properties. I didn’t think it worked like that but now on retrospect that makes sense.

    What I ended up doing was recursively plowing though the GAC directory tree starting at C:\WINDOWS\Assebmly looking for *.DLL and using the System.Diagnostics.FileVersionInfo.GetVersionInfo() method to get the company name. No assembly loading and reflection was required. I was just trying to make it a little smarter by having the GAC enumerator find some quirk about the assembly (like a custom property value) that would signal that it was one of ours and verify it with the GetVersionInfo() method. That way I wouldn’t have to visit every DLL in the GAC. Naming it starting with the company would have been a good idea too but our company has gone though so many name changes in the past years, I didn’t think that would be a good idea.

    Anyway, thanks for your help.

    Monday, December 1, 2008 4:03 PM