在 Mono 上运行且缺少 DLL 时如何捕获 FileNotFoundException?

发布于 2024-09-15 03:13:55 字数 973 浏览 9 评论 0原文

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

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

我正在尝试根据运行时可用的内容编写一个在 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  
  }

 }

}

I have a windows 7 x64 desktop with vs2010 and a virtual box installation of linux with mono and monodevelop. I compile the following program with vs2010 and run it in the linux virtual machine and it fails with a seemingly uncatchable FileNotFoundException. If I compile it in the virtual machine and run it in windows, it works great.

The problem seems to be that an uncatchable exception is tossed by mono before Main() when it is impossible to load a dll. Is there a way to restructure my program or coerce mono such that I can catch this exception?

I am trying to write a single program that has an interface in either WPF or GTK according to what is available at runtime.

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  
  }

 }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦过后 2024-09-22 03:13:55

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

如果将 Main2() 放在另一个类中,也许效果会更好。最好的办法就是准备一个可用的组件,如果需要的话还可以准备一个假人。

You are exposing yourself to the implementation details of the JIT-compiler. The exact time it will throw the exception for the missing assembly depends on how eagerly it translates the IL into machine code. I know the Microsoft jitter is truly just-in-time, it compiles one method at a time, just before it is about to execute. Although this is affected by whether or not a debugger is attached. You're dead in the water if Mono, say, compiles the entire class. The jitter will throw before Main() can start.

Maybe it will work better if you put Main2() in another class. The best thing to do is just have an assembly available, a dummy if necessary.

原野 2024-09-22 03:13:55

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

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

What DLL is not found? I'm assuming, judging from your code, it's probably WinForms. I'm not entirely familiar with the C# preprocessor, but I think #if __MonoCS__ may be more useful (or may act only) as a preprocessor define, that is, it doesn't change at runtime. You may try defining __MonoCS__ for the Mono build in the project settings and run that (I would think VS doesn't define that by default, so it's probably trying to work with WinForms anyway).

Another thing to try is commenting out the using System.Windows and all its related code (just using the GTK/Mono path) and test if that builds on Windows and runs on both. If so, then you've narrowed the possible problems down to just that include, and it should be easier to solve from there.

征﹌骨岁月お 2024-09-22 03:13:55

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

类似于:

  • ProgramName.exe - 包含 Main 入口点、IPlatformGui 以及所有平台共享的逻辑
  • ProgramName.Gtk.dll - 包含 GtkGui : IPlatformGui >
  • ProgramName.Wpf.dll - 包含 WpfGui : IPlatformGui

Instead of depending on the laziness of referenced assembly loading, I suggest you implement your platform-specific GUIs in different assemblies, perhaps implementing a common interface. The main assembly would then have no direct references to specific GUI toolkits, but would use reflection to try to load WPF or GTK from the GAC, and based on that would use reflection to load a specific GUI dll assembly and instantiate and use the GUI implementation.

Something like:

  • ProgramName.exe - contains Main entry point, IPlatformGui, and logic shared by all platforms
  • ProgramName.Gtk.dll - contains GtkGui : IPlatformGui
  • ProgramName.Wpf.dll - contains WpfGui : IPlatformGui
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文