Как поймать FilenotFoundException при запуске на Mono и DLL отсутствует?

StackOverflow https://stackoverflow.com/questions/3515505

Вопрос

У меня есть рабочий стол Windows 7 x64 с VS2010 и установка виртуальной коробки Linux с Mono и Monodevelop. Я составляю следующую программу с VS2010 и запускаю ее в виртуальной машине Linux, и она не работает с, казалось бы, невозможным FilenotFoundException. Если я составляю его в виртуальной машине и запускаю его в Windows, он отлично работает.

Похоже, что проблема заключается в том, что моно бросается невозможным исключением перед 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  
  }

 }

}
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

  • ProgramName.exe - содержит Main точка входа, IPlatformGui, и логика, общая всеми платформами
  • ProgramName.gtk.dll - содержит GtkGui : IPlatformGui
  • ProgramName.wpf.dll - содержит WpfGui : IPlatformGui
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top