我想使用反射在GAC中动态加载最新安装的程序集版本。
到目前为止,我已经找到了多种方法来实现这一目标,但它们都有其特定的缺点。
最简单的解决方案是使用Assembly.LoadWithPartialName()
方法。但是,自.NET Framework 2以来,这种方法已经过时了:
var assembly = Assembly.LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");
另一种可能性是使用Assembly.Load()
(根据过时警告的建议)并在try / catch块中使用其完全限定的程序集名称调用不同的程序集版本以获取最新安装的版本。这让人感到尖叫,只是看起来很脏:
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) { }
最后但并非最不重要的是another solution我在这里使用Assembly.LoadFrom()
方法找到了SO,然后基本上导入了程序集管理器模块fusion.dll
来计算最新版本的路径。对于这样一个“简单”的任务来说,这似乎太过分了。
如果没有使用过时的方法,使用魔术字符串创建维护地狱或调用非托管代码,是否有更好的解决方案?
提前致谢!
答案 0 :(得分:2)
Fusion.dll ......呃。我会找到你的目标框架版本并枚举所有的gas目录,并简单地根据根程序集名称查询它们,这样你唯一的魔术字符串就是程序集名称。然后,使用Assembly.ReflectionOnlyLoadFrom静态方法比较版本,直到找到最新的版本,然后使用Assembly.Load方法和相应的文件路径参数。除非您已经为应用程序提供了适当的信任,否则您可能会遇到单击一次下载的问题。
// 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/>");
}
}
}
见this other answer here on stack overflow。我用它来成功枚举gac。