2011-01-29 13 views

Respuesta

27

Actualización: Para código que detecta correctamente en Windows 8.1 y Windows 10 , ver this answer.

El código de abajo todavía funciona bien para las versiones anteriores de Windows, pero va a reportar nada más nuevo que Windows 8 como Windows 8.

El "valor de bits" código de prueba se muestra en la parte inferior (para ver si el sistema operativo es 32 bits o 64 bits todavía funciona, incluso en Windows 10.

El siguiente código devolverá un valor de cadena que indica la versión actual de Windows. Básicamente, todo lo que hace es obtener los números de versión del sistema de Windows usando el GetVersionEx API function, y luego haciendo coincidir esas hasta las versiones conocidas de Windows.

(Tenga en cuenta que algunas cosas no se detectan perfectamente. Por ejemplo, una versión de 64 bits de Windows XP probablemente se informará como Server 2003. El código para determinar si el usuario ejecuta Windows Vista o Server 2008, por ejemplo, tampoco se ha escrito. Pero puede tomar esto y ajustar como se desee.)

Option Explicit 

Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _ 
    (lpVersionInformation As OSVERSIONINFO) As Long 

Private Type OSVERSIONINFO 
    OSVSize   As Long 
    dwVerMajor  As Long 
    dwVerMinor  As Long 
    dwBuildNumber As Long 
    PlatformID  As Long 
    szCSDVersion As String * 128 
End Type 

Private Const VER_PLATFORM_WIN32s = 0 
Private Const VER_PLATFORM_WIN32_WINDOWS = 1 
Private Const VER_PLATFORM_WIN32_NT = 2 

' Returns the version of Windows that the user is running 
Public Function GetWindowsVersion() As String 
    Dim osv As OSVERSIONINFO 
    osv.OSVSize = Len(osv) 

    If GetVersionEx(osv) = 1 Then 
     Select Case osv.PlatformID 
      Case VER_PLATFORM_WIN32s 
       GetWindowsVersion = "Win32s on Windows 3.1" 
      Case VER_PLATFORM_WIN32_NT 
       GetWindowsVersion = "Windows NT" 

       Select Case osv.dwVerMajor 
        Case 3 
         GetWindowsVersion = "Windows NT 3.5" 
        Case 4 
         GetWindowsVersion = "Windows NT 4.0" 
        Case 5 
         Select Case osv.dwVerMinor 
          Case 0 
           GetWindowsVersion = "Windows 2000" 
          Case 1 
           GetWindowsVersion = "Windows XP" 
          Case 2 
           GetWindowsVersion = "Windows Server 2003" 
         End Select 
        Case 6 
         Select Case osv.dwVerMinor 
          Case 0 
           GetWindowsVersion = "Windows Vista/Server 2008" 
          Case 1 
           GetWindowsVersion = "Windows 7/Server 2008 R2" 
          Case 2 
           GetWindowsVersion = "Windows 8/Server 2012" 
          Case 3 
           GetWindowsVersion = "Windows 8.1/Server 2012 R2" 
         End Select 
       End Select 

      Case VER_PLATFORM_WIN32_WINDOWS: 
       Select Case osv.dwVerMinor 
        Case 0 
         GetWindowsVersion = "Windows 95" 
        Case 90 
         GetWindowsVersion = "Windows Me" 
        Case Else 
         GetWindowsVersion = "Windows 98" 
       End Select 
     End Select 
    Else 
     GetWindowsVersion = "Unable to identify your version of Windows." 
    End If 
End Function 

Además, si no es necesario dirigirse a las primeras versiones de Windows, puede obtener más información al pasar el OSVERSIONINFOEX structure lugar. Acabo de escribir ese código en C++, y la documentación es sorprendentemente fácil de seguir.


La determinación de si el sistema operativo anfitrión es de 32 bits o de 64 bits de un ejecutable VB 6 es un poco más difícil. La razón es porque VB 6 no puede compilar aplicaciones de 64 bits. Todo lo que escriba en VB 6 se ejecutará como una aplicación de 32 bits. Y las aplicaciones de 32 bits se ejecutan en versiones de 64 bits de Windows en el subsistema Windows-on-Windows (WOW64). Siempre informarán que la versión actual de Windows es de 32 bits, porque eso es lo que ven.

Podemos solucionar esto suponiendo inicialmente que el sistema operativo host es de 32 bits e intentamos probarlo de forma incorrecta. Aquí hay un código de muestra:

Private Declare Function GetProcAddress Lib "kernel32" _ 
    (ByVal hModule As Long, ByVal lpProcName As String) As Long 

Private Declare Function GetModuleHandle Lib "kernel32" _ 
    Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long 

Private Declare Function GetCurrentProcess Lib "kernel32"() As Long 

Private Declare Function IsWow64Process Lib "kernel32" _ 
    (ByVal hProc As Long, ByRef bWow64Process As Boolean) As Long 

Public Function IsHost64Bit() As Boolean 
    Dim handle As Long 
    Dim is64Bit As Boolean 

    ' Assume initially that this is not a WOW64 process 
    is64Bit = False 

    ' Then try to prove that wrong by attempting to load the 
    ' IsWow64Process function dynamically 
    handle = GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process") 

    ' The function exists, so call it 
    If handle <> 0 Then 
     IsWow64Process GetCurrentProcess(), is64Bit 
    End If 

    ' Return the value 
    IsHost64Bit = is64Bit 
End Function 
+0

osv.OSVSize = Len (osv) me da un error en VB2010Espress: La variable 'osv' se usa antes de que se le haya asignado alue .... –

+0

@RemusRigo: ** Sí, por supuesto! ** Este código es para * VB 6 *, la versión anterior fue actualizada por última vez alrededor de 1998. Cada versión de Visual Basic desde 2002 (llamada VB 7) tiene se ha basado en .NET Framework, e incluso originalmente se llamaba VB.NET. Desde entonces, han descartado la parte ".NET" porque todo el mundo se olvidó por completo de VB 6. Microsoft ya no lo admite porque tiene casi 15 años. VB 6 y VB.NET son * totalmente * diferentes, y el código que funciona en uno ** no funcionará ** en el otro. Necesita escribir el código .NET. Está viendo preguntas con la etiqueta incorrecta. –

+0

soy nuevo en VB/VB.NET, ¿me puede decir cómo solucionar el error? –

0

¡Ah, lo encontré! Personalmente no uso esta clase porque para mis necesidades es excesivo, pero definitivamente es el ejemplo más completo de la versión de OpSys que he encontrado. El crédito por este es para Kenneth Ives.

* Supongo que a StackOverflow no le gustan los bloques enormes de código, por lo que la clase (clsOperSystem.cls) se encuentra en el KiCrypt Demo, una excelente compilación de algoritmos hash y de encriptación.

2

Usted podría tratar de usar el Microsoft Sysinfo control que viene con VB6 y comprobar si hay OSPlatform, OSBuild y propertys OSVersion para que coincida con el buen OS Version #

4

También está el WMI Tasks for Operating Systems.

strComputer = "." 
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colOperatingSystems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem") 
For Each objOperatingSystem in colOperatingSystems 
    Wscript.Echo objOperatingSystem.Caption & " " & objOperatingSystem.Version 
Next 

Puede hacer algo similar a las declaraciones de casos proporcionados por Cody gris arriba para analizar el valor Version, o analizar el valor de texto sin formato Caption, que cuenta con un listado como Microsoft(R) Windows(R) Server 2003, Standard Edition y Microsoft Windows 7 Professional.

1

La respuesta aceptada funcionó para mi aplicación hasta que la probé en Windows 10. Incluso después de actualizar el código para los detalles del número de versión as listed here, informó una versión de Windows incorrecta. Resulta que esto es porque:

Las aplicaciones no manifestadas para Windows 8.1 o Windows 10 devolverán el valor de versión del SO Windows 8 (6.2). Una vez que se manifiesta una aplicación para una versión determinada del sistema operativo, GetVersionEx siempre devolverá la versión para la que se manifiesta la aplicación en futuras versiones. Para manifestar sus aplicaciones para Windows 8.1 o Windows 10, consulte Targeting your application for Windows.

Así que con el fin de obtener la versión correcta de Windows aparezca, equivale a la adición de una sección del manifiesto de aplicación:

<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> 

Y entonces funciona la API GetVersionInfo como se esperaba. Esta sección de manifiesto era nueva a partir de Windows 7, creo.

Sin embargo, una advertencia muy importante es que en realidad debe haber probado su aplicación en cada versión del sistema operativo que lo liste como compatible. Estas configuraciones afectan ciertas funciones de Windows, no solo la forma en que se informa la información de la versión de Windows.

+0

Agradable, para obtener más información, vea el enlace actualizado de arriba de Cody Gray.Aunque la primera respuesta aquí se ajusta a mis propósitos ya que no me importa la versión W10 (aunque la ejecute): P, –

1

Aquí es un método muy simple que utilizo para determinar 32 vs. sistema operativo de 64 bits:

OSBits = IIf(Len(Environ$("PROGRAMFILES(X86)")) > 0, 64, 32) 

En Windows de 64 bits, el sistema operativo establece los "PROGRAMFILES (X86)" variable de entorno, pero que doesn en sistemas de 32 bits. No me ha fallado aún ...

0

funcionar en Windows 10 VB6 - no funciona en modo de depuración - trabajo sólo en tiempo de ejecución

Private Declare Function RtlGetVersion Lib "ntdll" (ByRef lpVersionInformation As RTL_OSVERSIONINFOEX) As Long 

Private Type RTL_OSVERSIONINFOEX 
     dwOSVersionInfoSize As Long 
     dwMajorVersion As Long 
     dwMinorVersion As Long 
     dwBuildNumber As Long 
     dwPlatformId As Long 
     szCSDVersion As String * 128 
End Type 

llamada

Dim lpVersionInformation As RTL_OSVERSIONINFOEX 
lpVersionInformation.dwOSVersionInfoSize = Len(lpVersionInformation) 
RtlGetVersion(lpVersionInformation) 
Cuestiones relacionadas