6

I've an installer that complains about wrong Windows version numbers, preventing an upgrade to an application to be installed on Windows Server 2012:

Unsupported operating system, major=6, version=2.2, sp=0.0, type=3

Is it possible to use a shim to change type=3 into type=1 for the installer? If so, what would be the key steps?

According to the .exe file's properties, the installer was made with dotNetInstaller. I can imagine that it retrieves the version number by calling the API function GetProductInfo (update: no, it's GetVersionEx). I already tried running the installer in various compatibility modes. Unfortunately that doesn't affect the version numbers reported. See also my question on Super User.

feklee
  • 505
  • 3
  • 18

1 Answers1

5

I was wrong on my first answer. My first suggestion to you was to make a "version lie" shim for your application. But you can't, because you're using a managed code application. I'm not saying you can't write API hooks for .NET applications, but appcompat shim support seems to be a lot spottier for managed apps.

Application shims implement API redirects so that when the application makes a certain API call, it gets intercepted or 'hijacked' and some other data is returned to the application from the shim.

http://technet.microsoft.com/en-us/library/dd837644(v=WS.10).aspx

The Shim Infrastructure implements a form of application programming interface (API) hooking. Specifically, it leverages the nature of linking to redirect API calls from Windows itself to alternative code—the shim itself.

Most of the time, you can cook up your own shims with the Application Compatibility Toolkit:

http://blogs.technet.com/b/askperf/archive/2011/06/17/demystifying-shims-or-using-the-app-compat-toolkit-to-make-your-old-stuff-work-with-your-new-stuff.aspx

AppCompat Toolkit

And doing a "version lie" where the shim lies to the application about what version it's running on is the most common use case for appcompat shims.

Because developers insist on doing version checks in their code, which is wrong. Microsoft tells you it's wrong. Do not do version checks in your code. (Instead, check for the existence or lack thereof of a particular feature you intend to use.)

But developers still do version checks every day. What's worse is they do '==' version checks where the app simply won't work unless you're running an exact version of Windows, which is arbitrary and stupid.

Sigh... developers.

Chris Jackson of Microsoft has worked on the application compatibility stuff for many years, and his attitudes are similar:

One of the classes of shims that people find the easiest to understand are the version lie shims. In essence, we have shims that can compensate for the fact that so many developers' keyboards were shipped with a defective > key (and the failure rate of this key on developer keyboards is astonishing). They work by just returning a different value from the GetVersion(Ex) APIs, depending on which operating system you selected.

But unfortunately in that same article, he gives us what I believe is the critical piece of information here:

OK, so now that you have CompatAdmin started, under the System Database, expand the Compatibility Fixes list. With the /x switch, you'll notice that the WinXPSP2VersionLie now has a plus sign - if you expand this, you'll see a list of modules that have a red diamond next to them. These are modules that this shim specifically excludes. Among these? The .NET Framework modules.

You see, the .NET Framework doesn't take too kindly to being lied to. They do version checks to determine how to implement certain things, and thinking they're running down-level isn't so great. So, we intentionally exclude these modules, and, consequently, we intentionally exclude the code that you're writing that these modules are JITting and executing. Not that we wanted to do so, but the infrastructure didn't give us a great way to separate these out. We either lied to everything, or we lied to nothing. It was worse to lie to everything, so we didn't.

Hehe, that's kinda' funny that .NET is doing version checks too when I just said how bad of an idea it was...

For real-life applications that need a version lie, well, if the application is managed, you'll have to change the code. This is something you can't, and shouldn't, shim up.

So, if you notice the version lie isn't working, and the application is managed, then my spidey sense tells me you're trying to shim it up with an XP version lie - and that's not going to work.

From MSDN:

Generally, apps should not perform operating system version checks. If an app needs a specific feature, it is preferable to try to find the feature, and fail only if the needed feature is missing.

Ryan Ries
  • 55,011
  • 9
  • 138
  • 197
  • DotPeek didn't do the trick, and so I looked at the [source code](http://dotnetinstaller.codeplex.com/SourceControl/latest#dotNetInstallerToolsLib/OsUtil.cpp) of an old dotNetInstaller version, and found out that they get the version with the function [`GetVersionEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx). I have not yet succeeded in creating a shim. – feklee Sep 02 '13 at 20:45
  • It looks like it is [not](http://stackoverflow.com/a/1713385/282729) possible to create custom shims. As there seems to be no shim for `GetVersionEx` (I tried a lot of shims), the Application Compatibility Toolkit does not seem to be able to solve the problem. Perhaps you want to update your answer accordingly, or - alternatively - please correct me if I'm wrong. – feklee Sep 02 '13 at 21:06
  • Right you are. Edited I have. – Ryan Ries Sep 02 '13 at 21:28
  • I eventually tried getting the installer to run with WinDbg. While I could get make it jump past the error message dialog box, that is not enough: A variable needs to be set, and I don't know its address nor the needed value. So I give up for now, hoping that the vendor fixes the issue. – feklee Sep 03 '13 at 09:08