0

我有一个带有 vs2010 的 windows 7 x64 桌面和一个带有 mono 和 monodevelop 的 linux 虚拟盒安装。我用 vs2010 编译以下程序并在 linux 虚拟机中运行它,它失败并出现看似无法捕获的 FileNotFoundException。如果我在虚拟机中编译并在windows中运行它,效果很好。

问题似乎是当无法加载 dll 时,在 Main() 之前,mono 抛出了一个无法捕获的异常。有没有办法重组我的程序或强制单声道,以便我可以捕捉到这个异常?

我正在尝试根据运行时可用的内容编写一个在 WPF 或 GTK 中具有接口的单个​​程序。

using System;  
#if __MonoCS__  
using Gtk;  
#else  
using System.Windows;  
#endif  
using System.IO;  
using System.Runtime.CompilerServices;  
using System.Collections.Generic;  

namespace Test {

 public static class Program {

  [STAThread]
  public static void Main() {
   try {
    Main2();
   } catch (FileNotFoundException e) {
    Console.WriteLine("Caught FileNotFoundException");
    Console.WriteLine("FileName = {0}", e.FileName);
   }
  }

  [MethodImpl(MethodImplOptions.NoInlining)]
  public static void Main2() {
#if __MonoCS__  
   Application.Init();  
#else  
   Window w = new Window();  
#endif  
  }

 }

}
4

3 回答 3

0

找不到什么DLL?我假设,从你的代码来看,它可能是 WinForms。我对 C# 预处理器并不完全熟悉,但我认为#if __MonoCS__作为预处理器定义可能更有用(或可能只起作用),也就是说,它在运行时不会改变。您可以尝试__MonoCS__在项目设置中定义 Mono 构建并运行它(我认为 VS 默认情况下没有定义它,所以它可能无论如何都在尝试使用 WinForms)。

要尝试的另一件事是注释掉using System.Windows它及其所有相关代码(仅使用 GTK/Mono 路径)并测试它是否在 Windows 上构建并在两者上运行。如果是这样,那么您已经将可能的问题缩小到仅包括在内,并且应该更容易从那里解决。

于 2010-08-18T18:54:51.483 回答
0

您将自己暴露于 JIT 编译器的实现细节。它为缺少的程序集抛出异常的确切时间取决于它将 IL 转换为机器代码的热切程度。我知道 Microsoft jitter 确实是即时的,它一次编译一个方法,就在它即将执行之前。尽管这受是否附加调试器的影响。比如说,如果 Mono 编译整个类,那你就死定了。抖动将在 Main() 启动之前抛出。

如果将 Main2() 放在另一个类中,它可能会更好。最好的办法就是准备一个可用的组件,必要时提供一个虚拟组件。

于 2010-08-18T18:56:20.610 回答
0

我建议您在不同的程序集中实现特定于平台的 GUI,而不是依赖于引用程序集加载的惰性,也许实现一个通用接口。主程序集将没有对特定 GUI 工具包的直接引用,但会使用反射尝试从 GAC 加载 WPF 或 GTK,并基于此使用反射加载特定 GUI dll 程序集并实例化和使用 GUI 实现.

就像是:

  • ProgramName.exe - 包含所有平台共享的Main入口点IPlatformGui和逻辑
  • ProgramName.Gtk.dll - 包含GtkGui : IPlatformGui
  • ProgramName.Wpf.dll - 包含WpfGui : IPlatformGui
于 2010-08-19T16:52:42.323 回答