Wednesday, June 29, 2011

It’s manifestly simple, isn’t it?

No, it’s not!

As I start nearing the end of development for StrokePlay I’ve started to look at the packaging and deployment more and more.

I say more and more, it’s more like I try it and it fails, I try it and it fails. The reason? Manifests.

For the past couple of weeks I would try to deploy StrokePlay to a test virtual machine – a fresh XP SP3 Install, nothing else – and start it up. Every time, it failed stating that there’s a problem with the side-by-side configuration.

So, I’d park deployment and get back to coding or some other task.

This afternoon I sat down and decided not to stop until I’d found the problem and fixed it. As of 30 mins ago (10pm) it’s working!

In the end I tracked down and fixed a couple of build errors:

  • A Debug lib being included in a release build (oops)
  • Two 3rd party libraries being built with older versions of the Visual Studio 2008 CRT/MFC runtimes – now rebuilt.
  • An edit field that I forgot to remove – it was a custom edit field which used Regex from the Boost libraries. This resulted in a static link to Boost and, again, a dependency on an old CRT. It wasn’t actually needed so I removed it, thus taking out the Boost library dependency.

Once those were fixed I had everything using the same MFC/CRT/ATL versions but still no running application.

Final correction was to use the CRT/MFC/ATL libraries and manifest files from the installed VS2008 redist directory rather than installing the redistributable package. The redist directory contained the matching runtimes.

One rant on this though – given that manifests are such a big part of application deployment now, could we at least get some decent error messages and methods/tools to track down issues? I’m sure, judging by the volume of Google hits on this subject than I’m not alone in thinking that Manifests could do with a bit more work.

Any tips?

1. Make sure you’re consistently building with the latest available runtimes by including these defines at the top of your stdafx.h file (or defining them as environment variables):

Either all in one:

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

Or, individually:

#define _BIND_TO_CURRENT_CRT_VERSION 1

#define _BIND_TO_CURRENT_ATL_VERSION 1

#define _BIND_TO_CURRENT_MFC_VERSION 1

#define _BIND_TO_CURRENT_OPENMP_VERSION 1

2. If you’re deploying the runtimes locally to your installation directory then remember to include the correct manifest files too.

3. The Event Viewer (System log) contains more information about the failure than just the error message displayed.

4. The Dependency Walker is useful – but it doesn’t provide much more information. It was more useful as a test tool to see how things were progressing.

5. An excellent tool for viewing the content of embedded manifests is the Heaventools Resource Tuner. I downloaded the trial version and then bought a licence an hour later – it was invaluable to me when looking at the manifests embedded in the EXE and associated DLLs.

So, StrokePlay is now running on a basic XP build PC with SP3 and nothing else. It’s also some 300K lighter thanks to the corrections to the build. I can now get back to the job of finishing it off!

2 comments:

Anonymous said...

Oh, but you should have read my most popular stackoverflow answer http://stackoverflow.com/questions/59635/app-does-not-run-with-vs-2008-sp1-dlls-previous-version-works-with-rtm-versions/70808#70808 for tips and tricks ;) Also beware that Microsoft released an update to the CRT again two weeks ago, the 'current' version is .6161 (not .4148 which many people still have).

Patrick said...

Hahaha, I seem to live my life on stackoverflow at the moment - how did I miss that answer!

Yeah, 6161 is the version I needed and as the question and answers mentioned - that's not SP1.

Looks like you and I went through the same pain.

Patrick