3
votes

I have some Windows Forms applications that need to run on XP/2003/Vista/7/2008/8/2012, and should still look good when the user chooses Large Fonts or a higher DPI. Enabling DPI awareness in the app.manifest works well for Vista and later, but on XP/2003 the application reports an error due to an unsupported manifest entry.

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <asmv1:application>
    <asmv1:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv1:windowsSettings>
  </asmv1:application>
</asmv1:assembly>

Running the app with that manifest on Windows 2003 causes this error message:

This application has failed to start because the application
configuration is incorrect.

And this Windows event message is logged:

The element asmv1:application appears as a child of element
urn:schemas-microsoft-com:asm.v1^assembly which is not supported
by this version of Windows.

Is it possible to declare the manifest in a way that allows XP/2003 to ignore this portion of the manifest that they do not support? Or must I remove the manifest and make conditional calls to SetProcessDPIAware (even though everything I've read recommends against using that API function)?

1
No. Supporting ten+ year old operating systems does get to be a lossy proposition. You have little to fear from the initialization race problem that SetProcessDPIAware can cause, the just-in-time compiler helps a great deal avoiding that trap. Just pinvoke it in your Main() method. - Hans Passant
There's still a lot of Windows XP and Server 2003 in the world, so it is what it is. SetProcessDPIAware works fine. I was hoping there was a way to make a dpiAware manifest work in new OS version and be ignored in old OS versions, but I don't intend to beat my head against that particular wall. - Piper Keairnes
That's odd. I use <dpiAware>true</dpiAware> in the manifest file for one of my applications, and it runs fine all the way back on Windows 2000. Granted, this is a native C++ app, not .NET WinForms, so I suppose it is the .NET Framework that is reading the manifest file information and throwing the error. (I haven't checked to Windows event log to see if something is logged. It might be. I don't really care too much about that; the app runs file.) - Cody Gray

1 Answers

0
votes

I ended up with this manifest

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
  <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <asmv3:windowsSettings
         xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>True/PM</dpiAware>     
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>

Delphi specific condition: Use runtime themes is off and xpman.pas is not used anywhere