2011-01-29 10 views

risposta

27

Update: Per il codice che rileva correttamente di Windows 8.1 e Windows 10 , vedi this answer.

Il codice sotto funziona ancora bene per le vecchie versioni di Windows, ma segnalerà nulla più recente di Windows 8 come Windows 8.

Il "numero di bit" codice di test mostrato in basso (per vedere se il sistema operativo è a 32-bit o 64-bit funziona ancora, anche su Windows 10.

il seguente codice restituirà un valore stringa che indica la versione corrente di Windows. in pratica, tutto ciò che sta facendo sta ottenendo i numeri di versione del sistema da Windows utilizzando GetVersionEx API function e quindi confrontandoli con le versioni note di Windows.

(notare che alcune cose non vengono rilevate perfettamente. Ad esempio, una versione a 64 bit di Windows XP verrebbe probabilmente segnalata come Server 2003. Il codice per determinare se l'utente esegue Windows Vista o Server 2008, ad esempio, non è stato ancora scritto. Ma si può prendere questo e modificarlo, se lo desideri.)

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 

Inoltre, se non avete bisogno di indirizzare le prime versioni di Windows, è possibile ottenere ulteriori informazioni facendo passare il OSVERSIONINFOEX structure invece. Ho appena scritto quel codice in C++ e la documentazione è sorprendentemente facile da seguire.


Determinare se il sistema operativo host è a 32-bit o 64-bit da un VB 6 eseguibile è un po 'più complicato. Il motivo è che VB 6 non può compilare applicazioni a 64 bit. Tutto ciò che scrivi in ​​VB 6 verrà eseguito come un'applicazione a 32 bit. E le applicazioni a 32 bit vengono eseguite su versioni a 64 bit di Windows nel sottosistema Windows-on-Windows (WOW64). Riporteranno sempre la versione corrente di Windows come 32-bit, perché è quello che vedono.

Siamo in grado di aggirare questo presupponendo inizialmente che il sistema operativo host sia a 32 bit e che tenti di dimostrare questo errore. Ecco alcuni esempi di codice:

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) mi riceve un errore in VB2010Espress: la variabile 'osv' viene utilizzata prima che sia stata assegnata ale .... –

+0

@RemusRigo: ** Sì, certo! ** Questo codice è per * VB 6 *, la vecchia versione aggiornata l'ultima volta intorno al 1998. Ogni versione di Visual Basic dal 2002 (chiamata VB 7) ha stato basato su .NET Framework e originariamente era chiamato VB.NET. Da allora hanno abbandonato la parte ".NET" perché tutti sono completamente dimenticati di VB 6. Non è nemmeno più supportato da Microsoft perché ha quasi 15 anni. VB 6 e VB.NET sono * totalmente * diversi, e il codice che funziona in uno ** non funzionerà ** nell'altro. È necessario scrivere codice .NET. Stai guardando le domande con il tag sbagliato. –

+0

Sono nuovo a VB/VB.NET, puoi dirmi come correggere l'errore? –

0

Ah, l'ho trovato! Io personalmente non uso questa classe perché per i miei bisogni è eccessivo, ma è sicuramente l'esempio di versione OpSys più completo che abbia mai incontrato. Il merito per questo va a Kenneth Ives.

* Immagino che StackOverflow non ami enormi blocchi di codice, quindi la classe (clsOperSystem.cls) si trova nello KiCrypt Demo, un'eccellente raccolta di algoritmi di hash e di crittografia.

2

Si potrebbe provare a utilizzare Microsoft Sysinfo control che viene fornito con VB6 e verificare la presenza di OSPlatform, OSBuild e propertys OSVersion da abbinare con il corretto OS Version #

4

C'è anche il 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 

Si può fare qualcosa di simile ai casi dichiarazioni fornite da Cody Grey sopra per analizzare il valore Version, o analizzare la pianura valore di testo Caption, che ha elenchi come Microsoft(R) Windows(R) Server 2003, Standard Edition e Microsoft Windows 7 Professional.

1

La risposta accettata ha funzionato per la mia applicazione fino a quando non l'ho provato su Windows 10. Anche dopo aver aggiornato il codice per i dettagli sul numero di versione as listed here, è stata segnalata la versione errata di Windows. Questo perché:

Le applicazioni non manifestate per Windows 8.1 o Windows 10 restituiranno il valore della versione del sistema operativo Windows 8 (6.2). Una volta che un'applicazione viene manifestata per una determinata versione del sistema operativo, GetVersionEx restituirà sempre la versione per la quale l'applicazione è manifestata nelle versioni future. Per manifestare le applicazioni per Windows 8.1 o Windows 10, fare riferimento a Targeting your application for Windows.

Quindi, al fine di ottenere la versione corretta di Windows di presentarsi, equivale ad aggiungere una sezione del manifesto dell'applicazione:

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

E poi l'API GetVersionInfo funziona come previsto. Questa sezione manifest era nuova a partire da Windows 7, credo.

Tuttavia, un avvertimento molto importante è che è necessario aver effettivamente testato l'applicazione su ogni versione del sistema operativo che viene elencata come compatibile con. Queste impostazioni influiscono su alcune funzioni di Windows, non solo sul modo in cui vengono riportate le informazioni sulla versione di Windows.

+0

Bello, per maggiori informazioni vedi il link aggiornato di Cody Gray in alto.Sebbene la prima risposta qui sia adatta ai miei scopi, non mi interessa della versione W10 (anche se in esecuzione): P, –

1

Ecco un metodo molto semplice che uso per determinare 32 vs. sistema operativo a 64 bit:

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

Nel 64-bit di Windows, il sistema operativo imposta i "PROGRAMFILES (X86)" variabile d'ambiente, ma doesn 't su sistemi a 32 bit. Non mi ha ancora fallito ...

0

funzionare su Windows 10 VB6 - non funziona in modalità debug-lavoro solo su runtime

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 

chiamata

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