如何防止未找到引用的程序集时崩溃?
问题描述:
我有一个使用Team System API的小命令行程序。当机器上没有安装正确的团队系统,该程序将打印System.IO.FileNotFoundException回溯,但它也崩溃和显示标准错误讯息支付:如何防止未找到引用的程序集时崩溃?
XXX遇到问题, 需要关闭。我们很抱歉 不便。
我只是想让我的程序打印一个“该程序需要Team System 2008”消息给控制台并退出而不会崩溃。
从我所了解的整个加载过程发生在我的C#代码的第一行运行之前。有什么办法可以控制这个吗?
答
.NET代码即时编译上的方法,通过方法的基础。你的“Main”方法是否引用外部库?如果是的话,可以考虑:
[MethodImpl(MethodImplOptions.NoInlining)]
static int Main() { // add "args" etc if needed
try {
return Main2();
} catch (Exception ex) {
Console.Error.WriteLine(ex.Message);
return 1;
}
}
static int Main2() { // add "args" etc if needed
// your real code
}
我不能保证它会工作,但它是值得一试...
答
你可以尝试Override CLR Assembly Probing Logic
在.NET Framework,解决集引用时,对CLR首先检查GAC,然后搜索特定位置的应用程序目录。如果程序集不在这些位置之一中,CLR将触发AssemblyResolve事件。您可以订阅AssemblyResolve事件并使用Assembly.LoadFrom/LoadFile等返回程序集。
但是,就您而言,您只需显示您的消息箱,然后以干净的方式关闭即可。
答
是的。在第一次使用一个类型时,程序集将被加载,该类型本身引用要加载的程序集中的类型。
因此,解决方案是创建一个辅助类,该类包装与API的所有交互。然后在try/catch中调用这个包装类。
是这样的:
public class Program
{
static void Main()
{
try
{
WrapperClass.CallApi(...);
}
catch(FileNotFoundException)
{
... you can e.g. show a MessageBox and exit here ...
}
}
}
internal class WrapperClass
{
public void CallApi(...)
{
... you can reference types from the Team System assembly in WrapperClass
}
}
谢谢,但显然组件加载我的任何代码运行之前,我可以甚至没有达到Main的第一行。 – gooli 2008-10-18 12:11:10
是的,因为你直接在Main方法中引用它。如果你从一个单独的类引用(或者像Marc Gravell指出的那样,甚至是一个单独的方法),你的Main将被执行,你可以捕获异常。 – Joe 2008-10-18 13:53:39