Category: Windows

Manifests. Now windows programmers have more issues.

Brief Background

Those who lived through the Windows 9x era very well experience the situation known as DLL Hell. For those without background, it’s the situation where different programs overwrite shared libraries, known in Windows as DLLs. For example, Program A needs sound.dll to run, it then proceeds to copy that file to the Windows directory usually upon installation. Then here comes Program B with its own version of sound.dll, sees sound.dll in the Windows Directory and proceeds to overwrite sound.dll which Program A uses. Have a hundred programs overwriting each other’s shared libraries including Window’s own DLLs (DirectX, C runtime libraries) and the end result is different programs (including Windows!) are getting unexpected results from the shared libraries that they use, causing crashes and other odd behavior. Nevertheless, they didn’t prevent this (the use of shared libraries) because it was necessary for other things like servicing (more information about servicing could be found here.

Windows 2000 and XP “fixed” these problems by intoducing Protected DLLs and Side-by-side Assemblies (SxS for short). Protected DLLs are basically DLLs which are protected by the Operating System: modify it and the system will attempt to restore it. SxS assemblies, on the other hand, are more complicated. An article at CodeProject explains almost everything.

Abstractions, abstractions, abstractions…

Basically, in order to use the “manifested” DLLs, you’ll have to include an xml file either together with your application or compiled as a resource. This may not seem much but the problem is, it’s note entirely automatic. In order to be able to use Common Controls 6 and Windows XP visual styles to a Windows GUI Application, this XML has be included in the manifest (taken from http://msdn2.microsoft.com/en-us/library/ms649781.aspx):

XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="X86"
    name="YourCompanyName.YourDivision.YourApplication"
    type="win32"
/>
<description>Your application description here.</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>

The first assemblyIdentity element was needed to enable Visual Styles in the application while the second one was to use common-controls. The first one is already automated by Visual Studio but the common controls element has to be manually placed either using that method (manually typing the XML) or using the #pragma directive:

C++:

#if defined(_M_IX86)
#define MANIFEST_PROCESSORARCHITECTURE "x86"
#elif defined(_M_AMD64)
#define MANIFEST_PROCESSORARCHITECTURE "amd64"
#elif defined(_M_IA64)
#define MANIFEST_PROCESSORARCHITECTURE "ia64"
#else
#error Unknown processor architecture.
#endif

#pragma comment(linker, \
    "\"/manifestdependency:type=’Win32′ "\
    "name=’Microsoft.Windows.Common-Controls’ "\
    "version=’6.0.0.0′ "\
    "processorArchitecture=’" MANIFEST_PROCESSORARCHITECTURE "’ "\
    "publicKeyToken=’6595b64144ccf1df’ "\
    "language=’*’\"")

Anyway, the main point is, why does it have to be this tedious? Can’t we just add references just like how .net applications do?

In the linux world, this doesn’t matter very much since the applications are compiles to the user’s machine so all, if not most, dependencies are resolved using package managers and the like. And unlike Microsoft, there’s no single entity that carries all responsibility of servicing so they don’t have to worry about it much.

For Mac, with what they call “Frameworks”, it gets even easier, just add the Framework to the project (like how you Add References in .Net) and place this in your code:

C++:

#include <Framework_name/Header_filename.h>

Sometimes, I just hate how Microsoft treat C/C++ programmers like 2nd class citizens.