Comment puis-je attraper FileNotFoundException lors de l'exécution sur Mono et une DLL est manquante?
-
29-09-2019 - |
Question
J'ai un bureau Windows 7 x64 avec VS2010 et une installation de boîte virtuelle de Linux avec mono et monodevelop. Je compilez le programme suivant avec VS2010 et l'exécuter dans la machine virtuelle Linux et il échoue avec un FileNotFoundException apparemment insaisissable. Si je compile dans la machine virtuelle et l'exécuter dans Windows, il fonctionne très bien.
Le problème semble être qu'une exception uncatchable est lancée par mono avant principal () quand il est impossible de charger une dll. Est-il un moyen de restructurer mon programme ou coerce mono ce que je peux attraper cette exception?
Je suis en train d'écrire un seul programme qui a une interface dans WPF ou GTK selon ce qui est disponible lors de l'exécution.
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
}
}
}
La solution
Vous vous exposez à des détails d'implémentation du compilateur JIT. L'heure exacte, il va jeter l'exception des disparus dépend de la façon dont l'assemblage avidement se traduit par l'IL en code machine. Je sais que la gigue Microsoft est vraiment juste à temps, il compile une méthode à la fois, juste avant qu'il ne soit sur le point d'exécuter. Bien que cela soit affectée par si oui ou non un débogueur est attaché. Vous êtes mort dans l'eau si Mono, disons, compile toute la classe. La gigue jetteront avant Main () peut commencer.
Peut-être que cela fonctionnera mieux si vous mettez Main2 () dans une autre classe. La meilleure chose à faire est juste un assemblage ont disponible, un mannequin si nécessaire.
Autres conseils
Qu'est-ce que DLL est introuvable? Je suppose, à en juger à partir de votre code, il est probablement WinForms. Je ne suis pas tout à fait familier avec le C # préprocesseur, mais je pense que #if __MonoCS__
peut être plus utile (ou peut agir uniquement) en tant que préprocesseur définir, qui est, il ne change pas lors de l'exécution. Vous pouvez essayer de définir __MonoCS__
pour la construction Mono dans les paramètres du projet et exécuter que (je pense VS ne définit pas que par défaut, il essaie sans doute de travailler avec WinForms de toute façon).
Une autre chose à essayer est Décommenter le using System.Windows
et tout son code associé (juste en utilisant le chemin GTK / Mono) et le test si cela fait fond sur Windows et fonctionne sur les deux. Si oui, alors vous avez réduit les problèmes possibles vers le bas juste qui comprennent, et il devrait être plus facile à résoudre à partir de là.
Au lieu de dépendre de la paresse de chargement d'assemblage référencé, je vous suggère de mettre en œuvre vos interfaces graphiques spécifiques à la plateforme dans les différentes assemblées, la mise en œuvre peut-être une interface commune. L'assemblage principal aurait alors aucune référence directe à des boîtes à outils de l'interface graphique spécifique, mais utiliserait la réflexion pour tenter de charger WPF ou GTK du GAC, et sur cette base utiliserait la réflexion pour charger un ensemble dll GUI spécifique et instancier et utiliser l'implémentation de l'interface .
Quelque chose comme:
- ProgramName.exe - contient point d'entrée
Main
,IPlatformGui
et logique partagée par toutes les plates-formes - ProgramName.Gtk.dll - contient
GtkGui : IPlatformGui
- ProgramName.Wpf.dll - contient
WpfGui : IPlatformGui