2015-08-07 8 views
27

Ich bin für ein Mittel suchen, wenn app mein C# zu erkennen ist unter Windows 10.Wie kann ich erkennen, ob meine app unter Windows läuft 10

Ich hatte gehofft, dass Environment.OSVersion den Trick tun würde, aber das scheint eine Version von 6.3.9600.0 auf Windows 8.1 und Windows 10 zurückgeben.

Andere Lösungen wie this scheinen nicht zwischen Windows 8 und Windows 10 zu unterscheiden.

Irgendwelche Vorschläge?


Warum muss ich das tun?

Weil ich ein WinForms WebBrowser-Steuerelement verwende, um eine OAuth-Seite zu hosten, die abstürzt und in älteren IE-Versionen brennt (meine App verbindet sich mit einer user's Nest account ...).

Standardmäßig emuliert das WebBrowser-Steuerelement IE7. Mithilfe eines Registrierungsschlüssels können Sie festlegen, dass die neueste Version von IE, die auf dem Host-PC installiert ist, emuliert wird. Die value that worked bis zu Windows 8.1 (und Vorabversionen von Windows 10) funktioniert jedoch nicht in der endgültigen Version von Windows 10.

+5

Haben Sie [manifestieren die app] (https://msdn.microsoft.com/en-us/library/windows /desktop/dn481241%28v=vs.85%29.aspx) für Windows 10? – GSerg

+0

Führen Sie Ihr Programm im Kompatibilitätsmodus aus? – Graffito

+0

Es gibt andere Möglichkeit, diese Informationen zu erhalten, überprüfen Sie diesen Beitrag http://stackoverflow.com/questions/6331826/get-os-version-friendly-name-in-c-sharp – Rahul

Antwort

21

Wenn Sie bei Registrierung schauen Sie Umgebung Name gefunden:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName 

Zum Beispiel ist mein Produktname Windows 10 Home:

Registry

Mit diesem Code erhalten Sie, wenn es von Windows 10:

static bool IsWindows10() 
{ 
    var reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); 

    string productName = (string)reg.GetValue("ProductName"); 

    return productName.StartsWith("Windows 10"); 
} 

Hinweis: using Microsoft.Win32; zu Ihrem usings hinzufügen.

+1

Ich bin nicht sicher, dass Store-Apps auf die Registrierung zugreifen können ... – Rawling

+0

@Rawling - In meinem Szenario ist dies eine Old-Skool WinForms App, installiert über ClickOnce –

+4

@RichardEverett Messepunkt! Kinder in diesen Tagen und ihre "Apps", ich weiß nicht ... :) – Rawling

1

Haben Sie versucht, unten? [Sie müssen einen Verweis auf Microsoft.VisulaBasic dll hinzufügen]

new Microsoft.VisualBasic.Devices.ComputerInfo().OSFullName 

Auf meinem Rechner gibt es, Microsoft Windows 7 Ultimate

+1

Dies ist in Windows 10 abgeschrieben. – Claies

+0

@Claies, Keine Ahnung, aber das saugt dann :) – Rahul

+3

Auch ... Ich würde lieber vermeiden, eine VisualBasic-Referenz zu meinem C# -Projekt hinzufügen. –

14

Unter der Haube verwendet die GetVersionEx function, die veraltet ist. Die Dokumentation warnt vor dem von Ihnen beobachteten Verhalten:

Anwendungen, die nicht für Windows 8.1 oder Windows 10 verfügbar sind, geben den Windows 8-Betriebssystemversionswert (6.2) zurück.

Die Dokumentation geht weiter zu empfehlen:

das aktuelle Betriebssystem zu identifizieren, ist in der Regel nicht der beste Weg, um zu bestimmen, ob eine bestimmte Betriebssystem-Funktion vorhanden ist. Dies liegt daran, dass dem Betriebssystem möglicherweise neue Funktionen in einer weitervertreibbaren DLL hinzugefügt wurden. Anstatt GetVersionEx zu verwenden, um die Betriebssystemplattform oder die Versionsnummer zu ermitteln, müssen Sie das Vorhandensein des Features selbst testen.

Wenn die oben genannte Empfehlung nicht geeignet für Ihren Fall ist, und Sie wirklich wollen, die tatsächliche Lauf OS-Version überprüfen, dann die Dokumentation enthält auch einen Hinweis dazu:

das aktuelle System vergleichen Version auf eine erforderliche Version, verwenden Sie die VerifyVersionInfo Funktion anstelle von GetVersionEx, um den Vergleich selbst durchzuführen.

Der folgende Artikel hat eine Arbeitslösung geschrieben mit der VerifyVersionInfo Funktion: Version Helper API for .NET.

geben volle Anerkennung an den Autor dieses Artikels, das folgende Codefragment das Verhalten liefern sollten Sie suchen:

public class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine(IsWindowsVersionOrGreater(6, 3, 0)); // Plug in appropriate values. 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct OsVersionInfoEx 
    { 
     public uint OSVersionInfoSize; 
     public uint MajorVersion; 
     public uint MinorVersion; 
     public uint BuildNumber; 
     public uint PlatformId; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
     public string CSDVersion; 
     public ushort ServicePackMajor; 
     public ushort ServicePackMinor; 
     public ushort SuiteMask; 
     public byte ProductType; 
     public byte Reserved; 
    } 

    [DllImport("kernel32.dll")] 
    static extern ulong VerSetConditionMask(ulong dwlConditionMask, 
     uint dwTypeBitMask, byte dwConditionMask); 
    [DllImport("kernel32.dll")] 
    static extern bool VerifyVersionInfo(
     [In] ref OsVersionInfoEx lpVersionInfo, 
     uint dwTypeMask, ulong dwlConditionMask); 

    static bool IsWindowsVersionOrGreater(
     uint majorVersion, uint minorVersion, ushort servicePackMajor) 
    { 
     OsVersionInfoEx osvi = new OsVersionInfoEx(); 
     osvi.OSVersionInfoSize = (uint)Marshal.SizeOf(osvi); 
     osvi.MajorVersion = majorVersion; 
     osvi.MinorVersion = minorVersion; 
     osvi.ServicePackMajor = servicePackMajor; 
     // These constants initialized with corresponding definitions in 
     // winnt.h (part of Windows SDK) 
     const uint VER_MINORVERSION = 0x0000001; 
     const uint VER_MAJORVERSION = 0x0000002; 
     const uint VER_SERVICEPACKMAJOR = 0x0000020; 
     const byte VER_GREATER_EQUAL = 3; 
     ulong versionOrGreaterMask = VerSetConditionMask(
      VerSetConditionMask(
       VerSetConditionMask(
        0, VER_MAJORVERSION, VER_GREATER_EQUAL), 
       VER_MINORVERSION, VER_GREATER_EQUAL), 
      VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 
     uint versionOrGreaterTypeMask = VER_MAJORVERSION | 
      VER_MINORVERSION | VER_SERVICEPACKMAJOR; 
     return VerifyVersionInfo(ref osvi, versionOrGreaterTypeMask, 
      versionOrGreaterMask); 
    } 
} 

Haftungsausschluss: Ich habe keine 10 Fenster noch, so dass ich haven‘ t getestet, um den Code auf Windows 10.

+3

Von MSDN: "In Windows 10 wurde die VerifyVersionInfo-Funktion ebenfalls veraltet. Sie können die veralteten Funktionen dennoch aufrufen, wenn Ihre Anwendung dies tut Wenn Sie Windows 8.1 oder Windows 10 nicht gezielt verwenden, erhalten Sie die Windows 8-Version (6.2.0.0). " –

+0

https://msdn.microsoft.com/en-ca/library/windows/desktop/dn481241(v=vs.85) .aspx –

+0

Nicht funktioniert, immer noch 6,2 für Win10 zurück! "Windows 10: VerifyVersionInfo gibt false zurück, wenn es aufgerufen wird ...." –

18

Antwort

Verwenden Environment.OSVersion und eine Anwendung-Manifest-Datei mit den entsprechendenhinzufügenElemente unkommentiert.

z.B. fügen Sie diese unter < asmv1: Montage >

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application> 
     <!-- Windows 10 --> 
     <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> 
     <!-- Windows 8.1 --> 
     <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> 
     <!-- Windows Vista --> 
     <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
     <!-- Windows 7 --> 
     <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> 
     <!-- Windows 8 --> 
     <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> 
    </application> 
</compatibility> 

Grund

Ich mag die Antwort von @Mitat Koyuncu nicht, weil unnötig die Registrierung verwendet und wie in den Kommentaren verwendet unzuverlässig String-Parsing erwähnt.

Ich mag auch nicht die Antwort von @Sstan, weil es den Code von Drittanbietern verwendet und das Anwendungsmanifest sowieso benötigt.

Von MSDN:

Windows-10: VerifyVersionInfo gibt false zurück, wenn sie von Anwendungen aufgerufen, die eine Kompatibilität Manifest für Windows nicht 8.1 oder Windows 10, wenn die lpVersionInfo Parameter so eingestellt ist, dass es Gibt Windows 8.1 oder Windows 10 an, auch wenn die aktuelle Betriebssystemversion Windows 8.1 oder Windows 10 ist. Speziell VerifyVersionInfo hat das folgende Verhalten:

• Wenn die Anwendung kein Manifest enthält, verhält sich VerifyVersionInfo so, als wäre die Betriebssystemversion Windows 8 (6.2).

• Wenn die Anwendung über ein Manifest verfügt, das die GUID enthält, die Windows 8.1 entspricht, verhält sich VerifyVersionInfo so, als ob die Betriebssystemversion Windows 8.1 (6.3) ist.

• Wenn die Anwendung hat ein Manifest, das die GUID enthält, die auf Windows 10, VerifyVersionInfo verhält sich, als ob das Betriebssystem Version entspricht, ist Microsoft Windows 10 (10,0).

Der Grund ist, weil VerifyVersionInfo in Windows veraltet 10.

ich getestet habe auf Windows 10 und in der Tat Environment.OSVersion funktioniert genau wie erwartet, wenn die app.manifest die entsprechende GUID wie oben enthält. Das ist wahrscheinlich der Grund, warum sie es nicht von .Net Framework geändert oder veraltet haben.

+4

Dies ist der korrekte, offizielle Ansatz. Ich möchte andere darauf hinweisen, dass Sie beim Testen mit Ihrem 'app.manifest' sicherstellen müssen, dass es sich tatsächlich in Ihrem Ausgabeordner befindet. In der Debug-Konfiguration wurde meins nicht in 'bin/Debug' kopiert. Dachte, das 'app.manifest' funktionierte nicht, bis ich die Freigabe versuchte und ein wenig weiter grub. –

+0

Arbeitete für mich. Hat NT Version 6.2 gezeigt, bis ich das oben genannte zum app.manifest hinzufügte. –

4

Ich empfehle die Verwendung der Registrierung, um die gewünschten Werte zu finden. Microsoft hat die Art und Weise geändert, in der Windows 10 in der Registrierung aufgeführt ist, sodass der Code dafür angepasst werden muss. Hier

ist der Code, den ich verwendet, dass korrekt identifiziert Windows-10 als auch:

namespace Inspection 
{ 
    /// <summary> 
    /// Static class that adds convenient methods for getting information on the running computers basic hardware and os setup. 
    /// </summary> 
    public static class ComputerInfo 
    { 
     /// <summary> 
     ///  Returns the Windows major version number for this computer. 
     /// </summary> 
     public static uint WinMajorVersion 
     { 
      get 
      { 
       dynamic major; 
       // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
       // and will most likely (hopefully) be there for some time before MS decides to change this - again... 
       if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major)) 
       { 
        return (uint) major; 
       } 

       // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' 
       dynamic version; 
       if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) 
        return 0; 

       var versionParts = ((string) version).Split('.'); 
       if (versionParts.Length != 2) return 0; 
       uint majorAsUInt; 
       return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0; 
      } 
     } 

     /// <summary> 
     ///  Returns the Windows minor version number for this computer. 
     /// </summary> 
     public static uint WinMinorVersion 
     { 
      get 
      { 
       dynamic minor; 
       // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
       // and will most likely (hopefully) be there for some time before MS decides to change this - again... 
       if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", 
        out minor)) 
       { 
        return (uint) minor; 
       } 

       // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' 
       dynamic version; 
       if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) 
        return 0; 

       var versionParts = ((string) version).Split('.'); 
       if (versionParts.Length != 2) return 0; 
       uint minorAsUInt; 
       return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0; 
      } 
     } 

     /// <summary> 
     ///  Returns whether or not the current computer is a server or not. 
     /// </summary> 
     public static uint IsServer 
     { 
      get 
      { 
       dynamic installationType; 
       if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType", 
        out installationType)) 
       { 
        return (uint) (installationType.Equals("Client") ? 0 : 1); 
       } 

       return 0; 
      } 
     } 

     private static bool TryGetRegistryKey(string path, string key, out dynamic value) 
     { 
      value = null; 
      try 
      { 
       var rk = Registry.LocalMachine.OpenSubKey(path); 
       if (rk == null) return false; 
       value = rk.GetValue(key); 
       return value != null; 
      } 
      catch 
      { 
       return false; 
      } 
     } 
    } 
} 
+1

Schön! Das hat den Job für mich erledigt.Habe mich nicht um etwas anderes als die "CurrentMajorVersionNumber" gekümmert. Die App musste nur wissen, ob sie unter Win10 lief oder nicht. Wenn der Registrierungsschlüssel nicht existiert, weil es eine ältere Version ist, würde ich sagen, Mission erfüllt. – Nyerguds

Verwandte Themen