Tuesday, June 05, 2012

How to get Visual C++ 2012 (VC 11 Beta) statically linked CRT and MFC applications to run on Windows XP

XPSupport wrappers version 1.09

One of the major limitations of Visual C++ 2012 is that it does not create applications that can run on Windows XP.  As most of you already know, there is a connect item at Microsoft on this.  See: http://connect.microsoft.com/VisualStudio/feedback/details/690617
Note that the connect item was closed as “by design” and it was stated that only Vista SP2 and above is supported.  So this leaves out XP and Server 2003.

As you can see from the comments, many users simply will not adopt VC 11 because of its lack of XP targeting support.  Whether the Visual Studio 11 tools run on XP is a whole other story.  I don’t need the IDE to run on XP. What I need is the ability to use VC 11 (and all of its powerful new language features) AND still be able to target XP as a platform to deploy my apps to.

If you’re a long time reader of my blog, you know that I have written another article in the past on how to target Windows 2000 when using Visual Studio 2010.   In that article I explained that there is a simple trick that we can use to “wrap” missing API functions.  This involves making a small assembly language forwarding directive that calls our own C++ wrapper function.  If we use this trick we can substitute our own versions of any API symbol that is linked into our app, without causing any multiple symbol errors in the linker.  This means we do not have to use /FORCE:MULTIPLE.
To summarize, if we run dependency walker (available from www.dependencywalker.com) on a built executable that uses CRT and/or MFC 11 on Windows XP SP3, we’ll see a bunch of “red” icons beside the functions that are missing on XP (mostly in kernel32.dll). Our goal is to get rid of all of this red before it will run correctly on XP.

An aside: If it were truly a technical limitation to drop XP, then it would be impossible for us to “wrap” every instance of these functions without touching the original CRT and/or MFC static lib source code.  I’m about to show you a simple, elegant way to give your VC 11 apps the gift of XP support, while allowing the exact same binary to run on higher versions as well (e.g Vista, 7, Server 2008, etc)

There is another new roadblock that Microsoft has put in our way.  Previous to VC 11, we could override both the minimum operating system and subsystem version numbers using a linker command line option.  However in VC 11, they only allow specification of 6.0 (Vista) as a minimum.  That means there is NO way to write the necessary operating and subsystem versions to the built binary without a separate post-build tool.
Turns out that writing the operating system and subsystem version numbers can be acheived using EDITBIN.EXE (a tool that is included with VC11)  This means we can use this as post-build step just after linking occurs.

All that needs to be done is to run editbin.exe on the built executable itself, e.g.

EDITBIN.EXE testapp.exe /SUBSYSTEM:WINDOWS,5.01 /OSVERSION:5.1

It still throws a warning that the subsystem supplied is invalid but writes it anyway (unlike linking which refuses to write it when it’s invalid).
Note: if you’re trying these instructions with a console application, use

EDITBIN.EXE testapp.exe /SUBSYSTEM:CONSOLE,5.01 /OSVERSION:5.1

instead.

Notice that in the title of this blog post, I say “statically linked”.  There is good reason for that.  Microsoft no longer provides makefiles for their DLLs (since VC2010).  The last version to provide makefiles was VC2008.  That is unfortunate, as I could have provided a way to make dynamically linked apps run on XP as well.  But for now, we’ll have to do with a solution for statically linked apps only. I suggest you put pressure on Microsoft using the avenue of your choice to have them make available steps or makefiles that will allow us to rebuild the CRT and MFC DLLs.  If they agree, then I can provide a follow-up to this blog entry.

Read more: Teds blog
QR: Inline image 1

Posted via email from Jasper-Net