(cross-posted from the mailing list)
Windows Side-by-side (WinSxS) technology is a really shiny piece of technology that is not well enough understood, and often misused. This comes from a variety of reasons, one of which is the documentation—while quite excellent—only makes sense if you actually understand everything about WinSxS before hand. When I started brainstormin’ how to make CoApp go, I had an inklin’ that WinSxS would solve many of the most painful problems, it was just a matter of me figurin’ it out. Like my pappy always used to tell me “It may not be the easy way, but it’s the cowboy way.” … Well, WinSxS may not be the easy way (yet!), but it will most assuredly be the CoApp way.
A:I’ll let the good folks from Wikipedia take a stab at that:
Side-by-side technology is a standard for executable files in Microsoft Windows XP and later versions that attempts to reduce DLL hell. Side-by-side technology is also known as WinSxS or SxS. Executables that include an SxS manifest are designated SxS assemblies.
DLL hell designates a group of problems that arise from the use of dynamic-link libraries in Microsoft Windows. Problems include version conflicts, missing DLLs, duplicate DLLs, and incorrect or missing registration. In SxS, Windows stores multiple versions of a DLL in the WinSXS subdirectory of the Windows directory, and loads them on demand. This reduces dependency problems for applications that include an SxS manifest.
Hmm. I’m not sure that cleared it all up. Simply speakin’, WinSxS lets us take a DLL, give it a version number, digitally sign it, and then tell Windows to install it into a little box somewhere, and when we come lookin’ for it, it’ll give it to us. Now, when we make a new version of that same DLL, we can tell Windows that when someone comes lookin’ for the older one, that they should use this one instead.
Now, before some real WinSxS expert rides up and starts tellin’ us that it does a wagonload better than that, I’ll capitulate and say sure—it most certainly does a heck of a lot more, but we’re gonna take pony steps first. This time around, I’m gonna give ya’ll the easy explanation. Damn city slickers…
A: Well, technically speakin’, Windows can store more that DLLs with WinSxS—and consequently, rather than just call them DLLs, they call them Assemblies. And so WinSxS stores Assemblies for us.
A: Well, that’s because .NET assemblies and WinSxS are very similar. Good eye. Now, stop fussin’.
A: There are two implementations of WinSxS, they both work the same for the devleloper, with some minor behind-the-scenes implementation differences that aren’t important, and I’ll explain the Windows 7/Vista/2008/2008 R2 model. In the C:\Windows directory, you’ll find a subdirectory called WinSXS. Inside there is what appears to be an extraordinarily large number of directories, each holding a few files. And it seems a bit massive, and some of it seems redundant—but it ain’t.
WinSxS manages the files in there, so you don’t go about muckin’ with em. On top of that, it’s not really using up all the space you think it is, ‘cause it’s using hard links to manage multiple connections to the same files, so leave em alone. You’re not gonna ‘save space’ by messin’ with em.
A: You know, my pappy always used to tell me, “Never squat with your spurs on”. Good advice, and here’s a bit more, so pay attention. First of all, this ain’t 1989—disk space just ain’t that expensive. Hell, even if you needed a couple more gigs, you could probably find it somewhere else a lot easier, than muckin’ with somethin’ you really shouldn’t. And all that hard link’n is really hiding the fact that it’s not really using that much space.
A: When WinSxS stores stuff in there it stores it by using it’s assemblyIdentity. The assemblyIdentity consists of the name, the processorArchitecture (amd64/x86), the version (##.##.##.##), the publicKeyToken that was used to sign the assembly, and optionally the language of the assembly (en-us, fr-ca, etc...).
The publicKeyToken is a 16-character hexadecimal string representing the last 8 bytes of the SHA-1 hash of the public key under which the assembly is signed.
A: Yeah, pretty much. Even though everything else can stay constant, every version of an Assembly is uniquely accessible.
A: By attaching a particular kind of resource to the Assembly called an assembly manifest. The assembly manifest gives the Assembly its identity.
A: By attaching an application manifest to the application, the LoadLibrary API will ask the WinSxS system to load the correct Assembly at run time.
A: By specifying the policy in a publisher configuration file that gets registered along side the Assembly. The publisher can redirect specific versions, or a range of versions of old assemblies to a new one.
A: Yes. But I’m not going to explain that right now. You’re trying to solve the wrong problem, and it’s a slippery slope of pain and suffering. If you continue down this path, I’m gonna hog-tie you and throw you in another wagon.
A: Yep. It turns out there is a really easy way for us to support multiple compilers (VC9, VC10, MinGW, etc) with the same Assembly name, version number and architecture by using multiple certificates; one for each different compiler. So, the CoApp project will have several certificates, each publicKeyToken will support a different compiler. If that sounds complicated or troublesome, trust me, it ain’t.
A: Yep. That’s because … uh, well, let’s just say I disagree with how they used them. Visual C++ would bind to a very specific version number. They would put something like this in the application manifest:
<assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.42' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
Now, as you can plainly see they use version 8.90.50727.42. Let’s assume you want to run an app, and it needs the C++ redist files, and what if moments before, you had installed the C++ redistributables for the first time, with the version number 8.90.50727.40 ? When the application didn’t work, you’d think to yourself, but I just installed them (and you' really didn’t know what version it was), why is it not working? There isn’t an easy way for end-users to track this down, and it makes people go insane.
You’re probably thinking that well, you need to get the newest build, right? But you know what? The app probably would have run perfectly with the previous version, and if it was that damn important to have the absolute up-to-the-moment build, they should have given you the updated runtime in the app’s installer.
A: Well, in my humble opinion, they should have been binding to version 188.8.131.52 and let WinSxS use publisher policies to point to a newer version. If an application has a known problem with an old redist, they should be shipping the latest one with their app, and let WinSxS take care of it all.
A: *blink*. Um… sortof. The VC team stopped using WinSxS for the C++ runtime. I don’t really agree with what they’ve done, but heck, maybe I’m just a back-woods hick who doesn’t really understand the problem. After all, how much can you really know about this stuff without one of those fancy college educations?
A: You betcha. WinSxS will work, as long as we are playin’ by the rules, and we’ll make sure there are some tools for divinin’ what’s wrong if somebody tries somethin’ fishy.
A: No, not by a wide margin. But it’s enough for you to get a good grip on what it’s for, and why it’s so damn central to CoApp.
Hey, rather than commenting here, come join mailing list (join the team at https://launchpad.net/~coapp-developers) and continue the conversation!