winapivisual-studio-2017manifestdpi-aware

How to use my own manifest file and embed it into executable using Visual Studio 2017?


I am trying to use PerMonitorV2 DPI awareness, which resizes non-client area when DPI is changed. MSDN documentation recommends using manifest to set DPI awareness mode: Setting the default DPI awareness for a process.

Manifest Tool section of VS Configuration Properties provides only three options for DPI Awareness: None (unaware), Hight DPI Aware, and Per Monitor DPI Aware (which seems to be PerMonitorV1), so I need to find some way to override those DPI settings, but I don't know how to do that. (My best guess is to somehow provide my own manifest file instead of relying on Visual Studio to generate one.)


Solution

  • Within the manifest tool settings, you can define an additional manifest snippet that Visual Studio will merge with the default one. The default manifest will still provide the <dpiAware> tag, to serve as the fallback for older versions of the OS that don't understand the <dpiAwareness> tag.

    Steps:

    1. Open project configuration, select "Manifest Tool" > "Input and Output".
    2. In the field "Additional Manifest Files", enter the filename of the manifest snippet you want to include. The path is relative to your project folder.

      The snippet looks like this. Note that I removed the <dpiAware> tag from the MSDN sample:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <application xmlns="urn:schemas-microsoft-com:asm.v3">
          <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
          </windowsSettings>
        </application>
      </assembly>
      
    3. From the "DPI Awareness" combobox select "High DPI Aware". As written above, this is the fallback value for older Windows versions.

    Result:

    This is the merged manifest for a Win32 project I created using the application wizard. It is embedded in the resources of the application.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
          </requestedPrivileges>
        </security>
      </trustInfo>
      <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
          <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
          <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
        </windowsSettings>
      </application>
    </assembly>
    

    If you get two <dpiAware> tags, you forgot to remove the <dpiAware> from the manifest snippet.