20

我想检测从 95 到 Win 7 的任何 Windows 版本。

我还想显示操作系统是 32 位还是 64 位。

而已; 就这么简单。:) 我可以在 VB 6 应用程序中使用什么代码来执行此操作?

4

7 回答 7

29

更新:有关正确检测 Windows 8.1 和 Windows 10 的代码,请参阅此答案

下面的代码仍然适用于旧版本的 Windows,但它会将比 Windows 8 更新的任何东西报告为 Windows 8。

底部显示的“位”测试代码(查看操作系统是 32 位还是 64 位仍然有效,即使在 Windows 10 上也是如此。

以下代码将返回一个字符串值,指示当前的 Windows 版本。基本上,它所做的只是使用GetVersionExAPI 函数从 Windows 获取系统版本号,然后将它们与已知的 Windows 版本进行匹配。

(请注意,有些事情没有被完美地检测到。例如,Windows XP 的 64 位版本可能会报告为 Server 2003。例如,用于确定用户运行的是 Windows Vista 还是 Server 2008 的代码也没有被检测到。写的。但您可以根据需要对其进行调整。)

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

此外,如果您不需要针对最早版本的 Windows,则可以通过传递OSVERSIONINFOEX结构来获取更多信息。我刚刚用 C++ 编写了该代码,并且文档非常容易理解。


从 VB 6 可执行文件中确定主机操作系统是 32 位还是 64 位有点棘手。原因是因为 VB 6 不能编译 64 位应用程序。您在 VB 6 中编写的所有内容都将作为 32 位应用程序运行。32 位应用程序在 Windows-on-Windows (WOW64) 子系统中的 64 位版本的 Windows 上运行。他们将始终将当前版本的 Windows 报告为 32 位,因为这就是他们所看到的。

我们可以通过最初假设主机操作系统是 32 位来解决这个问题,并尝试证明这是错误的。这是一些示例代码:

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
于 2011-01-30T11:26:49.730 回答
4

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

您可以执行与上面 Cody Gray 提供的 case 语句类似的操作来解析该Version值,或解析纯文本Caption值,其中包含 和 之类的Microsoft(R) Windows(R) Server 2003, Standard Edition列表Microsoft Windows 7 Professional

于 2013-10-29T15:28:16.440 回答
2

您可以尝试使用 VB6 附带的 Microsoft Sysinfo 控件并检查 OSPlatform、OSBuild 和 OSVersion 属性以匹配正确的OS 版本#

于 2011-01-29T21:53:02.917 回答
1

接受的答案适用于我的应用程序,直到我在 Windows 10 上尝试。即使在更新了此处列出的版本号详细信息的代码后,它仍报告错误的 Windows 版本。原来这是因为:

未针对 Windows 8.1 或 Windows 10 显示的应用程序将返回 Windows 8 操作系统版本值 (6.2)。一旦针对给定的操作系统版本显示应用程序,GetVersionEx 将始终返回应用程序在未来版本中显示的版本。要为 Windows 8.1 或 Windows 10 显示您的应用程序,请参阅为 Windows 定位您的应用程序

因此,为了显示正确的 Windows 版本,这相当于在应用程序清单中添加一个部分:

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

然后 GetVersionInfo API 按预期工作。我相信这个清单部分是 Windows 7 的新内容。

但是,一个非常重要的警告是,您必须在您列出的每个操作系统版本上实际测试过您的应用程序,并将其列为兼容。这些设置会影响某些 Windows 功能,而不仅仅是报告 Windows 版本信息的方式。

于 2016-04-21T18:27:52.467 回答
1

这是我用来确定 32 位和 64 位操作系统的一个非常简单的方法:

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

在 64 位 Windows 中,操作系统设置环境变量“PROGRAMFILES(X86)”,但在 32 位系统上没有。它还没有让我失望...

于 2016-10-02T11:54:11.777 回答
0

啊,找到了!我个人不使用这个类,因为对于我的需要它是矫枉过正的,但它绝对是我遇到的最彻底的 OpSys 版本示例。这要归功于肯尼斯·艾夫斯。

*我猜 StackOverflow 不喜欢巨大的代码块,所以类 (clsOperSystem.cls) 位于KiCrypt Demo中,它是哈希和加密算法的优秀汇编。

于 2011-01-29T21:37:31.527 回答
0

在 WINDOWS 10 VB6 上工作 -在调试模式下不工作-仅在运行时工作

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

称呼

Dim lpVersionInformation As RTL_OSVERSIONINFOEX
lpVersionInformation.dwOSVersionInfoSize = Len(lpVersionInformation)
RtlGetVersion(lpVersionInformation)
于 2017-07-07T15:43:41.387 回答