Ich habe versucht, die DPI-Erkennung in einer ClickOnce-Anwendung zu deaktivieren.
Ich fand es schnell heraus, es ist nicht möglich, es im Manifest anzugeben, da ClickOnce asm.v3 in der Manifestdatei nicht unterstützt.SetProcessDpiAwareness hat keinen Effekt
Die nächste Option, die ich fand, war die neue Windows-Funktion SetProcessDpiAwareness aufrufen.
Nach this Tutorial
Call SetProcessDpiAwareness before you create the application window.
Und this Tutorial
you must call SetProcessDpiAwareness prior to any Win32API call
Sie haben die Funktion ziemlich früh zu nennen. Also, um zu testen, habe ich eine völlig leere WPF-Anwendung erstellt, und machte diese meine gesamte App-Klasse:
[DllImport("SHCore.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
[DllImport("SHCore.dll", SetLastError = true)]
private static extern void GetProcessDpiAwareness(IntPtr hprocess, out PROCESS_DPI_AWARENESS awareness);
private enum PROCESS_DPI_AWARENESS
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
static App()
{
var result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware);
var setDpiError = Marshal.GetLastWin32Error();
MessageBox.Show("Dpi set: " + result.ToString());
PROCESS_DPI_AWARENESS awareness;
GetProcessDpiAwareness(Process.GetCurrentProcess().Handle, out awareness);
var getDpiError = Marshal.GetLastWin32Error();
MessageBox.Show(awareness.ToString());
MessageBox.Show("Set DPI error: " + new Win32Exception(setDpiError).ToString());
MessageBox.Show("Get DPI error: " + new Win32Exception(getDpiError).ToString());
}
Die 3 Meldungsfelder zeigen diesen Inhalt:
Dpi set: True
Process_System_DPI_Aware
Set DPI error: System.ComponentModel.Win32Exception (0x80004005): Access is denied
System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
Warum ist die Anwendung noch gesetzt zu DPI_Aware? Ist dieser Anruf nicht früh genug?
Die Anwendung erlebt tatsächlich DPI-Skalierung.
Wenn ich das Manifest Definition verwenden:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
Es zurückkehrt Process_DPI_Unaware.
EDIT 1:
Jetzt Marshal.GetLastWin32Error() direkt nach PInvoke Methoden greifen, dies jetzt gibt tatsächlich einen Fehler.
Ah! Na sicher! Bitte sehen Sie meinen bearbeiteten Code, gibt "Set DPI Fehler: System.ComponentModel.Win32Exception (0x80004005): Zugriff verweigert" –
Siehe meine Bearbeitung für einen anderen Ansatz. – Aybe
Das hat einwandfrei funktioniert! Vielen Dank! –