【问题标题】:Getting Architecture of Windows (32/64 bit version)获取 Windows 体系结构(32/64 位版本)
【发布时间】: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?

谢谢帮助!!

问候
奥罗

【问题讨论】:

    标签: windows architecture kernel32


    【解决方案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 中的函数......谢谢你的帮助!
      猜你喜欢
      • 2010-12-23
      • 2013-12-14
      • 2016-12-25
      • 2015-01-18
      • 1970-01-01
      • 2021-07-08
      • 2010-10-10
      • 2012-10-26
      • 2020-10-28
      相关资源
      最近更新 更多