C# 如何检查引用的程序集在运行时是否可用?
我正在创建一个简单、独立的.net winforms应用程序。它引用.Net Framework 4的程序集C# 如何检查引用的程序集在运行时是否可用?,c#,C#,我正在创建一个简单、独立的.net winforms应用程序。它引用.Net Framework 4的程序集Microsoft.SqlServer.sqlwmi管理,该程序集可能存在于客户端计算机上,也可能不存在于客户端计算机上。如果该程序集不存在,那么在运行时,我希望我的应用程序能够正常地失败,而不是崩溃 我有一个启动的组件: ... using Microsoft.SqlServer.SqlWmiManagement; ... try { // do something that u
Microsoft.SqlServer.sqlwmi管理
,该程序集可能存在于客户端计算机上,也可能不存在于客户端计算机上。如果该程序集不存在,那么在运行时,我希望我的应用程序能够正常地失败,而不是崩溃
我有一个启动的组件:
...
using Microsoft.SqlServer.SqlWmiManagement;
...
try {
// do something that uses SqlWmiManagement
}
catch {
// handle the missing assembly
}
不幸的是,在加载组件时抛出了一个未处理的异常,远远早于我的小try块
正确的方法是什么
没有安装程序,这应该是一个拖放exe 当函数处于JIT状态时引发异常。将代码更改为:
void DoSomethingThatUsesSqlWmiManagement_()
{
...
}
void DoSomethingThatUsesSqlWmiManagement()
{
try
{
DoSomethingThatUsesSqlWmiManagement_();
}
catch
{
handle the missing assembly
}
}
您可能应该
仅捕获特定的异常
如果未找到程序集,则会触发AssemblyResolve事件。你可以尝试捕捉到它并在那里退出应用程序
确保包含Main()函数的类未引用与程序集相关的任何内容
如果它被定义为主窗体的一部分,请在它自己的类中取出它
然后,在方法的最开始使用Assembly.Load()。您必须将SqlWmiManagement.dll程序集的完全限定名作为参数传递。我想我通过更正代码中的作用域解决了这个问题。从这一条出发:
我将需要Microsoft.SqlServer.SqlWmiManagement
的方法移动到一个单独的类中。分离它意味着我可以在try{}
块中调用它,该块在导致隐式加载程序集的作用域之前启动。这意味着我可以从失败的程序集加载中捕获异常
而不是:
using Microsoft.SqlServer.SqlWmiManagement;
// .net implicitly loads assembly when current class is instantiated
// ... code ...
try {
// problem method using missing assembly
}
catch {
// this is ineffective because the ass'y load already failed before the try block
}
我能够:
try {
// invoke problem method in another class
// implicitly loads assembly here instead, inside the try block
}
catch {
// this now catches ass'y load failure
}
虽然@CC Inc的答案在调用Main()
后加载引用时有效,但对于使用静态对象或类的引用,需要在调用Main()
之前安装ResolveEventHandler
。您可以尝试:
private static bool gAutoLoad = ExecuteBeforeMain();
private static bool ExecuteBeforeMain()
{
// Note: AssemblyResolve only occurs when the resolution of an assembly fails.
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveErrorHandler;
return true;
}
private static System.Reflection.Assembly AssemblyResolveErrorHandler(object sender, ResolveEventArgs args)
{ ... }
我不认为可以保证ExecuteBeforeMain()
执行得足够早(在尝试加载引用之前),但当我将我的记录器包括在内时,它对我起到了作用,使用方式如下:
ReferenceNamespace.LoggerClass.StaticActiveLogger.LogMethod(string);
这是到目前为止我最喜欢的答案。谢谢,这个答案让我更接近
ReferenceNamespace.LoggerClass.StaticActiveLogger.LogMethod(string);