如何从 VB 6 应用程序确定 Windows 版本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4839210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:01:21  来源:igfitidea点击:

How can I determine the Windows version from a VB 6 app?

windowsvb632bit-64bitwindowsversion

提问by SOF User

I want to detect any Windows versions from 95 to Win 7.

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

I also would like to display if the OS is 32-bit or 64-bit.

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

That's it; it's that simple. :) What code could I use to do this from within a VB 6 application?

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

回答by Cody Gray

Update:For code that correctly detects Windows 8.1 and Windows 10, see this answer.

The code below still works fine for older versions of Windows, but it will report anything newer than Windows 8 as being Windows 8.

The "bitness" testing code shown at the bottom (to see if the OS is 32-bit or 64-bit still works, even on Windows 10.

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

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

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

The following code will return a string value indicating the current version of Windows. Basically, all it's doing is getting the system version numbers from Windows using the GetVersionExAPI function, and then matching those up to the known versions of Windows.

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

(Note that some things are not detected perfectly. For example, a 64-bit version of Windows XP would likely be reported as Server 2003. Code to determine whether the user is running Windows Vista or Server 2008, for example, has also not been written. But you can take this and tweak it as desired.)

(请注意,有些东西没有被完美地检测到。例如,64 位版本的 Windows XP 可能会被报告为 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

Additionally, if you don't need to target the earliest versions of Windows, you can get more information by passing the OSVERSIONINFOEXstructureinstead. I just wrote that code in C++, and the documentation is surprisingly easy to follow.

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



Determining if the host OS is 32-bit or 64-bit from a VB 6 executable is a little trickier. The reason is because VB 6 can't compile 64-bit applications. Everything you write in VB 6 will run as a 32-bit application. And 32-bit applications run on 64-bit versions of Windows in the Windows-on-Windows (WOW64) subsystem. They will always report the current version of Windows as 32-bit, because that's what they see.

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

We can work around this by initially assuming that the host OS is 32-bit, and attempting to prove this wrong. Here's some sample code:

我们可以通过最初假设主机操作系统是 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

回答by Joe M

There's also the WMI Tasks for Operating Systems.

还有操作系统WMI 任务

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

You can do something similar to the case statements provided by Cody Gray above to parse the Versionvalue, or parse the plain text Captionvalue, which has listings like Microsoft(R) Windows(R) Server 2003, Standard Editionand Microsoft Windows 7 Professional.

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

回答by Mark Hall

You could try using the Microsoft Sysinfo controlthat comes with VB6 and check for OSPlatform, OSBuild and OSVersion propertys to match with the proper OS Version #

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

回答by UuDdLrLrSs

The accepted answer worked for my application until I tried it on Windows 10. Even after updating the code for version number details as listed hereit reported the wrong Windows version. It turns out this is because:

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

Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). Once an application is manifested for a given operating system version, GetVersionEx will always return the version that the application is manifested for in future releases. To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.

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

So in order to get the correct Windows version to show up, it amounts to adding a section the application manifest:

因此,为了显示正确的 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>

And then the GetVersionInfo API works as expected. This manifest section was new as of Windows 7, I believe.

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

However, a very important caveat is that you must actually have tested your application on each operating system version that you list it as being compatible with. These settings affect certain Windows functions, not only the way Windows version information is reported.

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

回答by MountainMan

Here is a very simple method I use to determine 32 vs. 64 bit operating system:

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

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

In 64-bit Windows, the OS sets the environment variable "PROGRAMFILES(X86)" but it doesn't on 32-bit systems. It hasn't failed me yet...

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

回答by zone zone

WORK on WINDOWS 10VB6 - not work in debug mode- work only on runtime

在 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

call

称呼

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

回答by Joe Jordan

Ah, found it! I don't personally use this class because for my needs it's overkill, but it's definitely the most thorough OpSys version example I've come across. Credit for this one goes to Kenneth Ives.

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

*I guess StackOverflow doesn't like enormous blocks of code, so the class (clsOperSystem.cls) is located in the KiCrypt Demo, an excellent compilation of hash and encryption algorithms.

*我猜 StackOverflow 不喜欢大量的代码块,所以类 (clsOperSystem.cls) 位于KiCrypt Demo 中,这是一个出色的散列和加密算法编译。