如何检查某个程序集是不是存在?

Posted

技术标签:

【中文标题】如何检查某个程序集是不是存在?【英文标题】:How to check if a certain assembly exists?如何检查某个程序集是否存在? 【发布时间】:2011-02-07 09:13:47 【问题描述】:

我正在使用Activator 根据程序集的短名称(例如“CustomModule”)实例化一个新类。它抛出FileNotFoundException,因为程序集不存在。 有没有办法检查某个程序集名称是否存在?

我正在使用以下代码:

System.Runtime.Remoting.ObjectHandle obj = 
    System.Activator.CreateInstance(assemblyName, className);

主要目标是测试程序集是否存在,而不是等待异常发生。

【问题讨论】:

您的意思是加载到当前的应用程序域? assemblyName 是什么?完全限定的程序集名称或物理文件路径? @MrDisaapointment 我唯一知道的是我的数据库中有一个“CustomModule”。如果我的 bin 或 GAC (!?) 中存在 CustomModule.dll,它将生成由类名指定的类。 查看我的最新更新,希望这足以继续。 嗯....Net 1.1 方法使用 Assembly.LoadWithPartialName,如果程序集不存在,它将返回“null”。 (?) 是的,如果程序集不存在,那么您会得到null,但是您已经完成了所有可能的检查(假设您在我的答案中采用了代码),那么是时候获取FileNotFoundException了。 【参考方案1】:

如果您注意到我对您的问题的评论,很明显我不确定您想要或需要如何处理此问题,但直到我们有更详细的描述我只能为您提供这个,希望它适合您的情况(关键在于“搜索”程序集):

var className = "System.Boolean";
var assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var assembly = (from a in assemblies
                where a.FullName == assemblyName
                select a).SingleOrDefault();
if (assembly != null)

    System.Runtime.Remoting.ObjectHandle obj = 
        System.Activator.CreateInstance(assemblyName, className);             

.NET 2.0 兼容代码

Assembly assembly = null;
var className = "System.Boolean";
var assemblyName = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

foreach (var a in AppDomain.CurrentDomain.GetAssemblies())

    if (a.FullName == assemblyName)
    
        assembly = a;
        break;
    


if (assembly != null)

    System.Runtime.Remoting.ObjectHandle obj =
        System.Activator.CreateInstance(assemblyName, className);

如果您想在尝试加载文件之前确定该文件是否存在(一个好的做法),那么在您知道文件名并知道所需位置的情况下,只需在解析程序集时尝试查找该文件:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

var className = "***Lib.Class1";
var assemblyName = "***Lib.dll";
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var obj = Activator.CreateInstance(Path.Combine(currentAssemblyPath, assemblyName), className);

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)

    var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    if (File.Exists(Path.Combine(currentAssemblyPath, args.Name)))
    
        return Assembly.LoadFile(Path.Combine(currentAssemblyPath, args.Name));
    
    return null;

【讨论】:

@MrDisappointment,感谢您的代码。我没有说明我正在使用 .Net 2.0 这不是只返回 AppDomain 中已经加载的程序集吗? @mmix 有一个有效点。我可能在 bin 目录中存在一个尚未加载的 dll。 我同意,正如我在回答和评论中所说:您究竟想如何做到这一点尚不确定,所以我没有太多可做的事情。 嗯....Net 1.1 方法使用 Assembly.LoadWithPartialName,如果程序集不存在,它将返回“null”。【参考方案2】:

我认为最好不要试图避免异常。原因是如果你有类似的代码

if (DoesAssemblyExist(asmName)) 
    object = Activator.CreateInstance(typeName);

else 
    MessageBox.Show("Assembly does not exist");

在先发制人的多任务操作系统中,总是存在在检查和实际创建之间添加/删除程序集的风险。是的,我意识到这种风险很小,但我仍然认为异常变体看起来更好,因为它是原子的。

【讨论】:

【参考方案3】:

缺少程序集肯定是异常,try/catch FileNotFoundException 并按照你的逻辑处理。

【讨论】:

100% 正确!但我想对其进行测试,而不是等待异常发生。 在我的头顶上,我认为您不会轻易管理这个,因为您必须模拟一个完整的探测算法。它也容易出错(应该说应用程序域安装了自己的探测过程)。对于第一站看,如果您仍然想要这个,请查看此链接:[运行时如何定位程序集]:msdn.microsoft.com/en-us/library/yx7xezcf.aspx【参考方案4】:

我希望它对将来的某人有所帮助:

在您使用的每个外部 .dll 上,创建自己的唯一密钥,如下所示:

字符串键 = "fjrj3288skckfktk4owoxkvkfk4o29dic";

然后,当您加载表单时,对于您拥有的每个外部 .dll,只需检查密钥是否存在,如下所示:

如果(isMyLib.Variables.key == 键) // 继续

否则 // .dll 不存在或损坏。

【讨论】:

以上是关于如何检查某个程序集是不是存在?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查程序集是不是已更改

如何检查 pdb 文件是不是对调试程序集有效

如何检查 BigQuery 中是不是存在数据集?

如何检查用户是不是已授予我的 PHP 应用程序的特定权限集?

如何在合并数据集之前检查行是不是存在(SQL Server)

如何在编译时检查是不是存在可以使用特定参数集调用的函数?