¶An absolutely brilliant way to make sure buggy programs don't get fixed
I just spent the last hour or so trying to figure out why the newly added 64-bit configuration of my program didn't run, only to discover it was because Visual Studio happily linked in all *.manifest files it found in the project even though I don't see any docs or options mentioning this, and the manifest command line in project settings doesn't show it. Okay, we can deal with that, just set "exclude from build" and hope it works. Run it from the command line, and, yup, it now launches.
Crash. Oh well, the first launch never works anyway, probably a simple 64-bit porting issue. Visual Studio JIT dialog comes up, choose to debug.
To my horror, I then saw this dialog (this is Windows 7, btw):
Uh, WTF? I'm trying to debug the program, why would I want to enable a compatibility mode for it? And where's the cancel button??
I spent the next ten minutes trying to find out how to check a program's status or remove it from the compatibility list, and I couldn't find one. After a bit of spelunking in the Registry, I was horrified to find this:
A bit of explanation: user callbacks happen whenever the kernel-mode OS code needs to call back into the program in user space. The most common case of this is a window procedure, where the window manager running in kernel mode issues a callback to invoke the program's winproc code. I can't find concrete information on it, but what this mode appears to do is eat exceptions thrown from the user code, as if a try/catch with an empty handler were wrapped around it. And sure enough, when I ran the program, it didn't crash. It simply proceeded to silently not work instead. I could at least reproduce the crash under the debugger, but no longer out of it.
If I get all of this correctly, I find this to be a terrible design. The reason for the PCA is understandable, but the execution is lousy. Not only is there no apparent way to tell Windows not to apply a compatibility mode, but it also permanently enables that behavior for the program. Not even deleting and recreating the program will work, because the path is now embedded in the Registry. There does appear to be a supported way to disable the PCA (Group Policy), but it looks like the Registry Editor is the only way to remove a program entry. This has a number of bad implications for developers, because it means that you will only see the bug once, your QA and beta testers will only see the bug once, and after you've shipped a buggy app that you think is OK, your end users will see the bug once. The end result is that programmers keep shipping broken code, because the bugs are being masked.