2008-11-17 6 views
3

Si vous essayez de lancer une application .NET 3.5 sur un ordinateur Windows sur lequel cette version de .NET Framework n'est pas installée, vous obtenez un FileNotFoundException pour certains assemblys système (par exemple System.Core 3.5.0.0).Comment éviter FileNotFoundException si .NET 3.5 n'est pas installé?

Est-il possible d'intercepter cette exception et d'indiquer à l'utilisateur de mettre à niveau son infrastructure .NET ou est-il lancé trop tôt pour le gérer?

Répondre

3

Comment êtes-vous en train de déployer l'application? ClickOnce peut faire des vérifications d'ensemble (GAC) avant le lancement, et avec msi vous devriez avoir toute une gamme d'options de pré-vérification disponibles ... bien que ce ne soit pas toujours faisable, vous pourriez considérer une de ces options de déploiement?

Re attrapant l'exception - juste être sûr de diviser la principale façon à ce qu'il ne rien sauf attraper l'exception - sinon JIT peut arrêter votre Main de chargement:

// [STAThread] here if winform 
[MethodImpl(MethodImplOptions.NoInlining)] 
static void Main() { 
    try { 
     MainCore(); 
    } catch (SomeException ex) { 
     // TODO something simple but fun 
    } 
} 

static void MainCore() { ... } // your app here... 

Si vous mettez trop dans le Main principal, il peut barf avant d'exécuter n'importe quel, puisque JIT pourrait avoir besoin des types.

+0

mec, vous venez de fournir la solution à quelque chose que j'ai travaillé toute la matinée, vous m'avez sauvé des heures de me cogner la tête contre le mur. Merci! – Epaga

+0

[MethodImpl (MethodImplOptions.NoInlining)] devrait être sur MainCore ici, ne devrait-il pas? –

+0

@Dave - très probablement; c'était il y a presque 2 ans, donc ma mémoire est brumeuse, mais ce que vous dites est logique. –

3

La chose la plus simple serait de l'essayer. (Je n'ai pas de machines non-3.5 pour le tester, mais je suppose que vous le faites.)

Faites votre point d'entrée un très simple qui essaie juste de charger System.Core.dll et gère l'exception de manière appropriée. S'il passe, passez à une autre classe qui peut alors l'utiliser. Si cela échoue, donnez le message d'erreur approprié et quittez. Vous ne devez pas avoir ce niveau d'isolation - tant que vous n'avez pas de champs qui sont indisponibles, je ne m'attendrais pas à ce que l'assemblage soit résolu jusqu'à ce que vous ayez appeler une méthode qui en a besoin. Je devrais consulter CLR via C# pour vérifier. Cependant, le garder tout à fait isolé serait probablement plus sûr - il évite que vous introduisiez accidentellement des dépendances plus tard. Heck, vous pourriez même avoir votre type "boot and check" dans un assemblage séparé qui n'a fait que lancer un autre si tout va bien.

2

Vous pouvez attraper cette exception, oui.

Dans votre routine principale, utilisez simplement un try..catch autour de votre boucle de messages principale.

try 
{ 
    Application.Run(new MainForm()); 
} 
catch (Exception ex) 
{ 
    if (ex.MessageContains("Could not load file or assembly 'System.Core, Version=3.5.0.0")) 
    { 
     MessageBox.Show("This product requires the Microsoft .NET Framework version 3.5, or greater, in order to run.\n\nPlease contact your System Administrator for more information."); 
    } 
} 
Questions connexes