- Contents
- Introduction
- DynSxS – What it is and how it works
- How to use it
- Things to avoid
- Download it
Introduction
If you’ve used Visual Studio 2005 or 2008 and tried to run something you’ve built on a different computer than the development one, chances are that the first time you receieved this error message:
I think baffling is the word to describe it. There’s no indication of what exactly went wrong, or where you should start looking in order to fix it. A quick google for the error message, or an inspirational thought to look in the event log, will reveal that the requested version of the Visual Studio libraries as seen in the manifest is not installed.
While you can use a pay version of VS to create a setup program, or switch to using the static runtimes (which may bring about extra bugs), here’s a simpler solution to the problem.
DynSxS, What it is and how it works
DynSxS is mainly an executable wrapper that will link a hosted executable to the most recent version of the libraries that are present on the machine. By embedding the compiled exe inside a launcher, the library versions of the VC libraries can be checked before the hosted exe begins running. If the versions requested are present then the hosted exe runs as it normally would.
If they’re not, the launcher hooks the exe up to the latest version available by creating a new custom manifest for Windows to use. It then fixes up the IAT as the Windows loader normally would. If an import is missing, or a SxS version with the same major version to which the hosted exe is linked to is missing, the user is prompted to update their copy of the runtimes to the required versions with a message that is much more specific than the Windows one:
If Yes is selected, the tool then presents the following dialog, and downloads and installs the required update. Finally, the tool restarts and runs the hosted file.
How To Use
To create a DynSXS enabled application, add a post-build event to your Visual Studio project that launches the embedder application with the path to the exe file you created as an argument (most commonly this is the $(TargetPath) macro, this is shown below) and build as normal.
It’s strongly recommended that you also instruct the linker to generate a relocation section, as the exe file you built is unlikely to load at it’s preferred address. One can be created for your exe by toggling the “Fixed Base Address” linker option to “Generate a relocation section (/FIXED:NO)” as shown below.
You can debug your application within VS and attach to it as you normally would. The embedder tool will copy all icons and versions resources across to the unpacker so that the resulting file looks exactly like the original application does from Explorer’s point of view. Managed C++ and C++/CLI applications are not supported through the tool but MFC, ATL and OpenMP are.
Things to Avoid
Due to the use of the unpacker, code like the following should be avoided when using the tool.
TCHAR fileName[MAX_PATH]; GetModuleFileName(NULL, fileName, MAX_PATH); HANDLE hFile = CreateFile(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile != INVALID_HANDLE_VALUE) { // read from the exe's file CloseHandle(hFile); }
In this case, unexpected data will be read as GetModuleFileName will return the path of the unpacker, not the hosted file. To get the actual path of the hosted file and subsequently the required data, use the _DynSxSRealFilePath_ environment variable as follows.
char fileName[MAX_PATH]; GetEnvironmentVariable("_DynSxSRealFilePath_", fileName, MAX_PATH); HANDLE hFile = CreateFile(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile != INVALID_HANDLE_VALUE) { // read from the exe's file CloseHandle(hFile); }
Download
The source code and binaries for the x86 and x64 versions of the tools can be downloaded from here.
Happy deployment.