Are Windows executables forward and backwards compatible? - c++

Say I'm building a C++ portable executable and I include the windows.h header. Also, let's stick to just Windows 10. If I use the most recent Windows 10 Visual C++ toolchain to build the binary, can I run the binary on earlier versions of Windows 10? If I use the earliest Windows 10 Visual C++ toolchain to build the binary, can I run it on the latest version of Windows 10?
Let me know if you would like me to clarify the question.

Quoting from Microsoft's documentation under Update WINVER and _WIN32_WINNT.
Visual Studio and the Microsoft C++ compiler support targeting Windows 7 SP1 and later.
Older toolsets include support for Windows XP SP2, Windows Server 2003 SP1, Vista, and Windows Server 2008.
Windows 95, Windows 98, Windows ME, Windows NT, and Windows 2000 are unsupported.
Applications targeted at Windows 10 with the default #define's will run under all versions of Windows 10.
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
To use newer APIs introduced in a later version of Windows 10, see the section under Remarks starting with "for a more fine-grained approach to versioning, you can use the NTDDI version constants in sdkddkver.h", and also the Using the Windows Headers page. For example, compiling with #define _WIN32_WINNT 0x0A00 and #define NTDDI_VERSION NTDDI_WIN10_19H1 will allow using features introduced in Windows 10 19H1, but only targets Windows 10 19H1 and later.

Related

How to use Visual Studio 2019 to target Windows 7?

I would like to use Visual Studio 2019 to enjoy the latest C++ additions, but targeting Windows 7.
I created a Windows C++ application using the VS 2019 wizard (running on Windows 10).
A targetver.h file is created by the wizard, with the following content:
#pragma once
// // Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>
I followed the instructions in the comment lines, and added the following lines intargetver.h (before the #include <SDKDDKVer.h> line):
// Target Windows 7 SP1
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0601
To test that, in the program's main function I invoked an API (PathCchAppend) that is not supported in Windows 7.
The program builds fine (I statically link the CRT), and runs fine in Windows 10.
The same program fails when executed in Windows 7, showing the following error message:
Now, the program should have not compiled at all, because I specified the Windows 7 target, and the aforementioned API is not available on Windows 7.
Is this a bug in the Windows SDK?
Is it possible to target Windows 7 using VS 2019 and the Windows 10 SDK, getting errors during the build process when an API or structure that is not supported in Windows 7 is used in the code, and how?
VS 2019's toolset and the latest Windows 10 SDK support targeting Windows 7 Service Pack 1.
You have already configured the Windows headers in the Windows 10 SDK properly:
#include <winsdkver.h>
#define _WIN32_WINNT 0x0601
#include <sdkddkver.h>
You can still call APIs that are not supported by Windows 7 in this mode, which is why calling PathCchAppend builds, links, and fails at runtime.
The problem you are seeing may also be related to the Universal C/C++ Runtime not being on your target machine. Install the x86 and/or x64 native version on your target test machine.
See Microsoft Docs.

Windows SDK Version setting in Visual Studio 2017

I have a c++ project that compiles well under Visual Studio 2013.
Today I installed Visual Studio 2017 Professional Edition, then there's a new setting in project settings > General called "Windows SDK Version", by default is 10.0.16299.0. Since I'm compiling windows desktop programs for targeting Windows 7 systems, I changed it to 8.1, is this correct?
Generally speaking, a Windows SDK supports its "main" version and also the previous ones, but you need to specify what Windows version your program will need. In fact, you're better off doing so or else you can inadvertently use features not available in the version you want to support.
Given an SDK, you indicate which older Windows version to target by defining the WINVER and _WIN32_WINNT macros somewhere in your project files or in the C/C++ Preprocessor project settings in Visual Studio.
For example, the following definitions target Windows 7:
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
For more information, see Using the Windows Headers and Modifying WINVER and _WIN32_WINNT
Indeed I raised this issue because my freshly installed Visual Studio could not build the VM because SDK 16299 is now indeed the default. It's mentioned here:
https://en.wikipedia.org/wiki/Microsoft_Windows_SDK.
.
Also MS does not make finding older SDK's very easy. You have to click through to another page all the way on the end of this page:
https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
Even though I googled on "Microsoft Windows SDK 15063".
.
So all-in-all it's now a small chore for newbies to get up and running on the VM. To start, I think it should be made as easy as possible. (Complexity will come soon after that :)).
.
PS I'm not sure about Windows 7 compatibility. But the current VM SDK is also listed as being for Windows 10.

Which SDK do I need to ensure Windows 7 compatibility in Visual Studio C++ 2017

I am building Desktop apps with Visual Studio C++ 2017 on Windows 10. Compatibility with Windows 7 and 8 is required.
May I use the latest Windows 10 SDK for this, or do I have to use the Windows 8.1 SDK?
You can use the Windows 10 SDK to write Windows desktop applications compatible with Windows 7 and up. The minimum target version is controlled through preprocessor symbols (WINVER and _WIN32_WINNT). Set them to 0x0601 to target Windows 7 and up.
See Using the Windows Headers for details.

How to make 64 bit dll compatible with 64-bit editions of Windows Server 2008, Windows 7, and Windows XP?

I have compiled a dll on Windows Server 2008 64 bit edition. It works fine on that version of Windows, but if I switch to Windows 7 or XP 64 bit edition the dll does not work. How can I make the dll compatible with all three versions of 64bit edition windows?
I am using Visual Studio 2010.
You can use a program called Dependency Walker to see what dependencies your .dll file has, and eliminate the ones that are different between versions of Windows.
Check how _WIN32_WINNT and WINVER macros were defined in your DLL. To make your DLL compatible with Windows XP you should define them as 0x0501. That lets you find all dependency problems at compile time. More information about these macros you could find here.

Explorer thumbnails (winXP)

I have a file format I need to be able to show in explorer thumbnails. Since the target system is windows XP, the Vista PreviewHandler API will not be suitable. Ill be using c++.
How would I do it?
You'll need to register a shell extension for your file type. The extension contains code that extracts/generates the thumbnail by implementing the IExtractImage interface.
See: IExtractImage Interface on MSDN
https://github.com/reliak/moonpdf/tree/master/ext/sumatra/src/previewer is perfect example.
To build both x86 and x64 versions of DLL I use VS 2010 with SP1 along with Win7 x64 SDK (for <thumbcache.h>) installed on Windows 7 x64. Builded DLLs works fine on Win7 and Win10 of either bitness.
Also don't forget /MD linker flag to avoid necessity to install Microsoft Visual C++ 2010 Redistributable Package (x86) on WinXP.
Next lines may be added to "targetver.h" to avoid import and using of new functions from newer versions of Windows system DLLs (say, there is no RegDeleteTreeW in WinXP's advapi.dll):
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#include <winsdkver.h>
#include <SDKDDKVer.h>
Additionally it has implementation of previewer for some file formats, but related interfaces can be completely omitted in your implementation.