When addressing difficult application compatibility issues, there are some things you just can't fix. Some applications will never work on Windows Vista, shims or no shims.
For example, I was debugging one application that happened to be written in Visual Basic 4.0 16-bit. (Ah, the days when you would pick the bitness in Visual Basic. I had almost forgotten about that!) I was watching it error out with Error 70 - Access Denied and trying to sort out what the problem was. A little help from Process Monitor revealed that there were no file or registry keys that were the cause of the problem. I was next thinking it might be related to COM, when a colleague (whose name rhymes with Orange) suggested looking for windows hooks. Sure enough, a bp on user32!setwindowshookexa turned up a hit, I investigated the arguments, and it was setting up a hook of type WH_JOURNALPLAYBACK.
Now it all made sense. The bug was opened detailing that you have to press the Enter key after entering your data instead of pushing the submit button.
Yep - it's SendKeys. Rather than just calling the method, the developers pushed the button using SendKeys to get the button to call the method. (Really, I don't understand why anybody would do that.)
And that's something we can't fix. We could give it UIAccess, but we really needed the other mitigations to keep the application working, so that didn't work at all.
But I digress - the purpose of this post isn't to gripe about some SendKeys silliness that somebody wrote in the previous century. Rather, I wanted to discuss one small bit of the next thing we talk about when we come across an application that doesn't work.
"Well, your options are to use Virtual PC / Server, or Terminal Services."
Actually, let me back up. Lots of people also throw in Microsoft SoftGrid. Somewhere along the line, the way in which we have overloaded the notion of application compatibility has caused some folks to conflate the different meanings of compatibility. SoftGrid is great for app to app compatibility. It's not so hot for app to OS compatibility. There are some things it will do. However, to my knowledge, there isn't anything it could do that I couldn't similarly achieve using shims. (Prove me wrong.) So, if I tell you it can't be shimmed, this usually isn't a great option to bring up, even though it is exceptionally cool at the things it does do well. (It's not a product shortcoming when it doesn't do everything - I'm writing this using Windows Live Writer, which is downright dreadful for doing accounting for large enterprises, but it's a great blog post editor.)
But I digress yet again. (I do that sometimes.)
Let's zero in on Terminal Services. Specifically, some of the issues you may or may not encounter.
If an application doesn't work on Windows Vista, then it's not super likely to work on Windows Server 2008 either, terminal services or no. However, if it did work on Windows XP, then it just may work on Windows Server 2003. However, it may need a little bit of help. Here, you can use the Version Lie shims to lie about being a client version of the operating system. Yes, shims work just fine on Windows Server. Now, we don't typically apply them to server applications (even though the infrastructure is on server) - I mean, do you want a shimmed up old application to help you deliver 5 nines uptime? Because that may not work very well. But for shimming up client applications to run in terminal services, it can work great.
It can also help if it runs fine on Vista but not Windows Server 2008 because it needs that version lie.
All of that storytelling just to say "Hey, don't forget, you can shim things to work on Windows Server too, if you're trying to do terminal services." What can I say - I'm not feeling particularly terse tonight.
(Update: added the "s" to the SetWindowsHookExA API.)