Page 1 of 1

Detect Windows Version With WIN API Rate Topic: -----

#1 no2pencil  Icon User is online

  • Toubabo Koomi
  • member icon

Reputation: 5247
  • View blog
  • Posts: 27,071
  • Joined: 10-May 07

Posted 07 August 2011 - 02:09 AM

This is just one of a few ways to detect the current version of Windows. The reasons for doing are plentiful, but I'm sure most important would be directory locations, Operating System abilities, assumptions of Windows Software, & so on & so on...

First we define the _WIN32_WINNT value :

#define _WIN32_WINNT    0x0500



Next we load some standard headers. Most are used for self-explanatory items. If you are needing to detect the version of Windows for programmatic requirements, then I'm certain you know what these are & why they are in here ;)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <dirent.h> 



Now this is the header that defines our magic :

#include <shlobj.h>



& of course my favorite custom header. This is what I use for version number, string version representation, & of course the string output of the Windows version numbers :

#include "vars.h"



This is just some standard Windows API to setup our skeleton window. Again, I believe it's safe to assume you know what this is & why we need it :

// Global Variables
HWND g_hwnd; // main
HWND c_hwnd = NULL; //child

// Function Definitions
BOOL CALLBACK DlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {
    //#pragma region part 1 - use a WNDCLASSEX structure to create a window!!
    WNDCLASSEX wcx;
    MSG msg;

    wcx.cbClsExtra=0;
    wcx.cbSize=sizeof(WNDCLASSEX);
    wcx.cbWndExtra=0;
    wcx.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); // Change Background with NULL & WM_PAINT/WM_ERASEBKGND
    wcx.hCursor=LoadCursor(NULL, IDC_ARROW); //IDC_WAIT
    wcx.hIcon=LoadIcon( NULL, IDI_APPLICATION );
    wcx.hIconSm=NULL;
    wcx.hInstance=hInstance;
    wcx.lpfnWndProc=WndProc;
    wcx.lpszClassName=TEXT(STR_STR);
    wcx.lpszMenuName=MAKEINTRESOURCE(IDR_MYMENU);
    wcx.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClassEx(&wcx);

    g_hwnd=CreateWindowEx(WS_EX_LAYERED,TEXT(STR_STR),TEXT(STR_VER) TEXT(WRITTEN) TEXT(WRITTEN_YEAR),WS_OVERLAPPEDWINDOW,10, 10,400, 400, NULL, NULL, hInstance, NULL);
    SetLayeredWindowAttributes(g_hwnd, 0, 255, LWA_ALPHA );

    ShowWindow(g_hwnd, iCmdShow);
    UpdateWindow(g_hwnd);

    #pragma endregion
    #pragma region part 2 - enter message loop    

    while(GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    #pragma endregion
    return msg.wParam;
}



Alright, now we are talking! Lets get into some Win API magic!

Define our callback loop :
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {



Set the buffer variable for our version string : (& other variables)

    char BUFFER[BUFF]={0};
    HMENU hMenu, hSubMenu;
    HICON hIcon, hIconSm;



Our version definition type & variable :

    OSVERSIONINFO osvi;



The number (or integer) of the version :
    int value=PB_MIN;



Run init controls : (which is really for the progress bar)

    InitCommonControls(); 



Gather the version of Windows & load it into the variables. We are doing this here so that with any of the API loop the values will already be ready.

    // Gather version of Windows
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);




More standard API :

    GetVersionEx(&osvi);
    switch(message) {
    	case WM_CREATE: {
    	}
    	break;
	    case WM_KEYDOWN:
    	    switch(wparam) {



On the key escape, lets fill the buffer & show some results!

        	case VK_ESCAPE:
        		if(osvi.dwMajorVersion==6)
	        		c_hwnd = CreateWindowEx(0, PROGRESS_CLASS, (LPSTR)NULL, WS_CHILD | WS_VISIBLE, 10,10,200,10, hwnd, (HMENU) 0, NULL, NULL);
        		else
	        		c_hwnd = CreateWindowEx(0, PROGRESS_CLASS, (LPSTR)NULL, WS_CHILD | WS_VISIBLE, 10,10,200,10, hwnd, (HMENU) 0, NULL, NULL);
				if(!c_hwnd) {
	        		sprintf(BUFFER,"%s : Error!",STR_VER);
	        		MessageBox(hwnd, "Progress bar failed to init", BUFFER, 0|MB_OK);
	        		break;
        		}
        		while(value<PB_MAX) {
					SendMessage(c_hwnd, PBM_SETRANGE, 0, MAKELPARAM(PB_MIN,PB_MAX));
					SendMessage(c_hwnd, PBM_SETPOS, (WPARAM)value, 0);
					value++;
				}
				if(osvi.dwMajorVersion==5) {
					if(osvi.dwMinorVersion==0)	sprintf(BUFFER, "This client is running Microsoft %s",WIN2K);
					if(osvi.dwMinorVersion==1)	sprintf(BUFFER, "This client is running Microsoft %s",WINXP);
					if(osvi.dwMinorVersion==2)  sprintf(BUFFER, "This client is running Microsoft %s",WIN2003);
				}
				if(osvi.dwMajorVersion==6) {
					if(osvi.dwMinorVersion==0)  sprintf(BUFFER, "This client is running Microsoft %s",WINVISTA);
					if(osvi.dwMinorVersion==1)  sprintf(BUFFER, "This client is running Microsoft %s",WIN7);
				}



Seeing is believing ;)

	        	MessageBox(hwnd, BUFFER, "Windows Version", 0|MB_OK);
    
        		sprintf(BUFFER,"%s : Exit?",STR_VER);
        		if(MessageBox(hwnd, "Are you sure you want to exit?", BUFFER, 4|MB_ICONQUESTION)==IDYES) PostQuitMessage(0);



Lastly, we'll cleanly exit the Win API loop, or handle the exit :

        		break;
        	default:
        		break;
    		}
            break;
    	case WM_PAINT: {
            PAINTSTRUCT ps;
            EndPaint(hwnd, &ps);
        }
        break;
	   	case WM_DESTROY:
        	PostQuitMessage(0);
        break;
        default:
            break;
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}



The variables header file :

#define VER 			".01"
#define STR_STR			"Windows Version & Progress Bar"
#define STR_VER 		"Version .01"
#define WRITTEN			" #2pencil  "
#define WRITTEN_YEAR	"2011"
#define MAX 			256
#define BUFF 			2048
#define PB_MIN			0
#define PB_MAX			9999

// Dialog Box
#define IDD_MAINDLG 	1001
#define IDC_OUTLINE		1002
#define IDC_EDITBOX		1003
#define IDC_STATICENTER	1004
#define IDC_LISTBOX 	1005
#define IDC_BTN_SEL		1006
#define IDC_BTN_CAN		1007

// Menu Items
#define IDR_MYMENU 101
#define IDI_MYICON 201

#define ID_FILE_EXIT 	9000

#define ID_PROCESS_BEGN	9100
#define ID_PROCESS_STOP	9101

#define ID_HELP			9200
#define ID_HELP_ABOUTUS	9201
#define ID_HELP_TOPICS	9202

// Windows Versions
#define WIN7			"Windows 7"
#define WINVISTA		"Windows Vista"
#define	WIN2003			"Windows 2003"
#define	WINXP			"Windows XP"
#define WIN2K			"Windows 2000"


& finally I'll provide you with the full version of the code :

#define _WIN32_WINNT    0x0500

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <dirent.h> 
#include <shlobj.h>

#include "vars.h"

// Global Variables
HWND g_hwnd; // main
HWND c_hwnd = NULL; //child

// Function Definitions
BOOL CALLBACK DlgProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {
    //#pragma region part 1 - use a WNDCLASSEX structure to create a window!!
    WNDCLASSEX wcx;
    MSG msg;

    wcx.cbClsExtra=0;
    wcx.cbSize=sizeof(WNDCLASSEX);
    wcx.cbWndExtra=0;
    wcx.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); // Change Background with NULL & WM_PAINT/WM_ERASEBKGND
    wcx.hCursor=LoadCursor(NULL, IDC_ARROW); //IDC_WAIT
    wcx.hIcon=LoadIcon( NULL, IDI_APPLICATION );
    wcx.hIconSm=NULL;
    wcx.hInstance=hInstance;
    wcx.lpfnWndProc=WndProc;
    wcx.lpszClassName=TEXT(STR_STR);
    wcx.lpszMenuName=MAKEINTRESOURCE(IDR_MYMENU);
    wcx.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClassEx(&wcx);

    g_hwnd=CreateWindowEx(WS_EX_LAYERED,TEXT(STR_STR),TEXT(STR_VER) TEXT(WRITTEN) TEXT(WRITTEN_YEAR),WS_OVERLAPPEDWINDOW,10, 10,400, 400, NULL, NULL, hInstance, NULL);
    SetLayeredWindowAttributes(g_hwnd, 0, 255, LWA_ALPHA );

    ShowWindow(g_hwnd, iCmdShow);
    UpdateWindow(g_hwnd);

    #pragma endregion
    #pragma region part 2 - enter message loop    

    while(GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    #pragma endregion
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
    char BUFFER[BUFF]={0};
    HMENU hMenu, hSubMenu;
	HICON hIcon, hIconSm;
	OSVERSIONINFO osvi;
	int value=PB_MIN;
	InitCommonControls(); 
	// Gather version of Windows
	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osvi);
    switch(message) {
    	case WM_CREATE: {
    	}
    	break;
	    case WM_KEYDOWN:
    	    switch(wparam) {
        	case VK_ESCAPE:
        		if(osvi.dwMajorVersion==6)
	        		c_hwnd = CreateWindowEx(0, PROGRESS_CLASS, (LPSTR)NULL, WS_CHILD | WS_VISIBLE, 10,10,200,10, hwnd, (HMENU) 0, NULL, NULL);
        		else
	        		c_hwnd = CreateWindowEx(0, PROGRESS_CLASS, (LPSTR)NULL, WS_CHILD | WS_VISIBLE, 10,10,200,10, hwnd, (HMENU) 0, NULL, NULL);
				if(!c_hwnd) {
	        		sprintf(BUFFER,"%s : Error!",STR_VER);
	        		MessageBox(hwnd, "Progress bar failed to init", BUFFER, 0|MB_OK);
	        		break;
        		}
        		while(value<PB_MAX) {
					SendMessage(c_hwnd, PBM_SETRANGE, 0, MAKELPARAM(PB_MIN,PB_MAX));
					SendMessage(c_hwnd, PBM_SETPOS, (WPARAM)value, 0);
					value++;
				}
				if(osvi.dwMajorVersion==5) {
					if(osvi.dwMinorVersion==0)	sprintf(BUFFER, "This client is running Microsoft %s",WIN2K);
					if(osvi.dwMinorVersion==1)	sprintf(BUFFER, "This client is running Microsoft %s",WINXP);
					if(osvi.dwMinorVersion==2)  sprintf(BUFFER, "This client is running Microsoft %s",WIN2003);
				}
				if(osvi.dwMajorVersion==6) {
					if(osvi.dwMinorVersion==0)  sprintf(BUFFER, "This client is running Microsoft %s",WINVISTA);
					if(osvi.dwMinorVersion==1)  sprintf(BUFFER, "This client is running Microsoft %s",WIN7);
				}
	        	MessageBox(hwnd, BUFFER, "Windows Version", 0|MB_OK);
    
        		sprintf(BUFFER,"%s : Exit?",STR_VER);
        		if(MessageBox(hwnd, "Are you sure you want to exit?", BUFFER, 4|MB_ICONQUESTION)==IDYES) PostQuitMessage(0);
        		break;
        	default:
        		break;
    		}
            break;
    	case WM_PAINT: {
            PAINTSTRUCT ps;
            EndPaint(hwnd, &ps);
        }
        break;
	   	case WM_DESTROY:
        	PostQuitMessage(0);
        break;
        default:
            break;
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}



Attached Image

Is This A Good Question/Topic? 3
  • +

Replies To: Detect Windows Version With WIN API

#2 programmer4life  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 25-February 10

Posted 07 August 2011 - 02:12 PM

I made something similar some time ago using source code from somewhere using VB.NET:

http://www.mediafire.com/?5qknj0zmh0l

^ That's the result. It just tells you your NT version, but yeah you could easily change the code so it tells you the Windows version instead using the result.
Was This Post Helpful? 0
  • +
  • -

#3 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3553
  • View blog
  • Posts: 11,014
  • Joined: 05-May 12

Posted 02 June 2012 - 01:04 PM

Yikes! Are you getting paid by the line of code? Why does you WM_PAINT handler have an EndPaint() with no BeginPaint()? Why do you even have a WM_CREATE handler? Why is your progress bar code setting the range each iteration through the loop? What progress is the progress bar really showing since you already got the version a few lines back? What is the difference between line 79 and 81? What are the magic numbers that you OR in with the MessageBox() options parameter?

I think this would be so much simpler:
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define CountOf(_a) (sizeof(_a) / sizeof(_a[0]))

void MapVersionToString(const OSVERSIONINFOEX * posvi, LPTSTR pszVersion, INT cchVersionMax)
{
    PCWSTR pszProduct = NULL;
    TCHAR szUnknown[1024];

    // This is pretty basic. More detailed version string code can be found at:
    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724429(v=vs.85).aspx
    switch(posvi->dwMajorVersion)
    {
    case 5:
        switch(posvi->dwMinorVersion)
        {
        case 0:
            pszProduct = TEXT("Windows 2000");
            break;

        case 1:
            pszProduct = TEXT("Windows XP");
            break;

        case 2:
            if (GetSystemMetrics(SM_SERVERR2) == 0)
                pszProduct = TEXT("Windows Server 2003");
            else
                pszProduct = TEXT("Windows Server 2003 R2");
            break;
        }
        break;

    case 6:
        switch(posvi->dwMinorVersion)
        {
        case 0:
            if (posvi->wProductType == VER_NT_WORKSTATION)
                pszProduct = TEXT("Windows Vista");
            else
                pszProduct = TEXT("Windows Server 2008");
            break;

        case 1:
            if (posvi->wProductType == VER_NT_WORKSTATION)
                pszProduct = TEXT("Windows 7");
            else
                pszProduct = TEXT("Windows Server 2008 R2");
            break;
        }
        break;
    }

    if (!pszProduct)
    {
        StringCchPrintf(szUnknown, CountOf(szUnknown), TEXT("Windows Version %d.%d"), posvi->dwMajorVersion, posvi->dwMinorVersion);
        pszProduct = szUnknown;
    }

    StringCchPrintf(pszVersion, cchVersionMax, TEXT("Microsoft %s %s"), pszProduct, posvi->szCSDVersion);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    OSVERSIONINFOEX osvi = { 0 };
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    if (!GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&osvi)))
    {
        DWORD dwError = GetLastError();
        TCHAR szError[1024];
        StringCchPrintf(szError, CountOf(szError), TEXT("GetVersionEx() returned with last error set to %ld (%08x)"), dwError, dwError);
        MessageBox(NULL, szError, TEXT("Error"), MB_IConerror | MB_OK);
        return -1;
    }

    TCHAR szVersion[1024];
    MapVersionToString(&osvi, szVersion, CountOf(szVersion));
    MessageBox(NULL, szVersion, TEXT("Windows Version"), MB_ICONINFORMATION | MB_OK);
    return 0;
}


This post has been edited by Skydiver: 02 June 2012 - 01:05 PM

Was This Post Helpful? 1
  • +
  • -

#4 no2pencil  Icon User is online

  • Toubabo Koomi
  • member icon

Reputation: 5247
  • View blog
  • Posts: 27,071
  • Joined: 10-May 07

Posted 23 June 2012 - 06:27 PM

View PostSkydiver, on 02 June 2012 - 04:04 PM, said:

Yikes! Are you getting paid by the line of code? Why does you WM_PAINT handler have an EndPaint() with no BeginPaint()? Why do you even have a WM_CREATE handler? Why is your progress bar code setting the range each iteration through the loop? What progress is the progress bar really showing since you already got the version a few lines back? What is the difference between line 79 and 81? What are the magic numbers that you OR in with the MessageBox() options parameter?

The beauty of Dream In Code Tutorials is that one can post their contributions, & someone else can tare it apart so that others can learn why not to repeat something.

Thank you for increasing the usability of my tutorial.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1