Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load latest assembly version dynamically from GAC

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!

like image 884
Martin Buberl Avatar asked Oct 22 '22 15:10

Martin Buberl


1 Answers

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.

like image 83
EdFred Avatar answered Nov 02 '22 10:11

EdFred