获取 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 位应用,GetNativeSystemInfoGetSystemInfo 相同;否则,如果它在 WOW64 下运行,它将返回真实的系统属性,即使它是在模拟的 32 位环境中运行的。

GetNativeSystemInfo 填充了一个SYSTEM_INFO 结构,其中的wProcessorArchitecture 成员告诉您系统是32 位(可能是PROCESSOR_ARCHITECTURE_INTEL)还是64 位(可能是PROCESSOR_ARCHITECTURE_AMD64)。

如果你的语言没有这个 Win API 函数的包装器,要使用它,你可以像往常一样使用LoadLibraryGetProcAddress,当然你需要定义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_INTELPROCESSOR_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为之区分

Windows 8 堆随机化

如何在windows服务器中使用syslog功能

XP,32/64位Win7,32/64位Win8,32/64位Win10系统 春节版

微软C++编译器太烦人了!是不是有为 Windows 32/64 位编译的替代方法?

nvm 指令