Determine Information about System, User, Processes, Hardware...






4.71/5 (18 votes)
The never ending 'How do I find' article. Will be updated regularly!
And it begins!
This article is compilation of all "How To Determine" list. For example "How to find the computer name", "how to find number of fonts installed on system". As you know the list is endless, and this would be regularly updated, updated on reader's demands and as new technology evolve.
Every effort it taken to use both C++
and C#
. C++ code will be on top of native Windows API, and optionally using MFC. C# code will be on top of .NET framework, and if not available using DllImports of native Windows API. Content and examples on .NET may get delayed, but they would be added on regular basic. For all "how-to-retrieve" operation, there would be C++. For C++, wherever applicable, Unicode strings and functions are used.
No error checking is done in code snippets shown below. In projects attached, basic error checking is done.
Following is list of all "how-to" that is explained in this article. Linked or Bold content is mentioned here, and other how-to is scheduled for discussion. As the article would grow up, I would logically structure it.
- Retrieve Current Date and Time (Jump to .NET)
- Retrieve the name of User currently Logged in (Jump to .NET)
- Retrieve Name of Computer (Jump to .NET)
- Retrieve the Number of Processors (Jump to .NET)
- Retrieve Information about Memory (Jump to .NET)
- Retrieve Information about Drives
- Retrieve the Monitor Resolution
- Retrieve Windows Version
- How to find if I am connected to Internet?
- How to find CPU speed?
- How to find how many users are logged in?
- How to find all shares shared by me?
- How to find shares being accessed by users?
- How to find which Windows OS I am using?
- How to find if I am an Administrator?
- How to find number of processes running?
- How to find number of processors?
- How to find How long system has been running (uptime)?
- ...
Retrieve Current Date and Time
-
C++
There are multiple ways to retrieve the date/time. It depends if you need System Time (UTC), or the local time; the precision level of time and the preference with the time-retrieval function.
To retrieve Local Time, use can use GetLocalTime API, which would return time adjusted as per your location. This is the date/time you see everywhere and should display to end user. It retrieves local-time in SYSTEMTIME structure:
void DisplayCurrentTimeLocal() { SYSTEMTIME stLocal; GetLocalTime(&stLocal); // Raw display in YYYY-MM-DD, HH:MM:SS.ms format _tprintf( _T("Local Time: %d-%02d-%02d, %02d:%02d:%02d.%03d"), stLocal.wYear, stLocal.wMonth, stLocal.wDay, // Date stLocal.wHour, stLocal.wMinute, stLocal.wSecond, stLocal.wMilliseconds); }
You may retrieve non-adjusted System Time using GetSystemTime API. A UTC time may be useful for time-stamping in file or database, or to let Time travel across globe with consistency. It also takes SYSTEMTIME
structure.
void DisplayCurrentTimeSystem() { SYSTEMTIME stSystem; GetSystemTime(&stSystem); _tprintf( _T("UTC Time: %d-%02d-%02d, %02d:%02d:%02d.%03d"), stSystem.wYear, stSystem.wMonth, stSystem.wDay, // Date stSystem.wHour, stSystem.wMinute, stSystem.wSecond, stSystem.wMilliseconds); }
My friendly MFC programmers can use static method of CTime, named GetCurrentTime, which returns a CTime
object. This class provides many Get functions to retrieve different components of date/time. The method Format, which formats the time as per the format string given (same as strftime), can be used to generate user friendly time.
void DisplayCurrentTimeMFC() { CTime theTime; CString sFormattedTime; theTime = CTime::GetCurrentTime(); sFormattedTime = theTime.Format( _T("Today is %A, %B %d, %Y. And the time is %I:%M %p")); _tprintf(L"%s", sFormattedTime); // Today is Saturday, October 02, 2010. And the time is 10:31 AM }
Though not the time par se, GetTickCount
[64
] can be used to retrieve number of milliseconds elapsed since system was started. The old version, GetTickCount, can work flawlessly up to 49.7 days. For Windows Vista and higher OS, you should use GetTickCount64.
The C Runtime Library lovers can use _ftime and _ftime_s family of functions to retrieve current System Time; and localtime and localtime_s family of functions to retrieve Local Time. The time family of functions returns number of seconds elapsed* since 1-Jan-1970 midnight. All these functions internally use GetSystemTimeAsFileTime
.
Though not mentioned in MSDN, all other Windows API functions also use GetSystemTimeAsFileTime to retrieve current system time. GetSystemTimeAsFileTime
calls the not exposed (via header/library) function NtQuerySystemTime. The function GetSystemTimeAsFileTime
returns the most precise time among all other functions. It presumably returns timing in 100-nanoseconds precision. The precision depends on the hardware, the Operating System and the timing resolution set by calling process (use undocumented NtSetTimerResolution to set timer/timing resolution).
With .NET framework, you can use the shared/static property Now of DateTime class to retrieve Local Time. The DateTime
class is capable of producing time in precision of 100-nanoseconds.
// This method, and other upcoming methods are in InfoObtainer class. // The source code attached has complete code of InfoObtainer. void DisplayLocalTime() { // Get local time DateTime dtCurrentTime = DateTime.Now; Console.WriteLine("Local time (system formatted): {0}",dtCurrentTime); Console.WriteLine("Local time: {0:D4}-{1:D2}-{2:D2}, {3:D2}:{4:D2}:{5:D2}.{6:D3}", dtCurrentTime.Year, dtCurrentTime.Month, dtCurrentTime.Day, dtCurrentTime.Hour, dtCurrentTime.Minute, dtCurrentTime.Second, dtCurrentTime.Millisecond); }
Likewise, to retrieve the System Time in UTC, you can use the static property UtcNow.
void DisplaySystemTime() { // Retrieve system time DateTime dtCurrentTime = DateTime.UtcNow; Console.WriteLine("System time (system formatted): {0}",dtCurrentTime); Console.WriteLine("System time: {0:D4}-{1:D2}-{2:D2}, {3:D2}:{4:D2}:{5:D2}.{6:D3}", dtCurrentTime.Year, dtCurrentTime.Month, dtCurrentTime.Day, dtCurrentTime.Hour, dtCurrentTime.Minute, dtCurrentTime.Second, dtCurrentTime.Millisecond); }
To retrieve only the date, you can use static property Today, which keeps the time component to be 00:00:00
. The date component is retrieve out of Local Time, and not of System Time.
Just for completeness, the public property Kind (of type DateTimeKind
) can be used to know if time represented by DateTime
object is local, system or undefined type. Thus, when you retrieve local date/time using Now
or Today
, it would be DateTimeKind.Local
; and when you retrieve it using UtcNow
, it would be DateTimeKind.Utc
. This kindness is available in .NET Framework 2.0 and above.
The Ticks property returns number of 100-nanoseconds for this instance. A Tick is actually 0.1
microsecond, or 1/
10000
(0.0001
) milliseconds. Ticks
property is 64-bit integer. The following code calculates the microseconds out of 100-nanoseconds, and displays.
DateTime dtCurrentTime = DateTime.Now; // Get microseconds double nMicroSecs = ( dtCurrentTime.Ticks % 10000 ) / 10.0; Console.WriteLine("Time: {0:D2}:{1:D2}:{2:D2}, {3:D3}:{4:F1}", dtCurrentTime.Hour, dtCurrentTime.Minute, dtCurrentTime.Second, dtCurrentTime.Millisecond, nMicroSecs);
Retrieve Logged-in Username
-
C++
Technically it's not the username who is logged in, but the process or thread which is running under a user. A user or programmer may launch a process into another logon-credential using "RunAs" verb, or spawn a process using CreateProcessAsUser function. A running thread might be impersonated using ImpersonateLoggedOnUser API, or other impersonating functions. Well, this section is not about these tricks, but to retrieve the username under which current thread is running (or impersonating).
You can use GetUserName function to retrieve only the username.
void DisplayUserName() { // UNLEN (256) is defined in lmcons.h TCHAR Username[UNLEN+1]; DWORD nULen = UNLEN; GetUserName(Username, &nULen); _tprintf( _T("Username: %s"), Username); // Username: Ajay }
To retrieve fullname of user, you need to use GetUserNameEx function. This function is declared in header Security.h
(actually in secext.h
), thus you must #include<Security.h>
. Including this header requires either of these to be defined:
SECURITY_WIN32
- SECURITY_KERNEL
- SECURITY_MAC
Since our application is Windows' User-mode application, use just define the first one. Further, we need to include the library Secur32.lib
in Linker settings. Anyway, here is code:
#define SECURITY_WIN32 #include <Security.h> // Link with secur32.lib void DisplayUserNameEx() { TCHAR Username[UNLEN+1]; DWORD nULen = UNLEN; GetUserNameEx(NameSamCompatible, Username, &nULen); _tprintf( _T("Username: %s"), Username); }
Yes,
GetUserNameEx
takes one extra parameter, which is of EXTENDED_NAME_FORMAT enum type. The symbol NameSamCompatible
is one of them enum of this type. On non-domain connected computers, only this enum is supported. Please explore other members of EXTENDED_NAME_FORMAT
yourself, with which you can retrieve full name of user, the display name, the GUID of user; to name a few. The following is output of above' code:
Username: HERCULES\Ajay
Following is just for relevant discussion. As you know a process may be running in another Logon Session (i.e. sharing the Desktop/Console of other user), and the methods described above would just locate the username and not any information about the session under which process/thread is running. Whilst, I would elaborate about this sooner or later, the function you can use is: WTSGetActiveConsoleSessionId.
.NET programmers can use Environment.UserName property to retrieve only the username. The Environment.UserDomainName property retrieves the domain name associated with current process/thread.
void DisplayUserName() { Console.Write("Domain of user is: "); Console.WriteLine(Environment.UserDomainName); // HERCULES Console.Write("User name is: "); Console.WriteLine(Environment.UserName); // Ajay }
Please see MSDN documentation on how domain-name retrieval works. You can use following to retrieve both username and domain name in DOMAIN/USERNAME
format:
string sFullyQualified = System.Security.Principal.WindowsIdentity.GetCurrent().Name; Console.WriteLine("Fully qualified username: {0}", sFullyQualified);
See WindowsIdentity.Name property for more information.
Unfortunately, .NET Framework doesn't support equivalent routine for GetUserNameEx
. Therefore, you must import this function:
// using System.Runtime.InteropServices; public enum EXTENDED_NAME_FORMAT { NameUnknown = 0, NameFullyQualifiedDN = 1, NameSamCompatible = 2, NameDisplay = 3, NameUniqueId = 6, NameCanonical = 7, NameUserPrincipal = 8, NameCanonicalEx = 9, NameServicePrincipal = 10, NameDnsDomain = 12 } [DllImport("secur32.dll", CharSet = CharSet.Auto)] public static extern int GetUserNameEx(EXTENDED_NAME_FORMAT nameFormat, StringBuilder userName, ref uint userNameSize);
And you can call this imported function like this:
StringBuilder userName = new StringBuilder(1024); uint userNameSize = 1024; GetUserNameEx(EXTENDED_NAME_FORMAT.NameSamCompatible, userName, ref userNameSize); Console.Write(userName);
This code is derived from PInvoke.Net.
Retrieve the name of Computer
-
C++
Use GetComputerName to retrieve the name of computer.
void DisplayComputerName() { TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1]; DWORD lnNameLength= MAX_COMPUTERNAME_LENGTH; GetComputerName( szComputerName, &lnNameLength); _tprintf( L"\nComputer name: %s\n", szComputerName); // HERCULES }
To get computer name in different formats you can use GetComputerNameEx function. Since my personal machine is not connected to any domain, it would always show the same name, or would return empty name when I call GetComputerNameEx with different format specifiers. Anyway, here is sample code.
void DisplayComputerNameEx() { // Computer names may be larger than this macro, just // doubling the buffer size. See MSDN for more info. TCHAR scComputerName[MAX_COMPUTERNAME_LENGTH*2 + 1]; DWORD lnNameLength = MAX_COMPUTERNAME_LENGTH*2; GetComputerNameEx(ComputerNameNetBIOS, scComputerName, &lnNameLength); _tprintf( _T("Computer name: %s\n"), scComputerName); }
The symbol ComputerNameNetBIOS
is one of the symbols of enum type COMPUTER_NAME_FORMAT.
Use Environment.MachineName property to get the name of computer. Example:
public void DisplayComputerName() { Console.Write("Computer name is: "); Console.WriteLine(Environment.MachineName); }
You can also use System.Net.Dns.GetHostName to retrieve the same.
The .NET framework does not support equivalent to GetComputerNameEx
, thus you must import this function. For brevity, I am not showing code how to import. See GetUserNameEx
import sample above.
Retrieve the Number of Processors
-
C++
The function GetSystemInfo can be used to retrieve number of logical processors installed on system, including other processor related information. The GetSystemInfo takes SYSTEM_INFO and fills it. Following code displays number of processors installed on system.
void DisplayProcessorCount() { SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); _tprintf( _T("Number of processors: %d"), sysInfo.dwNumberOfProcessors); }
In .NET, it is fairly easy to retrieve logical processor count. Just use Environment.ProcessorCount property.
Console.WriteLine("Processor count: {0}", Environment.ProcessorCount);
Retrieve Information about Hard Drives
This section about Hard Drive volumes and capacities, not about harddisk devices.
-
C++
Information about hard drives may include the following:
- The drives present on the system (Volumes names like
C:
,D:
etc.) - The type of each volume present (CDROM, Hard drive, USB drive etc.)
- The capacity, allocated and free bytes on the drive.
- The file system of specified volume (FAT32, NTFS etc)
Let's start by listing the volumes present in the system, like you see in Windows Explorer. For this you can use GetLogicalDrives and GetLogicalDriveStrings functions.
GetLogicalDrives
returns a 32-bit (DWORD
) value, which is just is just mask of drives present on system. For example, if a system as A:, C: and D: drives, the return values would be 13
, which is, in binary 1101
. The last bit digit in binary represents that system as A:
drive, and so on. Following is simplified approach to get and display drive letters.
void DisplayDrives() { DWORD dwDrivesMap = GetLogicalDrives(); // Start with A: drive char cDrive='A'; for (DWORD dwBitMask = 1; dwDrivesMap != 0;) { if (dwDrivesMap & dwBitMask) { _tprintf( _T("%c: drive present\n"), cDrive); // Discard this bit from DrivesMap dwDrivesMap &= ~dwBitMask; } // Next letter cDrive++; // Move to next (1, 2, 4, 8..32...128...) dwBitMask *= 2 ; // OR dwBitMask <<= 1; } }
This may not be intuitive for most readers. The another function GetLogicalDriveStrings
, generates set of null terminated strings, with two null terminated characters at end. As you can guess this misfortune, this function is also not straightforward. Here is an example that displays drives.
void DisplayDriveStrings() { TCHAR szDrives[MAX_PATH+1]; GetLogicalDriveStrings(MAX_PATH, szDrives); TCHAR* pLetter = szDrives; while(*pLetter) { _tprintf( _T("Drive %s present\n"), pLetter); // _tprintf( _T("Drive %c: present\n"), *pLetter); // Find the null terminator for this string while(*++pLetter) ; // Notice Semi-colon! // And the next *possible* drive letter, // Or get the termination of all drive letters. pLetter++; } }
Okay, now let determine the type of drive (not the file-system). The type could be hard-disk drive, CDROM drive, Network drive, USB drive etc. First, I would explore simple function named GetDriveType, which returns one of the seven values (see the link mentioned). The following example shows how to process the drive type (only two types are processed).
void DisplayDriveTypes() { TCHAR szDrives[MAX_PATH+1]; DWORD dwLen = GetLogicalDriveStrings(MAX_PATH, szDrives); TCHAR* pLetter = szDrives; while(*pLetter) { UINT nType = GetDriveType(pLetter); _tprintf( _T("Drive %c: is "), *pLetter); switch(nType) { case DRIVE_FIXED: _tprintf( _T("Fixed Drive.\n") ); break; case DRIVE_CDROM: _tprintf( _T("CD/DVD Drive.\n") ); break; // Process other types } while(*++pLetter) ; // Notice Semi-colon! pLetter++; } }
This function cannot determine extended information, like if drive is USB drive. For this we need to use SetupDiGetDeviceRegistryProperty function, which is declared in setupapi.h
, exported via library setupapi.lib
and resides in setupapi.dll
. It is available on Windows 2000 and later systems. I am taking your implicit permission to delay writing about it, since it requires some effort on the Setup API ground.
Meanwhile, we proceed and now let's find out about capacity of drives. For this, we can use GetDiskFreeSpace
or GetDiskFreeSpaceEx function. Former does not support reporting information above 2GB, thus should not be used. Following example display the sizes of all enumerated drives.
void DisplayDriveSizes() { TCHAR szDrives[MAX_PATH+1]; DWORD dwLen = GetLogicalDriveStrings(MAX_PATH, szDrives); TCHAR* pLetter = szDrives; ULARGE_INTEGER liFree, liTotal; while(*pLetter) { // Get size, ignoring disk-quotas. GetDiskFreeSpaceEx(pLetter, NULL, &liTotal, &liFree); // Display information _tprintf ( _T("Drive %c: has\n\tBytes Total: %I64u (%.2f GB)\n") _T("\tBytes Available: %I64u (%.2f GB)\n\n"), *pLetter, liTotal.QuadPart, liTotal.QuadPart / (float)(1<<30), liFree.QuadPart, liFree.QuadPart/(float)(1<<30) ); while(*++pLetter); pLetter++; } }
Which would display something like:
Drive C: has Bytes Total: 58720251904 (54.69 GB) Bytes Available: 22550118400 (21.00 GB) Drive D: has Bytes Total: 85899341824 (80.00 GB) Bytes Available: 43008344064 (40.05 GB) Drive E: has Bytes Total: 341364961280 (317.92 GB) Bytes Available: 95171076096 (88.63 GB)
Finally let's retrieve File-System, Volume Label, Serial Number, Max File Length supported, and other Flags. For all this, you just need to use one function, GetVolumeInformation which takes eight parameters. The following code would help you to understand this function.
void DisplayVolumeInformations() { TCHAR szVolume[MAX_PATH+1]; TCHAR szFileSystem[MAX_PATH+1]; DWORD dwSerialNumber, dwMaxLen, dwSystemFlags; // Same stuff! TCHAR szDrives[MAX_PATH+1]; DWORD dwLen = GetLogicalDriveStrings(MAX_PATH, szDrives); TCHAR* pLetter = szDrives; BOOL bSuccess; while(*pLetter) { bSuccess = GetVolumeInformation(pLetter, // The source szVolume, MAX_PATH, // Volume Label (LABEL) &dwSerialNumber,&dwMaxLen, // Serial Number (VOL) &dwSystemFlags, szFileSystem, MAX_PATH); // File System (NTFS, FAT...) if(bSuccess) { _tprintf( _T("Information about volume %c:\n"), *pLetter); // LABEL command _tprintf( _T("\tVolume Label: %s\n"), szVolume); // Standard formal to display serial number (VOL command) _tprintf( _T("\tSerial Number: %X-%X\n"), HIWORD(dwSerialNumber), LOWORD(dwSerialNumber)); // File-System _tprintf( _T("\tFile System: %s\n\n"), szFileSystem); } else { _tprintf ( _T("Cannot retrieve Volume information for %s\n\n"), pLetter); } while(*++pLetter) ; // Notice Semi-colon! pLetter++; } }
I have noticed that for CD/DVD drive, where no disc is inserted, this function fails. It cannot retrieve the information, since it is about drive/volume not about disk. It would present output in following form:
Information about volume C: Volume Label: Windows Serial Number: 24AE-237C File System: NTFS Information about volume D: Volume Label: Stuff Serial Number: 40C5-2816 File System: NTFS Cannot retrieve Volume information for G:\ Information about volume T: Volume Label: Colossal Serial Number: 2292-7263 File System: NTFS
Notice that Serial Number is just a 32-bit value, and I just printed lower 16-bits and upper 16-bits in hex, which is same as output given by VOL
command.
Retrieve Information about Memory
-
C++
To retrieve information about memory (RAM), you can either use GlobalMemoryStatus or GlobalMemoryStatusEx. They take MEMORYSTATUS
and MEMORYSTATUSEX structures, respectively. The former has limitations and cannot return correct information on systems having more than 4GB, thus it should not be used. The following example shows how to get memory information, and displays it.
void DisplayMemoryStatus() { MEMORYSTATUSEX memoryStatus; memoryStatus.dwLength = sizeof(MEMORYSTATUSEX); // MUST! GlobalMemoryStatusEx(&memoryStatus); const float OneGB = 1024 * 1024 * 1024; // (1<<30) // In GBs _tprintf( _T("Total physical memory: %.2f GB\n") _T("Available physical memory: %.2f GB\n") _T("Pagefile size: %.2f GB"), memoryStatus.ullTotalPhys / OneGB, memoryStatus.ullAvailPhys / OneGB, memoryStatus.ullTotalPageFile/OneGB); }
Which would display something like:
Total physical memory: 3.99 GB Available physical memory: 1.69 GB Pagefile size: 7.98 GB
You should explore other members of this structure. One member of this structure is worth mentioning: dwMemoryLoad
(DWORD), which returns percent of physical memory occupied. Thus, you need not to calculate the memory-load! For the above run, it was 57
.
There is no .NET framework class that supports direct information retrieval. Thus, you either need to import the GlobalMemoryStatusEx
function or use the following approach:
const float OneGB = (1024 * 1024 * 1024); System.Management.ManagementObjectSearcher mos; mos = new ManagementObjectSearcher("SELECT TotalPhysicalMemory, FROM Win32_ComputerSystem"); foreach (ManagementObject mob in mos.Get()) { foreach (PropertyData pyd in mob.Properties) { if (pyd.Name == "TotalPhysicalMemory") { Console.WriteLine("Total Memory size: {0:F2}", Convert.ToInt64(pyd.Value) / OneGB); break; } } }
Seriously, even I do not know about this stuff! I found it somewhere, and pasted here (after testing!). There are other approaches with System.Management to retrieve more of this type of information.
See this link on how to import native function and retrieve memory information. The same link (PInvoke.net) gives more clue about the same.
Retrieve the Monitor Resolution
-
C++
First thing I should address - the "get monitor resolution" could mean multiple things depending on your need and perspective. These perspectives could be:
- You need exact current resolution of monitor.
- You need maximum client-area size for your application, that would exclude the taskbar.
- You may need resolutions of multiple attached monitors/displays (if any).
Let's start with the first one - retrieve the actual current resolution of monitor. For this you need to use GetSystemMetrics function, passing SM_CXSCREEN
and SM_CYSCREEN
parameters, to get Width and Height of monitor's resolution.
void DisplayMonitorResolution() { int nWidth = GetSystemMetrics(SM_CXSCREEN); int nHeight = GetSystemMetrics(SM_CYSCREEN); _tprintf( _T("Current Resolution is - Width: %d, Height: %d"), nWidth, nHeight); // Current Resolution is - Width: 1920, Height: 1080 }
You can retrieve the same information using GetDeviceCaps function, passing HORZRES
and VERTRES
arguments. This function requires you to pass a Device Context (HDC
). This article won't describe about that, but I would just put the sample code to show how GetDeviceCaps
can be used.
int nWidth = GetDeviceCaps(GetDC(GetDesktopWindow()), HORZRES); int nHeight = GetDeviceCaps(GetDC(GetDesktopWindow()), VERTRES);
Now, let's determines full-screen client area size. For this you need to use GetSystemMetrics
function, passing SM_CXFULLSCREEN
and SM_CYFULLSCREEN
parameters, to get Width and Height of workable area. This size excludes two things: the size (width) of Title bar of window, and size of taskbar. While most users have taskbar on bottom of screen, thus Height would be smaller than actual resolution of monitor - but, taskbar can be on any side of monitor, it can be any size or it doesn't occupy the desktop (hidden or disabled). The following code displays the possible client area for a full-screen window:
void DisplayClientAreaSize() { int nWidth = GetSystemMetrics(SM_CXFULLSCREEN); int nHeight = GetSystemMetrics(SM_CYFULLSCREEN); _tprintf( _T("Maximum Client Area - Width: %d, Height: %d"), nWidth, nHeight); // Maximum Client Area - Width: 1920, Height: 1028 }
Okay, in the same perspective, you might want to know how to get dimensions of a full-screen application that would include the taskbar, and exclude the size of Title bar. Any media player with skin support may need this.
For this you need to use SystemParametersInfo function with SPI_GETWORKAREA
action parameter. Since this function supports wide range of retrievals, with varying data-types, it takes LPVOID (void*
) as argument. For our action parameter, we need to pass address of a RECT
structure. Here is code:
void DisplayFullScreenSize() { RECT rectRes; SystemParametersInfo(SPI_GETWORKAREA, 0, &rectRes, 0); _tprintf( _T("Possible work area: Top = %d, Left = %d, Right = %d, Bottom = %d"), rectRes.top, rectRes.left, rectRes.right, rectRes.bottom); }
It display following for my default resolution and normal size taskbar on bottom:
Possible work area: Top = 0, Left = 0, Right = 1920, Bottom = 1050
Well, you cannot ignore the top
and left
, since moving the taskbar on top would produce the following result (also, I doubled the task bar's size!):
Possible work area: Top = 62, Left = 0, Right = 1920, Bottom = 1080
Multiple monitors! To get information about monitors you need to use EnumDisplayMonitors
, which would enumerate all monitors on system, via a callback. The callback would get HMONITOR
, which can be passed to GetMonitorInfo
function. GetMonitorInfo
function would fill up MONITORINFO
[EX
], and that structure's member would have resolution of desire monitor! You see, this demands another section in this article, and I would soon put it!
Retrieve the Windows Version
-
C++
You can use GetVersion or GetVersionEx to retrieve the Windows Version. The former function returns a 32-bit value, whose lower 16-bit represents the major and minor version numbers. The higher order 16 bits represents the build number. Following example illustrates this.
void DisplayWindowsVersion() { DWORD dwWinVer; dwWinVer = GetVersion(); _tprintf ( _T("Windows version: %d.%d.%d"), LOBYTE(LOWORD(dwWinVer)), HIBYTE(LOWORD(dwWinVer)), // LoWord HIWORD(dwWinVer)); }
Which displays following output on my Windows 7 machine:
Windows version: 6.1.7600
GetVersion
function has some concerns (not bugs), thus is is not suitable for recent applications. It cannot determine product information (Professional, Ultimate), service pack information etc, for example. It should not be used in new applications.
For new applications GetVersionEx
function should be used. Exploring more about this function is beyond the scope of this article, only basic information is being provided. You should read this article on CodeGuru.com.
Just in brief; this function returns information in either OSVERSIONINFO or OSVERSIONINFOEX structure. No, this function is not overloaded - instead the dwOSVersionInfoSize
member, which should be set to size of either of these structures, determines which type of information is requested.
void DisplayWindowsVersionEx() { OSVERSIONINFOEX osvInfo ={0}; osvInfo.dwOSVersionInfoSize = sizeof(osvInfo); // Need to typecast, function takes OSVERSIONINFO GetVersionEx( (OSVERSIONINFO*)&osvInfo ); _tprintf( _T("Windows version: %d.%d\n"), osvInfo.dwMajorVersion, osvInfo.dwMinorVersion); _tprintf( _T("Build: %d\n"), osvInfo.dwBuildNumber); _tprintf( _T("Product Type: ") ); switch(osvInfo.wProductType) { case VER_NT_WORKSTATION: _tprintf( _T("Workstation\n") ); break; case VER_NT_SERVER: _tprintf( _T("Server\n") ); break; case VER_NT_DOMAIN_CONTROLLER: _tprintf( _T("Domain Controller\n") ); break; } }
There are other useful and interesting members of OSVERSIONINFOEX
. Please look and do engineering with them yourself, or read the article link given above.
... But, it doesn't End!
Yes, this probably wont end in near future. I would keep it updated!
Stay Tuned!
History
- Oct 3, 2010 - Initial posting. Date/Time, Username, Computer name, Processor Count, Memory Information and Monitor Resolution explored.
- Oct 6, 2010 - Drives Information
- Oct 7, 2010 - Volume Information, Windows Version