我想检测我正在编译的操作系统是否是 Windows。我可以检查一个简单的宏来验证吗?
10 回答
[编辑:我假设您想使用编译时宏来确定您所在的环境。也许您想确定您是在 Linux 下的 Wine 上运行还是在 Windows 上运行,但一般来说,您的编译器针对特定环境,即 Windows (DOS) 或不是,但很少(从不?) 两个都。]
一些编译器提供宏来指示 Windows 构建环境。但是这些会因编译器而异,如果目标环境不是专门的 Windows,甚至在 Windows 上的相同编译器上也会有所不同。通常是__WIN32__
,但并非总是如此。
#if defined (__WIN32__)
// Windows stuff
#endif
有时它可以是_WIN32
, __CYGWIN32__
,或者可能只是编译器指示符 ( _MSC_VER
)。
如果您知道将要构建的环境(来自 makefile),那么您通常可以在#define
命令行中传入,例如“ g++ -D __WIN32__ yourfile.c
”。
有许多不同的方法可以检测编译、主机和运行时环境。一切都取决于你想知道什么。有三种广泛的环境类型:
- Build:这是编译程序的环境。
- 主机:这是程序运行的环境。
- 目标:对于代码生成工具(例如编译器),这是生成的代码将运行的地方。
如果您是交叉编译,则构建和宿主环境可能完全不同(这在构建嵌入式应用程序时很常见,但在构建桌面/服务器应用程序时并不常见),并且您通常无法在过去的系统上运行编译后的二进制文件编译它。否则,宿主环境必须与构建环境兼容:例如,在 XP 上构建将在 Vista 上运行的应用程序。
C 预处理器宏不能用于告诉您主机系统的详细信息(即您正在运行的系统);他们只能告诉你代码是为了什么而编译的。在 windows 的情况下,两个最重要的宏是:
- _WIN32表示 Win32 API 可用。它不会告诉您您正在使用哪个编译器,实际上 _WIN32 是在使用 Cygwin 的 GCC 和 MinGW 的 GCC 时定义的。因此,不要使用 _WIN32 来确定您是否正在使用 Visual Studio 进行编译。
_MSC_VER
告诉您程序正在使用 Microsoft Visual C/C++ 编译。嗯,差不多。在使用旨在替代 Visual C++ 的英特尔 C++ 编译器时也定义_MSC_VER
了。
Visual Studio 文档中描述了许多其他宏。
如果您想知道您使用的是哪个确切版本的 Windows,则必须使用运行时函数,例如 GetVersion()(如其他答案中所述)。
如果您确切地告诉我们您要检查的内容,您可能会得到更具体的答案。
% touch foo.C ; g++ -dM -E foo.C
将很好地列出您的 [机器特定] g++ 编译器为您自动定义的所有宏(#define's)。
微软的编译器可能有类似的东西......
这三行将帮助您进行检测,首先我们或将大多数预定义的 windows 提示合并到一个 OS_WIN 宏定义中:
#如果定义(_WIN32)|| 定义(WIN32) || 定义(__CYGWIN__)|| 定义(__MINGW32__) || 定义(__BORLANDC__) #define OS_WIN #万一
然后你可以使用预处理器 ifdef 检查它:
#ifdef OS_WIN //Windows特定的东西 #别的 //普通的东西 #万一
如果您正在运行 MS Windows 目标代码,您可以调用 GetVersion() 或 GetVersionEx() 以获取更多信息,并识别您正在运行的 Windows 的变体。
有关更多信息,请查看 MSDN 信息。
http://msdn.microsoft.com/en-us/library/ms724451(VS.85).aspx
MSVC++ 编译器(不是windows.h
)_WIN32
为所有构建定义,因此它是一个更安全的宏检查。MinGW gcc 编译器也可以。任何针对 Win32 的交叉编译环境也应该设置这个。
这个东西在 Visual Studio 2012 和其他 cgwin 的 g++ 编译器中工作。剪切并粘贴它,但它通常尽可能薄它所做的只是检测 Windows 操作系统。只需应用量化:如果没有获胜,那么 *inux :D 享受
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
Using namespace std;
int main(){
char chCap; int i = 0;
const int MAX_BUFFER = 70;
char buffer[MAX_BUFFER];
string cmd="ver";
FILE *stream = _popen(cmd.c_str(), "r");
if (0 != stream){
while (!feof(stream)){
//One way is here
//chCap = fgetc(stream);
//cout << chCap;
//buffer[i++] = chCap;
//This one seams better
fgets(buffer, MAX_BUFFER, stream);
}
_pclose(stream);
}
cout << endl;
cout << buffer << endl;
//The op sys detection starts here
string opSys(buffer); //char array to string
if("Microsoft" == opSys.substr(0,9)){
cout << "You are in a Microsoft envornment " << endl;
}
system("pause");
return 0;
}
到目前为止提到的链接指示编译时的信息。您可以在编译时在这些代码段中设置标志。
但是,我认为您要问的更多是“我在哪个版本的 Windows 下运行?”而不是“我是否编译为在 Windows 下运行?” 我希望这是一个正确的假设。
在C#下,比较简单。您可以参考 System.Environment.OSVersion 然后在“平台”下查看。
但是,您是在询问 C++。你用的是什么编译器?这对于您如何检查操作系统的版本有很大的不同,因为没有单一的标准来获取这些信息(我已经找到)。
在 Visual C++ 下,使用 Google 查找有关 GetVersion/GetVersionEx 的信息。两者都会为您提供包含有关当前运行程序的 Windows 版本的信息的结构。
实际上我会选择环境。getenv() 是一个标准库函数,因此可能是唯一可能实现此目的的可移植方式。诀窍是找出所有操作系统独有的变量。Windows 有 ComSpec、appdata、Windir、systemroot 和 systemdrive 应该设置。您还可以 strstr WINDOWS 或 WINNT 的路径变量,但这可能不准确。我不是 Linux shell/Solaris/MacOS 专家,因此其他人可能能够告诉您这些操作系统中存在哪些“标准”环境变量。CygWin 也可能会给您带来一些问题。
上面列出的宏将告诉您程序是否在(或者更确切地说,用于)Windows 机器上编译,而不是它是否在 Windows 机器上运行。
如果您编写的东西完全与平台无关(即它只处理打开/读取/处理/写入)文件流..您将不得不做一些测试,例如打开一个在计算机运行 Windows 时应该存在的文件。如果您的程序仅使用标准 stdio、数学等。情况就是这样。
否则,如果您的代码包含 Windows 特定的系统调用,它根本不会在任何其他平台上运行。
您可以编写一些宏,例如:
#define RUNNING_ON_WINDOWS ( ... some test )
只是不要将它用于条件编译,即:
if (RUNNING_ON_WINDOWS) {
...
} else
printf("Windows Required\n");