Windows 11, lanzado ayer, se informa a sí mismo como Windows 10.0 en casi todas partes: RtlGetVersion dice 10.0, y si le pregunta a VerifyVersionInfo si tiene 11.0 o superior, dice que no.
Parece que no hay un nuevo GUID para insertar en app.manifest para decir "hey, soy compatible con Windows 11" como lo hubo para Windows 7, 8, 8.1 y 10.
Actualmente confío en HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName para decirme cuál es la versión actual de Windows, pero en mi máquina que actualicé, todavía dice "Windows 10 Enterprise", no "Windows 11 Empresa".
Parece que solo hay un lugar en el registro que contiene el texto "Windows 11" y esa es la sección BCD (configuración de arranque), que también se puede cambiar de nombre, así que no quiero tocar eso.
Hasta ahora solo he identificado un puñado de métodos para saber si estoy ejecutando Windows 11:
Invoque WMI para consultar Win32_OperatingSystem y verifique la propiedad Nombre, que simplemente dice "Windows 11". Esto está incompleto (no incluye el SKU como "Enterprise") y WMI es relativamente lento y un poco frágil, por lo que no es una solución aceptable para mi caso de uso.
Verifique el número de compilación para ver si está por encima de 21996 (compilaciones beta) o 22000 (primer lanzamiento público). Como se mencionó anteriormente, esto no incluirá el SKU, y requeriría algunos trucos manuales para construir la cadena completa.
Ejecute sysinfo y analice la salida. Esto es bastante lento y posiblemente frágil (no lo he comprobado, pero la salida puede estar localizada en diferentes idiomas).
winver sabe, pero es una aplicación GUI, por lo que no puedo consultarla exactamente mediante programación.
¿Alguien tiene alguna otra idea sobre cómo sacar la cadena "Windows 11 Enterprise" (o "Windows 11 Pro", etc., según sea el caso) de mi sistema operativo de manera eficiente y completa? ¿De dónde lo obtienen WMI, sysinfo y winver?
Necesito hacer esto desde una biblioteca .NET, pero las llamadas a funciones nativas/P/Invokes son soluciones aceptables.
Dejo esto aquí para que pueda encontrarlo más tarde:
Parece que Windows mismo (por ejemplo, winver) obtiene esta información de la marca de Windows, específicamente de la tabla de recursos en %WinDir%\Branding\Basebrd\en-US\basebrd.dll.mui .
Para acceder a este, se pueden usar las API privadas en %WinDir%\System32\winbrand.dll . Específicamente, la función BrandingFormatString que acepta una cadena ancha (LPW[C]STR) y devuelve una cadena ancha.
por ejemplo BrandingFormatString("%WINDOWS_LONG%") devuelve "Windows 11 Pro" en la PC de mi casa.
No conozco la semántica del ciclo de vida de la cadena resultante, es decir, si/cuándo/cómo debe liberarse.
El siguiente código sirve como prueba de concepto funcional (C# 9.0):
using System; using System.Runtime.InteropServices; [DllImport("winbrand.dll", CharSet = CharSet.Unicode)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] static extern string BrandingFormatString(string format); Console.WriteLine(BrandingFormatString("Hello World from %WINDOWS_LONG%!"));tldr: el uso de EditionID y CurrentBuild de CurrentVersion en el registro parece ser una forma confiable de determinar Win10 vs Win11 y la "edición" del software. EditionID es "Profesional" en Windows 10 Pro y Windows 11 Pro, y CurrentBuild >= ~22000 le dice si es 10 u 11.
La colección de valores de registro en HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion revela lo que parece una falta de planificación por parte de Microsoft. Existe ReleaseId , que es un número que cambió con cada versión de Windows 10 (por ejemplo, 1903 , 1909 , 2004 ,...) hasta su último cambio para Windows 10 20H2, donde cambió a 2009 . Al mismo tiempo, se agregó DisplayVersion y se configuró en 20H2 .
Luego se lanzó Windows 10 21H1, y ReleaseId inexplicablemente permaneció en 2009 .
El hecho de que las versiones actuales de Windows 10 y Windows 11 puedan tener la misma DisplayVersion (por ejemplo, 21H2 cuando Windows 10 21H2 se lance pronto) y ProductName (por ejemplo, Windows 10 Pro ) es realmente desconcertante. (Gracias @yaakov por darse cuenta de mi error al decir que era 21H1).
Creé una herramienta de soporte remoto para administradores de escritorio (ver http://www.appslife-rdt.appspot.com ) En VB.Dot.Net usé una llamada al espacio WMI Win32_OperatingSystem y obtuve el valor "Nombre". Luego, esto debe dividirse para obtener el primer objeto que es lo que necesita. es decir
Dim query2 As New SelectQuery("SELECT * FROM Win32_OperatingSystem") Dim searcher2 As New ManagementObjectSearcher(objManagementScope2, query2, QueryOptions) For Each mo As ManagementObject In searcher2.[Get]() OSname = mo("Name") Next Dim array1 As Array = Nothing array1 = Split(OSname, "|") OSname = array1(0).ToStringOSname luego le brinda el "Windows 11 Pro" o "Windows XP Professional" que necesita.
También obtengo OSVersion con la información de actualización de parche más reciente del registro de la siguiente manera si es necesario...
ESTO ES PARA LAS VERSIONES DEL CLIENTE 10/11 :-
.SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Client.OS.rs2.amd64") .SetPropertyValue("sValueName", "Versión")
ESTO ES PARA VERSIONES DE SERVIDOR 2019 :-
.SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Server.OS.amd64") .SetPropertyValue("sValueName", "Versión")
Espero que esto sea de ayuda.