【发布时间】:2010-09-22 15:35:29
【问题描述】:
如果您尝试在未安装此版本 .NET 框架的 Windows 计算机上启动 .NET 3.5 应用程序,您会收到一些系统程序集的FileNotFoundException(例如 System.Core 3.5.0.0) .
是否有可能捕捉到这个异常并告诉用户升级他们的 .NET 框架,还是它抛出得太早而无法处理?
【问题讨论】:
如果您尝试在未安装此版本 .NET 框架的 Windows 计算机上启动 .NET 3.5 应用程序,您会收到一些系统程序集的FileNotFoundException(例如 System.Core 3.5.0.0) .
是否有可能捕捉到这个异常并告诉用户升级他们的 .NET 框架,还是它抛出得太早而无法处理?
【问题讨论】:
您目前如何部署应用程序? ClickOnce 可以在启动前进行组装 (GAC) 检查,并且使用 msi,您应该有一系列可用的预检查选项......虽然并不总是可行,但您可以考虑其中一个部署选项吗?
重新捕获异常 - 只需确保将 Main 拆分,以便它除了捕获异常之外什么都不做 - 否则 JIT 可能会阻止 Main 加载:
// [STAThread] here if winform
[MethodImpl(MethodImplOptions.NoInlining)]
static void Main() {
try {
MainCore();
} catch (SomeException ex) {
// TODO something simple but fun
}
}
static void MainCore() { ... } // your app here...
如果你在外部 Main 中放的太多,它可能会在运行 any 之前出现问题,因为 JIT 可能需要这些类型。
【讨论】:
最简单的就是尝试一下。 (我没有任何非 3.5 的机器来测试它,但我假设你有。)
让您的入口点变得非常简单,它只是尝试加载System.Core.dll 并适当地处理异常。如果它通过,则转到另一个可以使用它的类。如果失败,给出相应的错误信息并退出。
我怀疑你不需要有这个级别的隔离 - 只要你没有任何不可用类型的字段,我不希望程序集是解决,直到您第一次调用需要它的方法。我必须通过 C# 咨询 CLR 来检查。然而,保持它完全隔离可能会更安全——它可以避免你以后不小心引入依赖项。哎呀,你甚至可以将你的“启动和检查”类型放在一个单独的程序集中,如果一切正常,它什么都不做,只是启动另一个。
【讨论】:
你可以捕捉到那个异常,是的。
在您的主程序中,只需在主消息循环周围使用 try..catch。
try
{
Application.Run(new MainForm());
}
catch (Exception ex)
{
if (ex.MessageContains("Could not load file or assembly 'System.Core, Version=3.5.0.0"))
{
MessageBox.Show("This product requires the Microsoft .NET Framework version 3.5, or greater, in order to run.\n\nPlease contact your System Administrator for more information.");
}
}
【讨论】: