Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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# 在Mono上运行并且缺少DLL时,如何捕获FileNotFoundException?_C#_.net_Dll_Mono_Filenotfoundexception - Fatal编程技术网

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

C# 在Mono上运行并且缺少DLL时,如何捕获FileNotFoundException?,c#,.net,dll,mono,filenotfoundexception,C#,.net,Dll,Mono,Filenotfoundexception,我有一个带vs2010的Windows7x64桌面和一个带mono和monodevelop的linux虚拟机安装。我用vs2010编译了下面的程序,并在linux虚拟机上运行它,它失败了,出现了一个看似不可修补的FileNotFoundException。如果我在虚拟机中编译它并在windows中运行它,它将非常有效 问题似乎在于,当无法加载dll时,mono会在Main()之前抛出不可修补的异常。有没有办法重组我的程序或强制mono,这样我就可以捕捉到这个异常 我试图编写一个程序,根据运行时可

我有一个带vs2010的Windows7x64桌面和一个带mono和monodevelop的linux虚拟机安装。我用vs2010编译了下面的程序,并在linux虚拟机上运行它,它失败了,出现了一个看似不可修补的FileNotFoundException。如果我在虚拟机中编译它并在windows中运行它,它将非常有效

问题似乎在于,当无法加载dll时,mono会在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  
  }

 }

}

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


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

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


如果将Main2()放在另一个类中,可能效果会更好。最好的办法就是有一个可用的程序集,如果需要的话,可以使用一个虚拟程序集。

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

比如:

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

将Main2放到另一个类中没有帮助。你说的有道理,尽管抛出不可跟踪异常的想法让我非常沮丧。我将把这个问题留一段时间,看看是否有人有一个神奇的答案,但似乎不可避免的是,我会给你答案。谢谢。Linux上的PresentationFramework是第一个触发异常的DLL。在窗户上是GTK夏普。此程序中未使用Winforms。这个程序的全部目的是让它抛出一个异常,这样我就可以看到在哪里捕获它是合适的,所以注释掉你提到的各种代码会使这个练习变得不可能。如果有更好的方法让一个.exe能够在运行时在两个API之间进行选择,我洗耳恭听。啊,那么你使用的是表示框架,而不是表单?我认为这不会有多大变化。要使单个EXE能够在任何一个平台上运行,最好的方法是使用跨平台UI。GTK也适用于Windows,所以如果不麻烦的话,只使用它应该适合你。我最初想说的是,您得到异常的原因是系统没有像您预期的那样关注
#if
s,因此更改它们可能会更有帮助。不过,我对C#预处理器并不熟悉。如果没有其他办法,你可能只需要构建两次,一次用于Windows,一次用于Linux。正如我所期望的那样,它正在关注#ifs。他们应该强迫它总是使用错误的库。我想要例外。程序的全部要点是生成异常以捕获它。我想在很多情况下使用这种技术从各种库中进行选择。GTK和WPF只是一个例子。要做我想做的事似乎是不可能的。我不想强迫windows用户使用gtk。我可能会求助于你所说的。我想我没有其他选择了。我想我不能在这里选择一个以上的答案?我相信你们两个。