[英]Getting Windows OS version programmatically
我正在嘗試在我的 Windows 10 機器上使用 C# 獲取 Windows 版本。
我總是得到這些值(使用 C#\\C++):
專業:6
未成年人:2
根據 MSDN ,這是 Windows 8 操作系統
C#代碼:
var major = OperatingSystem.Version.Major
var minor = OperatingSystem.Version.Minor
C++代碼
void print_os_info()
{
//http://stackoverflow.com/questions/1963992/check-windows-version
OSVERSIONINFOW info;
ZeroMemory(&info, sizeof(OSVERSIONINFOW));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
LPOSVERSIONINFOW lp_info = &info;
GetVersionEx(lp_info);
printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);
}
Windows 10 假設與那些:
專業:10
次要:0*
構建者:10.0.10586.0 (th2_release.151029-1700)
我在這里缺少什么?
在我的場景中,我需要我的應用程序來捕獲計算機信息以獲取可能的錯誤報告和統計信息。
我沒有找到必須令人滿意地添加應用程序清單的解決方案。 不幸的是,我在谷歌搜索時發現的大多數建議都表明了這一點。
事實是,在使用清單時,必須手動向其中添加每個操作系統版本,以便該特定操作系統版本能夠在運行時報告自身。
換句話說,這變成了一種競爭條件:我的應用程序的用戶很可能正在使用我的應用程序的一個版本,該版本早於正在使用的操作系統。 當 Microsoft 推出新的操作系統版本時,我必須立即升級該應用程序。 我還必須強制用戶在更新操作系統的同時升級應用程序。
換句話說,不太可行。
在瀏覽選項后,我發現了一些建議使用注冊表查找的參考(與應用程序清單相比出奇地少)。
我只有WinMajorVersion
、 WinMinorVersion
和IsServer
屬性的我的(砍掉的) ComputerInfo
類如下所示:
using Microsoft.Win32;
namespace Inspection
{
/// <summary>
/// Static class that adds convenient methods for getting information on the running computers basic hardware and os setup.
/// </summary>
public static class ComputerInfo
{
/// <summary>
/// Returns the Windows major version number for this computer.
/// </summary>
public static uint WinMajorVersion
{
get
{
dynamic major;
// The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10,
// and will most likely (hopefully) be there for some time before MS decides to change this - again...
if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major))
{
return (uint) major;
}
// When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion'
dynamic version;
if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version))
return 0;
var versionParts = ((string) version).Split('.');
if (versionParts.Length != 2) return 0;
uint majorAsUInt;
return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0;
}
}
/// <summary>
/// Returns the Windows minor version number for this computer.
/// </summary>
public static uint WinMinorVersion
{
get
{
dynamic minor;
// The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10,
// and will most likely (hopefully) be there for some time before MS decides to change this - again...
if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber",
out minor))
{
return (uint) minor;
}
// When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion'
dynamic version;
if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version))
return 0;
var versionParts = ((string) version).Split('.');
if (versionParts.Length != 2) return 0;
uint minorAsUInt;
return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0;
}
}
/// <summary>
/// Returns whether or not the current computer is a server or not.
/// </summary>
public static uint IsServer
{
get
{
dynamic installationType;
if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType",
out installationType))
{
return (uint) (installationType.Equals("Client") ? 0 : 1);
}
return 0;
}
}
private static bool TryGetRegistryKey(string path, string key, out dynamic value)
{
value = null;
try
{
using(var rk = Registry.LocalMachine.OpenSubKey(path))
{
if (rk == null) return false;
value = rk.GetValue(key);
return value != null;
}
}
catch
{
return false;
}
}
}
}
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuildNumber", string.Empty).ToString()
從 XP 到當前 10.16299 的所有操作系統的相同代碼,在 Windows 8 中無法正常工作的情況下
OSVersion 屬性報告 Windows 8 和 Windows 8.1 的相同版本號 (6.2.0.0) 以及 Windows 10 的相同主要和次要版本號。
https://msdn.microsoft.com/library/system.environment.osversion.aspx
由於接受的答案僅適用於 C#,這里是 C++ 的解決方案。
它使用 ntdll.dll 中的 RtlGetVersion 使用與 GetVersionEx 相同的結構(名稱不同,但元素相同)並為您提供正確的版本。 由於此函數通常用於驅動程序開發,因此該函數是在 DDK 中聲明的,而不是在 SDK 中聲明的。 所以我使用了動態解決方案來調用函數。 請注意,ntdll.dll 在每次調用中都會被加載和釋放。 因此,如果您更頻繁地需要該功能,請保持庫加載。
pOSversion 指向的結構必須像 GetVersionEx 一樣初始化。
BOOL GetTrueWindowsVersion(OSVERSIONINFOEX* pOSversion)
{
// Function pointer to driver function
NTSTATUS (WINAPI *pRtlGetVersion)(
PRTL_OSVERSIONINFOW lpVersionInformation) = NULL;
// load the System-DLL
HINSTANCE hNTdllDll = LoadLibrary("ntdll.dll");
// successfully loaded?
if (hNTdllDll != NULL)
{
// get the function pointer to RtlGetVersion
pRtlGetVersion = (NTSTATUS (WINAPI *)(PRTL_OSVERSIONINFOW))
GetProcAddress (hNTdllDll, "RtlGetVersion");
// if successfull then read the function
if (pRtlGetVersion != NULL)
pRtlGetVersion((PRTL_OSVERSIONINFOW)pOSversion);
// free the library
FreeLibrary(hNTdllDll);
} // if (hNTdllDll != NULL)
// if function failed, use fallback to old version
if (pRtlGetVersion == NULL)
GetVersionEx((OSVERSIONINFO*)pOSversion);
// always true ...
return (TRUE);
} // GetTrueWindowsVersion
您可以在 C# 中以與 C++ 回答相同的方式執行此操作
[SecurityCritical]
[DllImport("ntdll.dll", SetLastError = true)]
internal static extern bool RtlGetVersion(ref OSVERSIONINFOEX versionInfo);
[StructLayout(LayoutKind.Sequential)]
internal struct OSVERSIONINFOEX
{
// The OSVersionInfoSize field must be set to Marshal.SizeOf(typeof(OSVERSIONINFOEX))
internal int OSVersionInfoSize;
internal int MajorVersion;
internal int MinorVersion;
internal int BuildNumber;
internal int PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string CSDVersion;
internal ushort ServicePackMajor;
internal ushort ServicePackMinor;
internal short SuiteMask;
internal byte ProductType;
internal byte Reserved;
}
...
var osVersionInfo = new OSVERSIONINFOEX { OSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)) };
if (!RtlGetVersion(ref osVersionInfo))
{
// TODO: Error handling, call GetVersionEx, etc.
}
您可以通過代碼從注冊表中讀取並按照您的意圖執行特定操作。
比如說:
注冊表項位於 HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion,然后查找“ProductName”。
您可以通過在運行中提供 regedit.exe 來打開注冊表信息 (Windows+r)
var reg =Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\WindowsNT\CurrentVersion");
string productName = (string)reg.GetValue("ProductName");
if (productName.StartsWith("Windows 10"))
{
}
else
{
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.