您的位置:首页 > 编程语言

跟Google学写代码--Chromium/base--windows_version源码学习及应用

2016-12-11 23:18 555 查看
Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。

前面写道:

跟Google学写代码–Chromium/base–stl_util源码学习及应用

今天与大家分享的就是Chromium下base中的windows_version,对于你的win32应用程序一定会有很多的帮助。

1 定义version枚举

enum Version {
VERSION_PRE_XP = 0,  // Not supported.
VERSION_XP,
VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
VERSION_VISTA,       // Also includes Windows Server 2008.
VERSION_WIN7,        // Also includes Windows Server 2008 R2.
VERSION_WIN8,        // Also includes Windows Server 2012.
VERSION_WIN8_1,      // Code named Windows Blue
VERSION_WIN_LAST,    // Indicates error condition.
};


enum VersionType {
SUITE_HOME,
SUITE_PROFESSIONAL,
SUITE_SERVER,
SUITE_LAST,
};


2 定义 OSInfo类

a. 通过BASE_EXPORT定义为导出类

b. 将OSInfo()和 ~OSInfo()声明为私有,即我们要的单例模式

class BASE_EXPORT OSInfo {
public:
struct VersionNumber {
int major;
int minor;
int build;
};

struct ServicePack {
int major;
int minor;
};

enum WindowsArchitecture {
X86_ARCHITECTURE,
X64_ARCHITECTURE,
IA64_ARCHITECTURE,
OTHER_ARCHITECTURE,
};

enum WOW64Status {
WOW64_DISABLED,
WOW64_ENABLED,
WOW64_UNKNOWN,
};

static OSInfo* GetInstance();

Version version() const { return version_; }
VersionNumber version_number() const { return version_number_; }
VersionType version_type() const { return version_type_; }
ServicePack service_pack() const { return service_pack_; }
WindowsArchitecture architecture() const { return architecture_; }
int processors() const { return processors_; }
size_t allocation_granularity() const { return allocation_granularity_; }
WOW64Status wow64_status() const { return wow64_status_; }
std::string processor_model_name();

static WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);

private:
OSInfo();
~OSInfo();

Version version_;
VersionNumber version_number_;
VersionType version_type_;
ServicePack service_pack_;
WindowsArchitecture architecture_;
int processors_;
size_t allocation_granularity_;
WOW64Status wow64_status_;
std::string processor_model_name_;

DISALLOW_COPY_AND_ASSIGN(OSInfo);
};

// Because this is by far the most commonly-requested value from the above
// singleton, we add a global-scope accessor here as syntactic sugar.
BASE_EXPORT Version GetVersion();

}  // namespace win
}  // namespace base


3 GetInstance()的实现

这里用到了InterlockedCompareExchangePointer:

Provides compiler intrinsic support for the Win32 Platform SDK InterlockedCompareExchangePointer function.

OSInfo* OSInfo::GetInstance() {
static OSInfo* info;
if (!info) {
OSInfo* new_info = new OSInfo();
if (InterlockedCompareExchangePointer(
reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
delete new_info;
}
}
return info;
}


这里补充一下,delete new_info后,最好把new_info置为nullptr。

4 获取WOW64状态的实现

最主要的是这行:

GetProcAddress(GetModuleHandle(L”kernel32.dll”), “IsWow64Process”));

可以通过加载Kernel32来动态判断 当前操作系统32bit还是64bit。

OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) {
typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
if (!is_wow64_process)
return WOW64_DISABLED;
BOOL is_wow64 = FALSE;
if (!(*is_wow64_process)(process_handle, &is_wow64))
return WOW64_UNKNOWN;
return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
}


应用:

简单的使用:

int main(int argc, char* argv[]) {

int version = base::win::OSInfo::GetInstance()->version();
std::cout << "VERSION_PRE_XP = 0," << std::endl;
std::cout << "VERSION_SERVER_2003 = 1," << std::endl;
std::cout << "VERSION_VISTA = 2," << std::endl;
std::cout << "VERSION_WIN7 = 3," << std::endl;
std::cout << "VERSION_WIN8 = 4," << std::endl;
std::cout << "VERSION_WIN8_1 = 5," << std::endl;
std::cout << "VERSION_WIN_LAST = 6," << std::endl;
std::cout << "My Windows Version is: " << version << std::endl << std::endl;

std::string processor_model_name = base::win::OSInfo::GetInstance()->processor_model_name();
std::cout << "My Processor Model Name is: " << processor_model_name << std::endl << std::endl;

int wow64_status = base::win::OSInfo::GetInstance()->wow64_status();
std::cout << "WOW64_DISABLED = 0," << std::endl;
std::cout << "WOW64_ENABLED = 1," << std::endl;
std::cout << "WOW64_UNKNOWN = 2," << std::endl;
std::cout << "My wow64_status is: " << wow64_status << std::endl << std::endl;

base::win::OSInfo::VersionNumber version_number = base::win::OSInfo::GetInstance()->version_number();
std::cout << "My Version Number: " << std::endl;
std::cout << " major: " << version_number.major << std::endl;
std::cout << " minor: " << version_number.minor << std::endl;
std::cout << " build: " << version_number.build << std::endl;

system("pause");
return 0;
}


输出结果:

VERSION_PRE_XP = 0,
VERSION_SERVER_2003 = 1,
VERSION_VISTA = 2,
VERSION_WIN7 = 3,
VERSION_WIN8 = 4,
VERSION_WIN8_1 = 5,
VERSION_WIN_LAST = 6,
My Windows Version is: 5

My Processor Model Name is: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz

WOW64_DISABLED = 0,
WOW64_ENABLED = 1,
WOW64_UNKNOWN = 2,
My wow64_status is: 1

My Version Number:
major: 6
minor: 2
build: 9200


插曲 一个坑儿:



一个VS中有好几个工程,在运行我们想要运行的项目的时候,出现上图中的错误。

如果你不够细心,你就以为是库的版本不对,比如库是64位,而你运行的是32位程序。。。。。。

但是你看编译库的工程也是32位的,这时候就有点发蒙。。。。。

蓦然回首,你没有把想要运行的程序设置为启动项,而且把那个库的工程设置为了启动项。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: