37

我想检测我正在编译的操作系统是否是 Windows。我可以检查一个简单的宏来验证吗?

4

10 回答 10

35

[编辑:我假设您想使用编译时宏来确定您所在的环境。也许您想确定您是在 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”。

更多信息在这里

于 2009-01-10T02:39:48.953 回答
23

有许多不同的方法可以检测编译、主机和运行时环境。一切都取决于你想知道什么。有三种广泛的环境类型:

  • 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()(如其他答案中所述)。

如果您确切地告诉我们您要检查的内容,您可能会得到更具体的答案。

于 2009-01-10T09:18:36.030 回答
16
% touch foo.C ; g++ -dM -E foo.C

将很好地列出您的 [机器特定] g++ 编译器为您自动定义的所有宏(#define's)。

微软的编译器可能有类似的东西......

于 2009-01-10T04:21:14.817 回答
10

这三行将帮助您进行检测,首先我们或将大多数预定义的 windows 提示合并到一个 OS_WIN 宏定义中:

#如果定义(_WIN32)|| 定义(WIN32) || 定义(__CYGWIN__)|| 定义(__MINGW32__) || 定义(__BORLANDC__)
#define OS_WIN
#万一

然后你可以使用预处理器 ifdef 检查它:

#ifdef OS_WIN
//Windows特定的东西
#别的
//普通的东西
#万一
于 2009-06-19T21:48:18.763 回答
4

如果您正在运行 MS Windows 目标代码,您可以调用 GetVersion() 或 GetVersionEx() 以获取更多信息,并识别您正在运行的 Windows 的变体。

有关更多信息,请查看 MSDN 信息。

http://msdn.microsoft.com/en-us/library/ms724451(VS.85).aspx

于 2009-01-10T02:57:08.077 回答
4

MSVC++ 编译器(不是windows.h_WIN32所有构建定义,因此它是一个更安全的宏检查。MinGW gcc 编译器也可以。任何针对 Win32 的交叉编译环境也应该设置这个。

于 2009-01-10T07:28:48.637 回答
4

这个东西在 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;    
}
于 2012-11-19T07:17:36.287 回答
3

到目前为止提到的链接指示编译时的信息。您可以在编译时在这些代码段中设置标志。

但是,我认为您要问的更多是“我在哪个版本的 Windows 下运行?”而不是“我是否编译为在 Windows 下运行?” 我希望这是一个正确的假设。

在C#下,比较简单。您可以参考 System.Environment.OSVersion 然后在“平台”下查看。

但是,您是在询问 C++。你用的是什么编译器?这对于您如何检查操作系统的版本有很大的不同,因为没有单一的标准来获取这些信息(我已经找到)。

在 Visual C++ 下,使用 Google 查找有关 GetVersion/GetVersionEx 的信息。两者都会为您提供包含有关当前运行程序的 Windows 版本的信息的结构。

于 2009-01-10T02:53:45.493 回答
2

实际上我会选择环境。getenv() 是一个标准库函数,因此可能是唯一可能实现此目的的可移植方式。诀窍是找出所有操作系统独有的变量。Windows 有 ComSpec、appdata、Windir、systemroot 和 systemdrive 应该设置。您还可以 strstr WINDOWS 或 WINNT 的路径变量,但这可能不准确。我不是 Linux shell/Solaris/MacOS 专家,因此其他人可能能够告诉您这些操作系统中存在哪些“标准”环境变量。CygWin 也可能会给您带来一些问题。

于 2009-01-10T05:05:58.020 回答
1

上面列出的宏将告诉您程序是否在(或者更确切地说,用于)Windows 机器上编译,而不是它是否在 Windows 机器上运行

如果您编写的东西完全与平台无关(即它只处理打开/读取/处理/写入)文件流..您将不得不做一些测试,例如打开一个在计算机运行 Windows 时应该存在的文件。如果您的程序仅使用标准 stdio、数学等。情况就是这样。

否则,如果您的代码包含 Windows 特定的系统调用,它根本不会在任何其他平台上运行。

您可以编写一些宏,例如:

#define RUNNING_ON_WINDOWS ( ... some test )

只是不要将它用于条件编译,即:

if (RUNNING_ON_WINDOWS) {
  ... 
} else 
   printf("Windows Required\n");
于 2009-01-10T02:49:48.467 回答