Windows – Win32: Suggestions for manifested app’s testing vs deployment

compatibilitymanifestshimwindows

Starting with Windows Vista, Microsoft added a class of compatibility shims that will allow an application that assumes it has administrative file and registry access to continue to function.

In other words: An application that failed on Windows XP would run on Windows Vista.

These OS provided bug-fixes can be disabled by adding a section to the application manifest, declaring the application should run asInvoker:

<!-- Disable Windows Vista standard user compatability heuristics -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
   <security>
      <requestedPrivileges>
         <requestedExecutionLevel level="asInvoker"/>
      </requestedPrivileges>
   </security>
</trustInfo>

Ideally, a developer would test their application to ensure that it doesn't (needlessly) require administrative privelages. In order for me to test this, i would need to manifest it asInvoker.

But when it comes down to it, i'm not going to release the application to the customer manifested asInvoker. If i did miss something, i don't want the user to be impacted. i want Microsoft's operating system to fix my mistakes. Problem with this solution is:

  • i have to modify the manfiest before release
  • i'll never know about the things i missed, becuase they're just work on Windows Vista.

A similar conundrum comes up with Windows 7's supportedOS manifiest entires. You can add a manifest to the application indicating which version of Windows you were designed and tested for:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
   <application> 
      <!--The ID below indicates application support for Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
      <!--The ID below indicates application support for Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
   </application> 
</compatibility>

In the case of the supportedOS items, the operating system knows up front which OS you were designed for. This will place your application in the context of Windows Vista if you do not say that you support Windows 7:

alt text
(source: msdn.com)

This action is similar to running an application in some Compatibility Mode, e.g.:

  • Windows Server 2008 (Service Pack 1)
  • Windows Vista (Service Pack 2)
  • Windows Vista (Service Pack 1)
  • Windows Vista
  • Windows Server 2003 (Service Pack 1)
  • Windows XP (Service Pack 2)
  • Windows 2000
  • Windows NT 4.0 (Service Pack 5)
  • Windows 98 / Windows Me
  • Windows 95

where you will get a schmorgasboard of compatibilty shims applied, and Windows will emulate old undocumented behaviour in order to help your app from crashing when it depended on that undocumented behaviour.

An example of compatibility shims that Windows 7 will provide for an application running in the Windows Vista context:

  • RPC will use the old private thread pool, rather than the OS thread pool
  • you will be able to Lock the primary video desktop display buffer
  • you will be able to Blit to the primary desktop video buffer without specifying a clipping window
  • you will be vulnerable to a GetOverlappedResult race condition (if you depended on it)
  • you will continue to get Program Compatibilty Assistant (PCA) mitigation

And once again, in order to test my application properly under Windows 7, i have to add the supportsOS manifest entry. But, again, i'm not going to ship the application with that flag, because i don't want to lose the benefit of these shims (e.g. PCA). And, again, if an app has problems that were fixed because it was running in the Vista context: i'll never know about it from our customers – because the app is just working.


Thoughts? Guidance? Best practices?

Best Answer

i'm not going to release the application to the customer manifested asInvoker. If i did miss something, i don't want the user to be impacted.

I think this is a bad approach. My advice is to manifest correctly from the start and test what you deploy.

Microsoft is not going to bend over backwards for everyone's compatibility. They're going to target the most common, high-impact mistakes made by the biggest vendors. If you miss some small issue, the chance of them providing a shim in the future is small.

Every time Microsoft adds a compatibility shim, we all pay a price. There are APIs that don't work the way they should because they had to handle some case in a brain dead way to achieve compatibility with somebody else's bug. This means long, painful debugging sessions, it means wading through longer (or less complete) documentation, and it means little inefficiencies in the OS for everyone. It also means Windows developers are wasting time fixing other people's mistakes instead of improving the OS.

Sometimes these compatibility changes are big hammers that penalize developers who do it right. Many applications don't handle high DPI correctly, so--in the name of compatibility--Vista assumes that no applications handle it correctly (unless they explicitly claim otherwise). Vista applies UI scaling. Applications that didn't handle high-DPI get improved (but suboptimal) results. Applications that did handle high_DPI get degraded results. (And customers who used the good apps see them get worse when they upgrade to Vista and blame Microsoft.) The developers who didn't pay their taxes get help from Microsoft, the rest of us (including Microsoft) get penalized. The only way to avoid this is for everyone to pay their taxes.

In general, Microsoft is getting better at making these compatibility shims more targeted (though Vista was pretty blunt). Nevertheless, there's a little cost to each one.

Follow the best practice during development. Test what you plan to deploy. If it breaks big, Microsoft might fix it for you. Otherwise, you might have to release an update. That's better than everyone suffering a penalty because some developers didn't do the right thing.

Related Topic