3

I have a windows application that should run in XP and above. But Windows API for XP is usually different from vista and above. What conditional compilation flags can I check to determine which windows OS the code is being compiled for? If not, is there any way to achieve this?

I think it should look something like this:

void SomeClass::SomeFunction()
{
    // Other code

#ifdef WINXP
    windowsXPCall();
#else
    WindowsCall();
#endif

    // Other code
}
JennyS
  • 119
  • 9
  • I believe the system library: http://www.cplusplus.com/reference/cstdlib/system/ can be used to run executables. Using this you can run something like a windows version checker. However this would only happen at run time, and probably not so useful at compile time. Not sure if that solves your problem, but good luck :) – Liang Dec 05 '15 at 01:27
  • You wouldn't normally build a separate application for Windows XP, you would build a single application that works for both XP and later versions. Sometimes that means just using WindowsXPCall, which in most cases will still be available in later versions, and sometimes it means deciding which call to make at runtime. – Harry Johnston Dec 05 '15 at 01:28
  • If you really want to build a separate executable, though, you can detect use of the XP toolset as per [this question](http://stackoverflow.com/q/23279157/886887). – Harry Johnston Dec 05 '15 at 01:33
  • @Liang: there's no need to shell out to a separate application to detect the Windows version. The API provides version-checking facilities, though it is usually preferable to detect features, not versions; e.g., you can find out whether a particular API function exists using GetProcAddress. – Harry Johnston Dec 05 '15 at 01:35
  • I need to build one executable for all windows platform. The problem is I used a win32 API that doesn't work on XP. So when I try to run on XP, it complains about the API's entry point can't be located in kernel.dll – JennyS Dec 05 '15 at 01:45
  • 4
    If you `need to build one executable for all windows platform` then the `#ifdef WINXP` in the OP doesn't make sense. That's a compile time directive, and if you compile twice with and without WINXP defined, then you end up with different executables for different platforms. – dxiv Dec 05 '15 at 01:54
  • If you want to build a single executable, you don't want conditional compilation, so this question is based on a flawed premise. You might want to ask another one, but it would be sensible to work out just what your actual problem is first. Obviously you can't use an API that doesn't exist on XP if you want your program to run on XP. But with only a very few exceptions, everything that works on XP will also work on later versions. Is there a particular function you're having trouble with? – Harry Johnston Dec 05 '15 at 02:03

2 Answers2

2

The answer depends on the compiler and toolchain. If the question is about Visual C++ then you should tag it as such.

For VC++ the target minimum OS version supported is controlled by a set of macros described at Using the Windows Headers.

In the simplest case, to target XP you would need to add

#define _WIN32_WINNT 0x0501

before including any of the windows headers, or add /D_WIN32_WINNT=0x0501 to the compiler command line.

Replace 0x0501 with 0x0502 if you don't need to support the original release of XP (without any service packs applied), per this note in the same linked article.

Note that some features introduced in the latest version of Windows may be added to a service pack for a previous version of Windows. Therefore, to target a service pack, you may need to define _WIN32_WINNT with the value for the next major operating system release. For example, the GetDllDirectory function was introduced in Windows Server 2003 and is conditionally defined if _WIN32_WINNT is 0x0502 or greater. This function was also added to Windows XP with SP1. Therefore, if you were to define _WIN32_WINNT as 0x0501 to target Windows XP, you would miss features that are defined in Windows XP with SP1.

P.S. It's you who controls the sources and compilation flags of your own code, so I am not sure how to answer this part of the original question.

What conditional compilation flags can I check to determine which windows OS the code is being compiled for?

dxiv
  • 16,984
  • 2
  • 27
  • 49
0

With one executable, detecting "what version you are being targetted to" does not make much sense; your executable has to target every version. #ifdef like the above cannot fix your problem, unless you build more than one executable (or use a helper dll which you build more than one version of).

Your problem may be solved by "how do I restrict the API available to winXP". @dxiv's answer solves that problem.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524