获取 Windows 体系结构(32/64 位版本)
Posted
技术标签:
【中文标题】获取 Windows 体系结构(32/64 位版本)【英文标题】:Getting Architecture of Windows (32/64 bit version) 【发布时间】:2011-03-11 22:19:39 【问题描述】:我遇到了一个小问题:
我想得到操作系统的架构,问题是我的编程语言不支持这些功能。因此,我需要从 Windows dll(如 kernel32.dll)中读取此信息
我确实尝试使用函数GetNativeSystemInfo/GetVersionEx/GetSystemInfo
获取信息。
不幸的是,我无法获得架构:/
是否有其他函数可以读取任何 Windows dll 中的体系结构? (它不需要是kernel32它可以是任何dll但它必须存在于win xp+中)
作为信息:我正在使用 Gupta (SQLWindows/Team devoloper)
编辑1:
typedef struct _SYSTEM_INFO
union
DWORD dwOemId;
struct
WORD wProcessorArchitecture;
WORD wReserved;
;
;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
SYSTEM_INFO;
这是来自MSDN 的信息,我尝试使用 10 和 12 参数调用此函数 (Gupta 不支持结构)。 在 32 位上我得到:alt text http://img714.imageshack.us/img714/1954/32bit.gif
在 64 位上我得到:alt text http://img691.imageshack.us/img691/8978/64bit.gif
我每次都会在 32 位上获得 0
OemID 吗?或者更好的是在 64 位版本的 windows 上填充 OemID everytiem?
谢谢帮助!!
问候 奥罗
【问题讨论】:
【参考方案1】:我觉得你是这样的,
BOOL SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo)
BOOL bRet = FALSE;
do
if (lpSystemInfo == NULL)
break;
typedef void(WINAPI *GetNativeSystemInfoProc) (LPSYSTEM_INFO lpSystemInfo);
GetNativeSystemInfoProc pFun = (GetNativeSystemInfoProc)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetNativeSystemInfo");
if (NULL != pFun)
pFun(lpSystemInfo);
else
GetSystemInfo(lpSystemInfo);
bRet = TRUE;
while (FALSE);
return bRet;
BOOL GetOSDisplayString( LPTSTR pszOS)
GRS_USEPRINTF();
OSVERSIONINFOEX osvi = sizeof(OSVERSIONINFOEX);
SYSTEM_INFO si = ;
BOOL bOsVersionInfoEx;
DWORD dwType;
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
return FALSE;
//GetSystemInfo(&si);
if (SafeGetNativeSystemInfo(&si) == FALSE)
return FALSE;
if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4 )
StringCchCopy(pszOS, BUFSIZE, _T("Microsoft "));
if ( osvi.dwMajorVersion == 6 )
if( 0 == osvi.dwMinorVersion )
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, _T("Windows Vista "));
else
StringCchCat(pszOS, BUFSIZE, _T("Windows Server 2008 " ));
else if( 1 == osvi.dwMinorVersion )
if( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, _T("Windows 7 "));
else
StringCchCat(pszOS, BUFSIZE, _T("Windows Unknown "));
else
StringCchCat(pszOS, BUFSIZE, _T("Windows Unknown "));
GetProductInfo( 6, 0, 0, 0, &dwType);
switch( dwType )
case PRODUCT_ULTIMATE:
StringCchCat(pszOS, BUFSIZE, _T("Ultimate Edition" ));
break;
case PRODUCT_HOME_PREMIUM:
StringCchCat(pszOS, BUFSIZE, _T("Home Premium Edition" ));
break;
case PRODUCT_HOME_BASIC:
StringCchCat(pszOS, BUFSIZE, _T("Home Basic Edition" ));
break;
case PRODUCT_ENTERPRISE:
StringCchCat(pszOS, BUFSIZE, _T("Enterprise Edition" ));
break;
case PRODUCT_BUSINESS:
StringCchCat(pszOS, BUFSIZE, _T("Business Edition" ));
break;
case PRODUCT_STARTER:
StringCchCat(pszOS, BUFSIZE, _T("Starter Edition" ));
break;
case PRODUCT_CLUSTER_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Cluster Server Edition" ));
break;
case PRODUCT_DATACENTER_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Datacenter Edition" ));
break;
case PRODUCT_DATACENTER_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, _T("Datacenter Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Enterprise Edition" ));
break;
case PRODUCT_ENTERPRISE_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, _T("Enterprise Edition (core installation)" ));
break;
case PRODUCT_ENTERPRISE_SERVER_IA64:
StringCchCat(pszOS, BUFSIZE, _T("Enterprise Edition for Itanium-based Systems" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Small Business Server" ));
break;
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
StringCchCat(pszOS, BUFSIZE, _T("Small Business Server Premium Edition" ));
break;
case PRODUCT_STANDARD_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Standard Edition" ));
break;
case PRODUCT_STANDARD_SERVER_CORE:
StringCchCat(pszOS, BUFSIZE, _T("Standard Edition (core installation)" ));
break;
case PRODUCT_WEB_SERVER:
StringCchCat(pszOS, BUFSIZE, _T("Web Server Edition" ));
break;
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
StringCchCat(pszOS, BUFSIZE, _T( ", 64-bit" ));
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
StringCchCat(pszOS, BUFSIZE, _T(", 64-bit"));
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64)
StringCchCat(pszOS, BUFSIZE, _T(", 64-bit"));
else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
StringCchCat(pszOS, BUFSIZE, _T(", 32-bit"));
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
if( GetSystemMetrics(SM_SERVERR2) )
StringCchCat(pszOS, BUFSIZE, _T( "Windows Server 2003 R2, "));
else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
StringCchCat(pszOS, BUFSIZE, _T( "Windows Storage Server 2003"));
else if( osvi.wProductType == VER_NT_WORKSTATION &&
si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
StringCchCat(pszOS, BUFSIZE, _T( "Windows XP Professional x64 Edition"));
else
StringCchCat(pszOS, BUFSIZE, _T("Windows Server 2003, "));
if ( osvi.wProductType != VER_NT_WORKSTATION )
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, _T( "Datacenter Edition for Itanium-based Systems" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, _T( "Enterprise Edition for Itanium-based Systems" ));
else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, _T( "Datacenter x64 Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, _T( "Enterprise x64 Edition" ));
else
StringCchCat(pszOS, BUFSIZE, _T( "Standard x64 Edition" ));
else
if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
StringCchCat(pszOS, BUFSIZE, _T( "Compute Cluster Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, _T( "Datacenter Edition" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, _T( "Enterprise Edition" ));
else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
StringCchCat(pszOS, BUFSIZE, _T( "Web Edition" ));
else
StringCchCat(pszOS, BUFSIZE, _T( "Standard Edition" ));
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
StringCchCat(pszOS, BUFSIZE, _T("Windows XP "));
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
StringCchCat(pszOS, BUFSIZE, _T( "Home Edition" ));
else
StringCchCat(pszOS, BUFSIZE, _T( "Professional" ));
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
StringCchCat(pszOS, BUFSIZE, _T("Windows 2000 "));
if ( osvi.wProductType == VER_NT_WORKSTATION )
StringCchCat(pszOS, BUFSIZE, _T( "Professional" ));
else
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
StringCchCat(pszOS, BUFSIZE, _T( "Datacenter Server" ));
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
StringCchCat(pszOS, BUFSIZE, _T( "Advanced Server" ));
else
StringCchCat(pszOS, BUFSIZE, _T( "Server" ));
// Include service pack (if any) and build number.
if( _tcslen(osvi.szCSDVersion) > 0 )
StringCchCat(pszOS, BUFSIZE, _T(" ") );
StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
TCHAR buf[80];
StringCchPrintf( buf, 80, _T(" (build %d)"), osvi.dwBuildNumber);
StringCchCat(pszOS, BUFSIZE, buf);
return TRUE;
else
GRS_PRINTF(_T( "This sample does not support this version of Windows.\n") );
return FALSE;
【讨论】:
【参考方案2】:GetNativeSystemInfo
绝对是要使用的功能。如果您的应用是原生 64 位应用,GetNativeSystemInfo
与 GetSystemInfo
相同;否则,如果它在 WOW64 下运行,它将返回真实的系统属性,即使它是在模拟的 32 位环境中运行的。
GetNativeSystemInfo
填充了一个SYSTEM_INFO
结构,其中的wProcessorArchitecture
成员告诉您系统是32 位(可能是PROCESSOR_ARCHITECTURE_INTEL
)还是64 位(可能是PROCESSOR_ARCHITECTURE_AMD64
)。
如果你的语言没有这个 Win API 函数的包装器,要使用它,你可以像往常一样使用LoadLibrary
和GetProcAddress
,当然你需要定义SYSTEM_INFO
结构。
更新
我会定义
typedef struct _SYSTEM_INFO
WORD wProcessorArchitecture;
WORD wReserved;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
SYSTEM_INFO;
然后wProcessorArchitecture = 0
在(通用)32 位系统上,wProcessorArchitecture = 9
在(通用)64 位系统上。这些只是常量PROCESSOR_ARCHITECTURE_INTEL
和PROCESSOR_ARCHITECTURE_AMD64
,分别。这些是常见的 32 位和 64 位架构。 PROCESSOR_ARCHITECTURE_IA64 = 6
稍微不常见,PROCESSOR_ARCHITECTURE_UNKNOWN = 65535
肯定也是如此。
更新
是的,我看到了你的问题。在 C 中,union
表示您一次选择 一个 选项。也就是说,结构要么是
DWORD dwOemId;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
或
WORD wProcessorArchitecture;
WORD wReserved;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
因为一个 DWORD 包含与两个字 (2×2) 一样多的字节 (4),所以替代方案只是寻址(和命名)整个结构的数据的两种方式。在我们的例子中,我们更感兴趣的是 wProcessorArchitecture
词,而不是 wProcessorArchitecture
的扩充 dwOemId
和完全无趣的 wReserved
词。
【讨论】:
看起来我不能使用 GetNativeSystemInfo 因为它不清晰可读。有没有办法从注册表中读取它?我不确定 HKLM\Sorftware\Microsoft\Windows NT\currentVersion\BuildLabEx 是否保存... 啊,现在它完美运行了:D 是的,问题是我确实以错误的方式调用了 Kernel32 中的函数......谢谢你的帮助!以上是关于获取 Windows 体系结构(32/64 位版本)的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL Developer从11.0.6版本开始32/64为之区分
XP,32/64位Win7,32/64位Win8,32/64位Win10系统 春节版