web-dev-qa-db-fra.com

Existe-t-il des macros pour déterminer si mon code est en cours de compilation vers Windows?

Je voudrais détecter si l'OS sur lequel je compile est Windows. Existe-t-il une macro simple que je peux vérifier pour le vérifier?

36
batty

[Edit: Je suppose que vous souhaitez utiliser des macros au moment de la compilation pour déterminer quel environnement vous utilisez. Peut-être que vous voulez déterminer si vous exécutez sur Wine sous Linux ou quelque chose au lieu de Windows, mais en général, votre compilateur cible un environnement spécifique, et c'est soit Windows (DOS) ou ce n'est pas le cas, mais c'est rarement (jamais ?) les deux.]

Certains compilateurs proposent des macros pour indiquer un environnement de build Windows. Mais ceux-ci varient d'un compilateur à l'autre, et même sur le même compilateur sous Windows si l'environnement cible n'est pas exclusivement Windows. C'est généralement __WIN32__, mais pas toujours.

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

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

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

n peu plus d'informations ici

34
phord

Il existe différentes manières de détecter les 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:

  • Build: C'est l'environnement dans lequel le programme est compilé.
  • Host: Il s'agit de l'environnement dans lequel le programme est exécuté.
  • Target: Dans le cas d'outils de génération de code (tels que les compilateurs), c'est là que le code généré s'exécutera.

Si vous effectuez une compilation croisée , l'environnement de génération et l'hôte peuvent être complètement différents (ceci est courant lors de la création d'applications intégrées, mais pas très courant lors de la construction d'un bureau)./server apps), et vous ne pouvez généralement pas exécuter le binaire compilé sur le système utilisé pour le compiler. Sinon, l'environnement Host doit être compatible avec l'environnement de build: par exemple, construire une application sur XP qui s'exécutera sur Vista.

Les macros du préprocesseur C ne peuvent pas être utilisées pour vous indiquer les détails du système hôte (c'est-à-dire sur quoi vous exécutez); ils peuvent seulement vous dire pour quoi le code a été compilé. Dans le cas de Windows, les deux macros les plus importantes sont:

  • _ WIN32 signifie que l'API Win32 est disponible. Il ne pas vous indique quel compilateur vous utilisez, en fait _WIN32 est défini à la fois lorsque vous utilisez GCC de Cygwin et GCC de MinGW. Par conséquent, n'utilisez pas _WIN32 pour déterminer si vous êtes compilé avec Visual Studio.
  • _MSC_VER vous indique que le programme est en cours de compilation avec Microsoft Visual C/C++. Enfin presque. _MSC_VER est également défini lors de l'utilisation du compilateur C++ d'Intel, qui est destiné à remplacer directement 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 vous utilisez, vous devrez utiliser des fonctions d'exécution telles que GetVersion () (comme décrit dans d'autres réponses).

Vous pouvez obtenir des réponses plus précises si vous nous dites exactement ce que vous souhaitez vérifier.

19
JesperE
% touch foo.C ; g++ -dM -E foo.C

Fera un bon travail de listage de toutes les macros (# define's) définies automatiquement pour vous par votre compilateur g ++ [spécifique à la machine].

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

15
Mr.Ree

Cette chose fonctionne dans Visual Studio 2012 et dans le compilateur g ++ de cgwin. Coupez-le et collez-le, mais c'est généralement aussi fin que possible. Tout ce qu'il fait, c'est détecter les systèmes d'exploitation Windows. Il suffit d'appliquer la quantification: sinon gagner alors * 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;    
}
4
Mat-e

Si vous exécutez du code ciblé MS Windows, vous pouvez appeler GetVersion () ou GetVersionEx () pour plus d'informations et pour identifier la variante de Windows sur laquelle vous exécutez.

Pour plus d'informations, consultez les informations MSDN.

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

4
user51241

Le compilateur MSVC++ (pas windows.h) définit _WIN32 pour tous builds, c'est donc une macro plus sûre à vérifier. Le compilateur MinGW gcc fait aussi. Tout environnement de compilation croisée ciblant Win32 devrait définir cela également.

3
j_random_hacker

Les liens mentionnés jusqu'à présent indiquent des informations au moment de la compilation. Vous pouvez définir des indicateurs dans ces segments de code au moment de la compilation.

Cependant, je pense que ce que vous demandez est plus dans le sens de "sous quelle version de Windows suis-je exécuté?" Et non "suis-je compilé pour fonctionner sous Windows?" J'espère que c'est une hypothèse 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 dans la façon dont vous recherchez une version du système d'exploitation, car il n'y a pas de norme unique pour obtenir ces informations (que j'ai trouvées).

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.

3
Jerry

En fait, j'irais avec l'environnement. getenv () est une fonction de bibliothèque standard et est donc 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 d'accès pour WINDOWS ou WINNT mais cela peut ne pas être précis. Je ne suis pas un expert Linux Shell/Solaris/MacOS, donc quelqu'un d'autre pourrait être en mesure de vous dire quelles variables d'environnement "standard" existent dans ces systèmes d'exploitation. CygWin peut également vous causer des problèmes.

2
jmucchiello

Cela dépendrait probablement du compilateur que vous utilisez, mais essayez:

#ifdef WIN32
...
#endif
1
Ates Goral

Des macros telles que celles répertoriées ci-dessus vous indiqueront si votre programme était compilé sur (ou plutôt, pour ) une machine Windows , pas s'il 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) des flux de fichiers .. vous devrez faire un test comme ouvrir un fichier qui devrait exister si l'ordinateur exécute Windows. Si votre programme utilise uniquement stdio standard, mathématiques, 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 )

Ne l'utilisez pas pour la compilation conditionnelle, c'est-à-dire:

if (RUNNING_ON_WINDOWS) {
  ... 
} else 
   printf("Windows Required\n");
1
Tim Post