5

I'd like to dynamically load the latest installed version of an assembly in the GAC using reflections.

So far I've found multiple working ways to accomplish this but they're all having their specific downsides.

The easiest solution is using the Assembly.LoadWithPartialName() method. But this method is obsolete since .NET Framework 2:

var assembly = Assembly.LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");

Another possibility is to use Assembly.Load() (as recommended by the obsolete warning) and call the different assembly versions with their fully qualified assembly name in a try/catch block to get the latest installed version. This screams for maintenance and just looks dirty:

Assembly assembly = null;

try
{
    assembly = Assembly.Load("Microsoft.WindowsAzure.ServiceRuntime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
}
catch (FileNotFoundException) { }

try
{
    assembly = Assembly.Load("Microsoft.WindowsAzure.ServiceRuntime, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
}
catch (FileNotFoundException) { }

Last but not least there's another solution I found here on SO using the Assembly.LoadFrom() method and then basically importing the assembly manager module fusion.dll to figure the path of the latest version. This seems to be way too much for such a "simple" task.

Isn't there any better solution to accomplish that without using an obsolete method, creating a maintenance hell with magic strings or by calling unmanaged code?

Thanks in advance!

Community
  • 1
  • 1
Martin Buberl
  • 45,844
  • 25
  • 100
  • 144

1 Answers1

3

Fusion.dll... ugh. I would find your target framework version and enumerate all of the gas directories and simply query them based on the root assembly name so that your only magic string is the assembly name. Then, use Assembly.ReflectionOnlyLoadFrom static method to compare the versions of until you find the latest one and then use the Assembly.Load method with the appropriate file path arguments. You may have trouble with this using click-once download unless you have given the app the appropriate trust.

// List of all the different types of GAC folders for both 32bit and 64bit
// environments.
List<string> gacFolders = new List<string>() { 
    "GAC", "GAC_32", "GAC_64", "GAC_MSIL", 
    "NativeImages_v2.0.50727_32", 
    "NativeImages_v2.0.50727_64" 
};

foreach (string folder in gacFolders)
{
    string path = Path.Combine(@"c:\windows\assembly", folder);
    if(Directory.Exists(path))
    {
        Response.Write("<hr/>" + folder + "<hr/>");

        string[] assemblyFolders = Directory.GetDirectories(path);
        foreach (string assemblyFolder in assemblyFolders)
        {
            Response.Write(assemblyFolder + "<br/>");
        }
    }
}

See this other answer here on stack overflow. I used this to enumerate the gac successfully.

Community
  • 1
  • 1
EdFred
  • 661
  • 4
  • 10
  • not directly related, but one should notice that sometimes DLLs are installed (?) under `temp` folder for some weird reason. – itsho Jan 15 '15 at 15:33