Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查引用的程序集在运行时是否可用?_C# - Fatal编程技术网

C# 如何检查引用的程序集在运行时是否可用?

C# 如何检查引用的程序集在运行时是否可用?,c#,C#,我正在创建一个简单、独立的.net winforms应用程序。它引用.Net Framework 4的程序集Microsoft.SqlServer.sqlwmi管理,该程序集可能存在于客户端计算机上,也可能不存在于客户端计算机上。如果该程序集不存在,那么在运行时,我希望我的应用程序能够正常地失败,而不是崩溃 我有一个启动的组件: ... using Microsoft.SqlServer.SqlWmiManagement; ... try { // do something that u

我正在创建一个简单、独立的.net winforms应用程序。它引用.Net Framework 4的程序集
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);