2009-01-10 8 views
34

Je voudrais savoir si le système d'exploitation sur lequel je compile est Windows. Y a-t-il une simple macro que je peux vérifier pour vérifier cela?Y a-t-il des macros pour déterminer si mon code est compilé sous Windows?

+1

Vous pouvez préciser si vous voulez savoir de Windows vs Linux vs Mac OS X par rapport à tout ou si vous voulez connaître Windows XP vs Windows Vista par rapport à quoi que ce soit. –

Répondre

31

[Edit: Je suppose que vous voulez utiliser des macros de compilation pour déterminer quel environnement vous êtes. Peut-être voulez-vous déterminer si vous utilisez Wine sous Linux ou quelque chose au lieu de Windows, mais en général, votre compilateur cible un environnement spécifique, Windows (DOS) ou non, mais rarement (jamais ?) les deux.]

Certains compilateurs offrent des macros pour indiquer un environnement de construction Windows. Mais ceux-ci vont varier du compilateur au compilateur, et même sur le même compilateur sous Windows si l'environnement cible est et non exclusivement windows. Habituellement, c'est __WIN32__, mais pas toujours.

#if defined (__WIN32__) 
    // Windows stuff 
#endif 

Parfois, il peut être _WIN32, __CYGWIN32__, ou peut-être juste l'indicateur du compilateur (_MSC_VER).

Si vous connaissez l'environnement dans lequel vous allez construire (à partir du fichier makefile), vous pouvez généralement passer le #define sur la ligne de commande, comme "g++ -D __WIN32__ yourfile.c".

A little more info here

0

Il dépendra probablement du compilateur que vous utilisez, mais essayez:

#ifdef WIN32 
... 
#endif 
+0

Ce qui vous indique si vous êtes _compiling_ sur windows. La question dit "en cours d'exécution", bien qu'il ne soit pas clair si l'OP écrit ce qu'il veut dire ... – dmckee

+0

Soyez prudent, car cela ne peut être défini que si vous incluez windows.h. –

+0

Le compilateur MSVC++ (pas windows.h) définit _WIN32 pour les versions * all *, c'est donc une macro plus sûre à vérifier. Tout environnement de compilation croisée qui cible Win32 doit également le définir. –

0

macros telles que celles énumérées ci-dessus vous dira si vous programme a été compilé sur une machine Windows, pas si elle est en cours d'exécution sur une machine Windows. Si vous écrivez quelque chose qui est complètement indépendant de la plate-forme (c'est-à-dire qu'il ne gère que l'ouverture/la lecture/le traitement/l'écriture), vous devrez effectuer un test comme ouvrir un fichier . Si votre programme n'utilise que des standards stdio, maths, etc., ce sera le cas. Sinon, si votre code contient des appels système spécifiques à Windows, il ne fonctionnera tout simplement pas sur une autre plate-forme.

Vous pouvez écrire une macro comme:

#define RUNNING_ON_WINDOWS (... some test) 

Il suffit de ne pas l'utiliser pour la compilation conditionnelle, i.e. .:

if (RUNNING_ON_WINDOWS) { 
    ... 
} else 
    printf("Windows Required\n"); 
+2

Les constantes du préprocesseur * peuvent * être approuvées. Même si vous effectuez une compilation croisée par ex. gcc sur une machine Linux, l'environnement de compilation croisée fournira des constantes de préprocesseur indiquant l'environnement * runtime * prévu. –

2

Les liens mentionnés indiquent à ce jour des informations au moment de la compilation. Vous pouvez définir des indicateurs dans ces segments de code lors de la compilation.

Cependant, je pense que ce que vous demandez est plus sur les lignes de "Quelle version de Windows suis-je en cours d'exécution?" Pas "Suis-je compilé pour fonctionner sous Windows?" J'espère que c'est une supposition correcte.

Sous C#, c'est relativement simple. Vous pouvez référencer System.Environment.OSVersion puis regarder sous "Platform".

Cependant, vous posez des questions sur C++. Quel compilateur utilisez-vous?Cela fait une grande différence sur la façon dont vous vérifiez une version du système d'exploitation, car il n'y a pas de standard unique pour obtenir cette information (que j'ai trouvé). Sous Visual C++, utilisez Google pour trouver des informations sur GetVersion/GetVersionEx. Les deux vous donneront des structures qui contiennent des informations sur la version actuelle de Windows sous laquelle le programme s'exécute.

13
% touch foo.C ; g++ -dM -E foo.C 

fera un bon travail de la liste de toutes les macros (#define de) automagiquement définies pour vous par votre [machine spécifique] compilateur g ++.

Il pourrait y avoir quelque chose de similaire pour les compilateurs de Microsoft ...

+5

Ou tout simplement gcc -E -xc -dM/dev/null » si vous ne voulez pas laisser un fichier temporaire derrière (remplacer' '-xc' avec -xC++' pour les macros utilisées avec C++ au lieu de C). –

1

En fait, je voudrais aller avec l'environnement. getenv() est une fonction de bibliothèque standard et est probablement le seul moyen potentiellement portable de le faire. L'astuce consiste à déterminer quelles variables sont uniques à tous les systèmes d'exploitation. Windows a ComSpec, appdata, Windir, systemroot et systemdrive qui doivent être définis. Vous pouvez également strstr la variable de chemin pour WINDOWS ou WINNT mais cela peut ne pas être exact. Je ne suis pas un expert Linux/Solaris/MacOS pour que quelqu'un d'autre puisse vous dire quelles variables d'environnement "standard" existent dans ces OS. CygWin peut aussi vous causer des problèmes.

2

Le MSVC++ compilateur (non windows.h) définit _WIN32 pour tous builds, il est donc plus sûr macro pour vérifier. Le compilateur gcc MinGW le fait aussi. Tout environnement de compilation croisée qui cible Win32 doit également définir.

17

Il existe plusieurs méthodes de détection des environnements de compilation, d'hôte et d'exécution. Tout dépend exactement de ce que vous voulez savoir. Il existe trois grands types d'environnements:

  • Construire: Ceci est l'environnement dans lequel le programme est compilé.
  • Hôte: Il s'agit de l'environnement dans lequel le programme est exécuté.
  • Cible: Dans le cas d'outils de génération de code (tels que des compilateurs), c'est là que le code généré s'exécutera.

Si vous êtes compilation croisée, l'environnement de construction et l'hôte peut être complètement différent (ce qui est commun lors de la construction des applications embarquées, mais pas très commun lors de la construction de bureau/applications de serveur), et vous généralement ne pouvez pas exécuter le binaire compilé sur le système utilisé pour le compiler. Sinon, l'environnement hôte doit être compatible avec l'environnement de construction: par exemple, construire une application sur XP qui fonctionnera sur Vista. C Les macros de préprocesseur C ne peuvent pas être utilisées pour vous indiquer les détails du système hôte (c'est-à-dire ce que vous utilisez); ils peuvent seulement vous dire à quoi le code a été compilé.Dans le cas des fenêtres, les deux macros les plus importantes sont les suivantes:

  • _WIN32 signifie que l'API Win32 est disponible. Il ne pas vous dire quel compilateur vous utilisez, en fait _WIN32 est défini à la fois lors de l'utilisation de GCC de Cygwin et GCC de MinGW. Donc, n'utilisez pas _WIN32 pour savoir si vous êtes compilé avec Visual Studio.
  • _MSC_VER vous indique que le programme est en cours de compilation avec Microsoft Visual C/C++. Eh bien, presque. _MSC_VER est également défini lors de l'utilisation de C++ d'Intel compilateur qui est destiné à être un remplacement de drop-in pour Visual C++.

Il existe un tas d'autres macros décrites dans la documentation de Visual Studio.

Si vous voulez savoir quelle version exacte de Windows que vous utilisez, vous devrez utiliser les fonctions d'exécution telles que GetVersion() (comme décrit dans d'autres réponses).

Vous pourriez obtenir des réponses plus précises si vous nous avez dit exactement ce que vous voulez vérifier.

+2

Cygwin GCC ne définit que _ _WIN32' lors de la compilation d'une application Win32 (qui n'est pas une application Cygwin), ce qui le fait fonctionner comme un compilateur MinGW, ce qui fait que '_WIN32' est une bonne vérification du système d'exploitation. – rubenvb

5

Ces trois lignes vous aider à la détection, d'abord nous ou la plupart des fenêtres prédéfinies conseils en une seule OS_WIN définition macro:

 
#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) 
#define OS_WIN 
#endif 

Ensuite, vous pouvez vérifier à l'aide du ifdef préprocesseur:

 
#ifdef OS_WIN 
//Windows specific stuff 
#else 
//Normal stuff 
#endif 
+2

Cygwin! = Win32. – rubenvb

+0

@rubenvb: vous voulez aussi commenter votre autre downvote? Je ne comprends pas - encore – sehe

+1

Eh bien, il n'y a vraiment qu'une seule "bonne" macro à vérifier, étant '_WIN32'. Je downvoted celui-ci parce que, Cygwin, n'est pas Windows. Bien que vous puissiez lier à msvcrt.dll, Cygwin n'est pas conçu pour cela. C'est un environnement complètement différent. 'WIN32' ou' __WIN32__' ne sont décrits nulle part sur msdn.com, et la lecture de toutes les macros prédéfinies en sortie par 'gcc -dM -E' n'aide pas du tout à obtenir ceux qui sont seulement dépendants du système d'exploitation, ce qui est la question. – rubenvb

3

Cette chose fonctionne en studio visuel 2012, et autre le compilateur ++ de cgwin g. Coupez et collez autour mais cela est généralement aussi mince qu'il obtient Tout ce qu'il fait est de détecter les systèmes Windows op. Il suffit d'appliquer la quantification: Sinon gagner Puis * inux : D profiter

#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;  
} 
+3

C'est exagéré. Tout ce qui suit '_popen' n'est pas nécessaire. Si '_popen' compile, c'est une plate-forme Microsoft, sinon ce n'est pas le cas. – MSalters

+0

@ Mat-e S'il utilisait les commandes popen et pclose, qui fonctionnent sur MinGW, vous pourriez obtenir un faux positif d'une commande utilisateur ver. – user877329

Questions connexes