2010-12-29 7 views
3

Nicht zu schlagen die deadhorse, jedoch suche ich nach einer Möglichkeit, die installierten .NET-Frameworks zu erkennen. Es scheint so, als ob die bereitgestellten Lösungen (in den Links) alle gut sind bis zu dem Punkt, an dem eine neue Version des Frameworks veröffentlicht wird und dann alle Wetten aus sind. Der Grund dafür ist, dass die Erkennung auf den Registrierungsschlüsseln beruht und es scheint, dass v4 des Frameworks die Konvention gebrochen hat und man jetzt zusätzliche Schritte unternehmen muss, um v4 zu erkennen.Zukunftssichere .NET-Versionserkennung

Gibt es eine Möglichkeit das .NET Framework zu erkennen, die auch funktionieren, wenn .NET v5 erscheint.

EDIT: Ok, für zukünftige Generationen von frustrierten Sucher .NET Version, hier ist der Code, um sie geschehen:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Diagnostics; 
using Microsoft.Win32; 

private List<string> GetInstalledDotNetFrameworks() 
{ 
    string key = string.Empty; 
    string version = string.Empty; 
    List<string> frameworks = new List<string>(); 

    var matches = Registry.LocalMachine 
       .OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP") 
       .GetSubKeyNames().Where(keyname => Regex.IsMatch(keyname, @"^v\d")); 


    // special handling for v4.0 (deprecated) and v4 (has subkeys with info) 
    foreach (var item in matches) 
    { 
     switch (item) 
     { 
      case "v4.0": // deprecated - ignore 
       break; 

      case "v4":// get more info from subkeys 

       key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item; 
       string[] subkeys = Registry.LocalMachine 
        .OpenSubKey(key) 
        .GetSubKeyNames(); 


       foreach (var subkey in subkeys) 
       { 
        key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item + @"\" + subkey; 
        version = Registry.LocalMachine 
          .OpenSubKey(key) 
          .GetValue("Version").ToString(); 

        version = string.Format("{0} ({1})", version, subkey); 
        frameworks.Add(version); 
       } 


       break; 
      case "v1.1.4322": // special case, as the framework does not follow convention 
       frameworks.Add(item); 
       break; 
      default: 

       try 
       { 
        // get the Version value 
        key = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\" + item; 
        version = Registry.LocalMachine 
          .OpenSubKey(key) 
          .GetValue("Version").ToString(); 

        frameworks.Add(version); 

       } 
       catch 
       { 
        // most likely new .NET Framework got introduced and broke the convention 
       } 

       break; 

     } 

    } 

    // sort the list, just in case the registry was not sorted 
    frameworks.Sort(); 

    return frameworks; 
} 

Antwort

4

Kurz gesagt, Sie dies etwa verwenden können (siehe unten für weitere Komplettlösung):

Microsoft.Win32.Registry.LocalMachine 
    .OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP") 
    .GetSubKeyNames().Where(keyname=>Regex.IsMatch(keyname,@"^v\d")) 

Auf meinem Rechner dies zurück: v2.0.50727, v3.0, v3.5, v4, v4 .0. Unterschlüssel könnten verwendet werden, um Service Packs zu erkennen (die wahrscheinlich relevant sind). Auch mit dem Schlüssel SOFTWARE\Microsoft\.NETFramework gibt v2.0.50727, v3.0 und v4.0.30319 - ehhh, schön, etwas anders!

Es gibt keine Garantie, dieses Muster halten wird, aber es ist eine ziemlich vernünftige Wette :-). http://support.microsoft.com/kb/318785 hat einige weitere Informationen über die Details der Registrierung beschreibt die Versionierung, und insbesondere können Sie müssen für Install überprüfen - aber das ist schwierig wie v4.0 demonstriert.

Edit: ich diese verlängert habe beliebigen Unterschlüssel die von der Registrierung zu erkennen, die Installation Informationen enthalten, um v4-Client und ein Profil korrekt zu erfassen. Auch der RegistryKey Typ ist IDisposable, und es sieht aus wie die Dispose-Methode ist in der Tat etwas (Registrierungsschlüssel Entriegelung) zu tun.

var versionList = new List<string>(); 
using(var ndpKey=Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP")) { 
    Action<RegistryKey, Action<RegistryKey,string>> processKids = (node, action) => { 
     foreach(var childname in node.GetSubKeyNames()) 
      using(var child = node.OpenSubKey(childname)) 
       action(child,childname); 
    }; 

    Action<RegistryKey, Func<RegistryKey, bool>> visitDescendants = null; 
    visitDescendants = (regkey, isDone) => { 
     if(!isDone(regkey)) 
      processKids(regkey, (subkey, subkeyname)=>visitDescendants(subkey,isDone)); 
    }; 

    processKids(ndpKey, (versionKey, versionKeyName) => { 
     if(Regex.IsMatch(versionKeyName,@"^v\d")) { 
      visitDescendants(versionKey, key => { 
       bool isInstallationNode = Equals(key.GetValue("Install"), 1) && key.GetValue("Version") != null; 
       if(isInstallationNode) 
        versionList.Add(
         key.Name.Substring(ndpKey.Name.Length+1) 
         + (key.GetValue("SP")!=null ? ", service pack "+ key.GetValue("SP"):"") 
         + " ("+key.GetValue("Version") +") " 
        ); 
       return isInstallationNode; 
      }); 
     } 
    }); 
} 

versionList dann enthält:

v2.0.50727, service pack 2 (2.0.50727.4927) 
v3.0, service pack 2 (3.0.30729.4926) 
v3.5, service pack 1 (3.5.30729.4926) 
v4\Client (4.0.30319) 
v4\Full (4.0.30319) 
+0

Danke, ich wusste nicht über diesen Registrierungsschlüssel - dachte, ich musste zu HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP gehen. Ich denke, das könnte den Trick machen. – AngryHacker

+0

Sorry, das hat nicht wirklich funktioniert. Software/Microsoft/.NETFramework listet v3.5 nicht auf – AngryHacker

+0

Behoben - ich verwende jetzt den NDP-Registrierungsschlüssel. –

3

Erwarten Sie, wir können Ihnen die Zukunft vorhersagen? :) Warum brauchst du das überhaupt? Ich meine, wenn Sie eine App für v4 schreiben, welchen Unterschied macht es, wenn v5 installiert ist oder nicht? Sie können in der app.config angeben, welche Versionen Sie unterstützen, aber Sie können nicht im Voraus wissen, was die nächste Version sein wird, oder selbst wenn Ihre App darauf ausgeführt wird. Immer wenn ein neues Framework herauskommt, müssen Sie Ihre App testen und entscheiden, ob Sie migrieren möchten oder nicht. Wenn Sie migrieren, nehmen Sie Änderungen an der app.config und möglicherweise auch am Code vor und geben eine neue Version frei. Wenn Sie dies nicht tun, müssen Sie immer noch eine ältere Framework-Version installieren. Es ist nicht so, dass v5 herauskommt und die Leute werden anfangen, alle vorherigen Frameworks zu deinstallieren. Ich habe immer noch v1.1 und v2 auf meiner Maschine und ich denke, dass sie für eine Weile bleiben werden.

+0

Das ist nicht der Punkt - die Daten nicht durch meine Anwendung verwendet wird. Da meine App jedoch von einer großen Anzahl von Personen in meiner Organisation verwendet wird, entscheiden die Verantwortlichen, meine Anwendung als Möglichkeit zu verwenden, Informationen über die Fähigkeiten der Benutzercomputer zu sammeln (z. B. CPU, RAM, HD-Speicherplatz usw.). ..), einschließlich des .NET-Frameworks. Es scheint, als ob ich diese Routine jedes Jahr neu schreiben muss, weil sich der Erkennungsmechanismus ändert. Ich möchte das in die Vergangenheit bringen und etwas haben, das vorwärts geht. – AngryHacker

3

Ich bin im Einvernehmen mit fejesjoco. Warum möchten Sie sogar eine zukünftige Version erkennen, für die Ihr Code nicht kompiliert wurde?

Wenn Sie in den Framework-Ordner (C: \ Windows \ Microsoft.NET \ Framework) schauen, werden Sie sehen, dass alle vorherigen Versionen des Frameworks zusammen mit der neuesten Version installiert werden. Wenn Ihr Code gegen 4.0 und 5.0 kompiliert wird, wird es noch einen Ordner für 4.0 haben.

Wenn Sie uns ein bisschen mehr Kontext geben könnten, warum Sie zukünftige Versionen erkennen, wollen wir in der Lage sein, besser zu helfen.

+0

Siehe den Kontext in meinem Kommentar für die Antwort von @ fejesjoco. – AngryHacker

+0

OK, das macht ein bisschen mehr Sinn. Warum durchlaufen Sie nicht den Registrierungsschlüssel unter dem entsprechenden .Net-Ordner, um die installierten Versionen des Frameworks abzurufen? HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ .NETFramework \ [v2.0 | v3.0 | v4.0.30319]. Ich würde vermuten, dass die nächste Version des Frameworks wird v4.5 oder v5.0 sollte einfach genug zu tun, was denkst du? – Burt

0

Fügen Sie ein Auto-Update-Funktion bei der Erkennung-Tool?