3

I have an old program written in VB6 which needs to run on 3 different platforms, including my laptop which is running Win7. I googled how to determine OS from VB6 and found some code which I slightly modified as follows:

Declare Function GetVersionExA Lib "kernel32" (lpVersionInformation As OSVERSIONINFO) As Integer

Public Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId 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 As Long = 2


Private Function GetOS() As String
    Dim osinfo As OSVERSIONINFO
    Dim retvalue As Integer
    Dim sOS as String

    osinfo.dwOSVersionInfoSize = 148
    osinfo.szCSDVersion = Space$(128)
    retvalue = GetVersionExA(osinfo)

    Select Case osinfo.dwMajorVersion
        Case 7
            sOS = "?"  'Win7?
        Case 6
            sOS = "Vista"
         Case 5
            sOS = "XP"
         Case 4
            sOS = "Win2000"
     End Select

     MsgBox (sOS)
     return sOS     

End Function

When I run this from my WIN7 laptop, osinfo.dwMajorVersion = 5, which suggests it is on an XP machine.

What's ocurring here? Can I determine if I am running Win7 using this method? What's the best way of getting the info I need?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
DeveloperM
  • 1,129
  • 7
  • 17
  • 30
  • I tried that but I am getting an error on: Case VER_PLATFORM_WIN32s. "Variable not Defined" – DeveloperM May 12 '11 at 15:45
  • Impossible. I copied and pasted the code *exactly* as shown in my answer to a new project in VB 6. I didn't get any compilation errors. Make sure that you copy *all* of the code. `VER_PLATFORM_WIN32s` is a constant defined at the top. – Cody Gray - on strike May 12 '11 at 15:46
  • @Cody I re-copied your code and this time it ran but I am still getting majorversion = 5. I have tried running the program both with and without compatibility set, restarting my pc each time I changed a compatibility setting. No luck. Do you have any suggestions on what else I can check? Thanks. – DeveloperM May 12 '11 at 18:11
  • Why do you need to check what OS is running? This is a bad sign. You should be aiming to have your app run the same way across all systems. – CJ7 Nov 26 '11 at 11:21

7 Answers7

8

Windows 7 is actually version 6.1, not version 7. You're checking for the wrong number. Otherwise, I'm not really sure why the code you've shown doesn't work. At least one problem is that there is no return keyword in VB 6. The last line in your GetOS function should be GetOS = sOS, instead. Once I fix those problems, it works just fine for me as well.

I have a full working solution available here. It detects all known versions of Windows quickly and accurately. I've personally tested this on at least 5 different versions of Windows with nary a hitch. All that you have to do is copy and paste the code into your project, and it just works.

Here's proof that it works correctly on my Windows 7 laptop:

     

I'm really not sure why everyone is working so hard to propose alternative, partially-working solutions. This one is guaranteed to work, or your money back. If it doesn't work for you, make sure that you are not running the application under "Windows XP Mode" or some other virtual machine.

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • Ok, I tried again. This time it ran but I am still getting a majorversion = 5. – DeveloperM May 12 '11 at 16:34
  • I also chanegd the "return" to the correct "GetOS = sOS". The other commentors here seem to be able to get he correct info but I am still coming up with majorversion=5. Any ideas? – DeveloperM May 12 '11 at 16:56
  • @Cody, do you have any suggestions? – DeveloperM May 12 '11 at 17:47
  • @DeveloperM: Ah, if you have Windows 7 Professional or Ultimate, you're very likely running the software in the [Windows XP Mode](http://en.wikipedia.org/wiki/Windows_Virtual_PC#Windows_XP_Mode). That would definitely make it appear to the application that it's actually running on Windows XP (version 5.1, to be more exact). You need to turn that off and run the app in full Windows 7 in order to get the right numbers. The code *does* work, so that's not the problem. It's something related to your configuration. – Cody Gray - on strike May 13 '11 at 02:49
  • Several programs that run fine in prod fail or cannot be stepped through under Win7, so a number of adjustments were made, e.g. in IIS and VS 2008. – DeveloperM May 13 '11 at 17:47
  • @DeveloperM: Erm, what? I'm sorry, I don't understand what your last comment is trying to say. Yes, Windows 7 is different from earlier versions. That sometimes means breaking changes. However, *this* code works fine on *any* version of Windows. I've tested it myself. I don't know how it works under Windows XP Mode, but you don't need to run it under XP Mode. If the *rest* of your app requires XP Mode, then you need to fix that part of your app. There's no way to detect that the host OS is Windows 7 if your app is running on an *emulated* version of XP. If it could, the emulation failed. – Cody Gray - on strike May 14 '11 at 04:24
  • @Cody: Thank you for all your help. I am not running in XP Mode. I am running Windows 7 Professional, SP 1. – DeveloperM May 16 '11 at 13:26
  • +1. Minor pedantic correction, there is a `Return` statement in VB6, but only for use with `Gosub ... Return` within one routine. It is not equivalent to the `Return` statement in VB.Net http://msdn.microsoft.com/en-us/library/aa243378(v=VS.60).aspx – MarkJ May 16 '11 at 14:52
  • @MarkJ: Hah! Really? I have honestly *never* used `Gosub` in VB 6. I think I maybe did when I was 6 and hacking in QBASIC. But I had no idea what I was doing. (By the way, any ideas why it seems I'm the only one that can get this code to work? It works *flawlessly* for me, but the OP seems to be having lots of undiagnosable trouble.) – Cody Gray - on strike May 16 '11 at 14:55
4

Windows 7 has version 6.1.7600 that's majorversion 6, minorversion 1, build 7600 in your code. The reason why you are seeing MajorVersion 5 is probably because of a compatibility setting. Right-click your .exe, select properties and look in the "compatibility" tab.

ZippyV
  • 12,540
  • 3
  • 37
  • 52
  • 1
    The compatibility mode is a good theory, but it doesn't bear fruit. My tests show that both `GetVersion` and `GetVersionEx` return the correct version of Windows, regardless of the compatibility settings applied to the application. – Cody Gray - on strike May 12 '11 at 15:40
  • @Cody: I just now tested it and found that setting the compatibility mode to XP did indeed change it. I had a getversion.exe sitting around that called that function. I am running Win 7 and it returns 6.1 for the version. I dropped a shortcut to it on my desktop, set compatibility to XP, and it printed 5.1. +1 – Mark Wilkins May 12 '11 at 15:46
  • @Cody You need to restart the application after changing the compatibility setting. – ZippyV May 12 '11 at 15:48
  • In fact, after creating the shortcut and then deleting it, it still shows v5.1 when run from a command prompt. I copy the .exe to somethingelse.exe and it prints v6.1. Odd. But (at least in my case), it definitely was affected by the compatibility setting ... sort of permanently. – Mark Wilkins May 12 '11 at 15:49
  • @ZippyV: Yes, obviously I did that. @Mark: Just tried it again using the VB 6 code that I linked to. It reports Windows 7 regardless of the app compat settings. I simply can't make it blink. You're either calling a different function, or something's getting handled differently in your test app. – Cody Gray - on strike May 12 '11 at 15:51
  • @Cody: That's odd. Maybe the VB environment changes it. My test code is a 10 line C program built from the command line (cl.exe). – Mark Wilkins May 12 '11 at 15:54
  • @Mark: It's not just VB, a .NET app I have around does the same thing. I can't imagine why C would be different, but I can't disprove it at the moment. :-) – Cody Gray - on strike May 12 '11 at 15:57
  • Thanks for all the help. I set compatability to Windows 7, restarted my computer but I am still getting majorversion 5. – DeveloperM May 12 '11 at 16:23
  • I found a silly error but correcting it didn't change my results: I had inadvertantly set compatability setting to Win 7 but I was supposed to set it to the OS where the program ran correctly, so I reset it to Windows 2000, restarted teh computer and re-ran. And I am STILL getting majorversion 5. – DeveloperM May 12 '11 at 17:09
  • 1
    Re Compatability: I found the following online: "If compatibility mode is in effect, the GetVersionEx function reports the operating system as it identifies itself, which may not be the operating system that is installed. For example, if compatibility mode is in effect, GetVersionEx reports the operating system that is selected for application compatibility." This can be found at http://msdn.microsoft.com/en-us/library/ms724451(VS.85).aspx – DeveloperM May 13 '11 at 15:53
3

I tried all the API calls and code but always ended up with Windows XP for some or other reason. Used this "hack" to solve my problem and it works for me.

Private Function GetMyWindowsVersion() As String    
Dim r As Long, bFile As Integer, verString As String, fResult As String, bracketStart As Integer, verInfo As String, bracketEnd As Integer, versionLength As Integer

fResult = "Windows OS"

bFile = FreeFile
Open App.Path & "\checkos.bat" For Output As #bFile    
    Print #bFile, "@echo off"    
    Print #bFile, "ver > version.txt"    
    Print #bFile, "exit"    
Close #bFile

r = Shell(App.Path & "\checkos.bat", vbMinimizedNoFocus)

bFile = FreeFile    
Open App.Path & "\version.txt" For Input As #bFile    
    Do Until EOF(bFile)    
        Line Input #bFile, verString    
        If Trim(verString) <> "" Then    
            bracketStart = InStr(verString, "[")    
            bracketEnd = InStr(verString, "]")    
            If bracketStart And bracketEnd > 0 Then    
                versionLength = bracketEnd - bracketStart    
                verInfo = Mid(verString, bracketStart + 1, versionLength - 1)    
                If InStr(verString, "6.2") Then    
                    fResult = "Windows 8 " & verInfo    
                End If    
                If InStr(verString, "6.1") Then    
                    fResult = "Windows 7 " & verInfo    
                End If    
                If InStr(verString, "5.") Then    
                    fResult = "Windows XP " & verInfo    
                End If    
                Exit Do    
                Else    
                fResult = verString    
                Exit Do    
            End If    
        End If    
    Loop    
Close #bFile    
GetMyWindowsVersion = fResult    
End Function
Ray
  • 31
  • 1
0

This is what you are looking for....

Option Explicit



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

Private Const VER_NT_WORKSTATION = 1
Private Const VER_NT_DOMAIN_CONTROLLER = 2
Private Const VER_NT_SERVER = 3

Private Type OSVERSIONINFOEX
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
    wServicePackMajor As Integer
    wServicePackMinor As Integer
    wSuiteMask As Integer
    wProductType As Byte
    wReserved As Byte
End Type

Private Declare Function GetVersionExA Lib "kernel32" (ByRef lpVersionInformation As OSVERSIONINFOEX) As Long




Public Function GetWindowsVersion() As String
    Dim osinfo As OSVERSIONINFOEX
    Dim retvalue As Integer

    osinfo.dwOSVersionInfoSize = 148
    osinfo.szCSDVersion = Space$(128)
    retvalue = GetVersionExA(osinfo)

    With osinfo
        Select Case .dwPlatformId
            Case 1
                Select Case .dwMinorVersion
                    Case 0:         GetWindowsVersion = "Windows 95"
                    Case 10:        GetWindowsVersion = "Windows 98"
                    Case 90:        GetWindowsVersion = "Windows Millenium"
                End Select

            Case 2
                Select Case .dwMajorVersion
                    Case 3:         GetWindowsVersion = "Windows NT 3.51"
                    Case 4:         GetWindowsVersion = "Windows NT 4.0"

                    Case 5
                        Select Case .dwMinorVersion
                            Case 0: GetWindowsVersion = "Windows 2000"
                            Case 1: GetWindowsVersion = "Windows XP"
                            Case 2: GetWindowsVersion = "Windows 2003"
                        End Select

                    Case 6
                        Select Case .dwMinorVersion
                            Case 0: GetWindowsVersion = "Windows Vista/2008"
                            Case 1: GetWindowsVersion = "Windows 7/2008 R2"
                            Case 2: GetWindowsVersion = "Windows 8/2012"
                            Case 3: GetWindowsVersion = "Windows 8.1/2012 R2"
                        End Select
                End Select

            Case Else
                GetWindowsVersion = "Failed"
        End Select
    End With
End Function
Steve
  • 1
0

Take a look at the following site. This works for detecting Vista and Windows 2008, with some minor enhancement it should work for Windows 7.

Zamboni
  • 7,897
  • 5
  • 43
  • 52
0

Your lookups are wrong; dwMajorVersion 5 is win2k or XP, 6 is Server 2k8 R2 or Win 7 - you need to take into account dwMinorVersion to make your detection accurate. (Table of values)

Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • Thanks for the link to the table. I am using the code someone suggested above to check both majorversion and minorversion, with compatibility level set to Windows 2000, but I am still getting majorversion = 5. – DeveloperM May 12 '11 at 17:45
  • Did you mean **not** set? I'm on win7 x64 & if I copy/paste your code and `Debug.Print osinfo.dwMajorVersion, osinfo.dwMinorVersion` I get `6, 1` - Have you run this from a compiled exe? I know that Glass is disabled for the VB6 IDE, perhaps some other compatibility setting is affecting the result – Alex K. May 12 '11 at 18:33
-1

Thanks for the code. However I have tried this on Windows 7 Ultimate and it reports as "XP" with "version 5.1"?

Ok I have just tried the following and it seems to be working fine. This is using the MS SysInfo control.

Private Sub Command2_Click()

    Dim MsgEnd As String
    Select Case SysDetectOS.OSPlatform
        Case 0
            MsgEnd = "Unidentified"
        Case 1
            MsgEnd = "Windows 95, ver. " & _
                     CStr(SysDetectOS.OSVersion) & "(" & _
                     CStr(SysDetectOS.OSBuild) & ")"
        Case 2
            MsgEnd = "Windows NT, ver. " & _
                     CStr(SysDetectOS.OSVersion) & "(" & _
                     CStr(SysDetectOS.OSBuild) & ")"

            If SysDetectOS.OSVersion >= 6.01 Then
                MsgEnd = MsgEnd + " Win7"
            End If        
    End Select
    MsgBox "System: " & MsgEnd    
End Sub
forsvarir
  • 10,749
  • 6
  • 46
  • 77
Krammig
  • 11
  • 3
  • 1
    Yes. Windows XP **is** version 5.1. That's the way it *should* be reporting it. I don't really understand why people are proposing all these alternative, half-working implementations. Did you miss [the link](http://stackoverflow.com/questions/4839210/how-can-i-determine-the-windows-version-from-a-vb-6-app) in my answer to a **fully-tested, fully-working** VB 6 implementation? Guaranteed to work or your money back. You can even examine the code and see which version numbers correspond to which version of Windows. – Cody Gray - on strike May 14 '11 at 04:27