Как я могу поймать FileNotFoundException при запуске на Mono и отсутствует DLL? - PullRequest
0 голосов
/ 18 августа 2010

У меня есть рабочий стол Windows 7 x64 с vs2010 и установка виртуальной коробки Linux с моно и monodevelop.Я компилирую следующую программу с vs2010 и запускаю ее на виртуальной машине linux, и она завершается с ошибкой, которая, по-видимому, не поддается обнаружению FileNotFoundException.Если я скомпилирую его на виртуальной машине и запустлю в Windows, он прекрасно работает.

Проблема, похоже, заключается в том, что неуловимое исключение выбрасывается mono перед Main (), когда невозможно загрузить dll.Есть ли способ реструктурировать мою программу или заставить моно так, чтобы я мог поймать это исключение?

Я пытаюсь написать одну программу, которая имеет интерфейс в 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  
  }

 }

}

Ответы [ 3 ]

0 голосов
/ 18 августа 2010

Вы подвергаете себя деталям реализации JIT-компилятора.Точное время, когда он сгенерирует исключение для отсутствующей сборки, зависит от того, насколько охотно он переводит IL в машинный код.Я знаю, что джиттер Microsoft действительно своевременен, он компилирует по одному методу за раз, перед тем, как приступить к выполнению.Хотя это зависит от того, подключен ли отладчик.Ты мертв в воде, если Моно, скажем, соберет весь класс.Джиттер сработает до того, как Main () сможет запуститься.

Возможно, он будет работать лучше, если вы поместите Main2 () в другой класс.Лучшее, что можно сделать, - это просто иметь доступную сборку, если нужно, манекен.

0 голосов
/ 19 августа 2010

Вместо того, чтобы зависеть от лени загрузки ссылочной сборки, я предлагаю вам реализовать свой графический интерфейс для конкретной платформы в разных сборках, возможно, реализуя общий интерфейс.В этом случае основная сборка не будет иметь прямых ссылок на конкретные наборы инструментов GUI, но будет использовать отражение, чтобы попытаться загрузить WPF или GTK из GAC, и на основе этого будет использоваться отражение для загрузки конкретной сборки DLL GUI, создания экземпляра и использования реализации GUI..

Что-то вроде:

  • ProgramName.exe - содержит Main точку входа, IPlatformGui и логику, общую для всех платформ
  • ProgramName.Gtk.dll - содержит GtkGui : IPlatformGui
  • ProgramName.Wpf.dll - содержит WpfGui : IPlatformGui
0 голосов
/ 18 августа 2010

Какая DLL не найдена?Я предполагаю, судя по вашему коду, это, вероятно, WinForms.Я не совсем знаком с препроцессором C #, но я думаю, что #if __MonoCS__ может быть более полезным (или может действовать только) как определение препроцессора, то есть оно не изменяется во время выполнения.Вы можете попробовать определить __MonoCS__ для сборки Mono в настройках проекта и запустить его (я думаю, VS не определяет это по умолчанию, поэтому, вероятно, все равно пытается работать с WinForms).

Еще одна вещь, которую стоит попробовать - это закомментировать using System.Windows и весь связанный с ним код (просто используя путь GTK / Mono) и проверить, работает ли он на Windows и на обоих.Если это так, то вы сузили возможные проблемы и включили их, и оттуда должно быть легче решить.

...