多个高分屏导致 Aero 主题无法开启
简介
Aero 主题 仅仅是一个受人追捧的毛玻璃效果而已,但是在项目实际使用的时候却发现与 DirectX 渲染效率相关,在未开启 Aero 主题的情况下叠加透明窗体 Device.Present() 方法 延迟约在 00:00:00.1258071 相比开启了 Aero 主题的延迟约在 00:00:00.0000365,千倍的时间差。
测试结果
换个主题并不是难事,但是面对一个早已不受微软支持的操作系统,对多屏幕的支持不是很好,目前也没什么解决办法,实际测试中 3 块 1080p 显示器及以上无法被动开启 Aero 主题,2 块 4k 显示器及以上无法被动开启 Aero 主题,试过多型号显卡(Quadro P1000、Quadro P2000、Quadro P4000、Gtx 1080、Rtx 2070、Rtx 4000),排除显卡性能问题,试过多版本驱动,但是不排除显卡驱动与 Windows 7 兼容不好。
系统设置上的比对
桌面右键菜单个性化
异常情况左下角提示:解决透明度和其他 Aero 效果问题
证明此时 Windows 7 系统是知道显示存在问题的

解决透明度和其他 Aero 效果问题
点击修复程序,结果却显示很多问题不存在,无法修复

点击个性化中的窗口颜色
此时点击个性化中的窗口颜色,弹出的窗口颜色外观界面不同,异常情况无法设置 Aero 效果

系统性能选项
在系统性能选项卡中异常情况缺少 启用 Aero Peek 选项与其他重要选项

解决方案
在 Windows 7 兼容(4块1080p显示器以下或2块4k显示器以下)允许的范围内解决显示器接入断开导致 Aero 效果失效,软件操作恢复而不用人工操作。
处理方式
- 通过 dwmapi.dll 库的 DwmIsCompositionEnabled 检测 Aero 开启状态
 
- 通过系统 Environment.OSVersion.Version 方法获取 Windows 版本
 
- 通过 CMD 命令切换 Aero 主题和启动服务
 
- 通过 System.ServiceProcess.ServiceController 重启服务
 
- 涉及到的服务主要由 UxSms,或可能与 Themes也有关 
 
 
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
   | 
 
  [DllImport("dwmapi.dll", PreserveSig = false)] public static extern bool DwmIsCompositionEnabled();
 
 
 
 
  private bool IsWindows7() {     return Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1; }
 
 
 
 
  private void RunCmd(string strCmdCommand) {     Process cmd = new Process();     cmd.StartInfo.FileName = "cmd";     cmd.StartInfo.RedirectStandardInput = true;     cmd.StartInfo.RedirectStandardOutput = true;     cmd.StartInfo.CreateNoWindow = true;     cmd.StartInfo.UseShellExecute = false;     cmd.Start();     cmd.StandardInput.WriteLine(strCmdCommand);     cmd.StandardInput.Flush();     cmd.StandardInput.Close();     cmd.Close();     cmd.Dispose(); }
 
 
 
 
  private bool RecoveryAero() {     if (IsWindows7() && !DwmIsCompositionEnabled())     {                  ServiceController service = new ServiceController("UxSms");         if (service.Status == ServiceControllerStatus.Stopped)         {             RunCmd("net start UxSms");         }                  if (!DwmIsCompositionEnabled())         {             string strAeroTheme = @"C:\WINDOWS\Resources\Themes\aero.theme";             string strCmdCommand = string.Format(@"rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""{0}""", strAeroTheme);              RunCmd(strCmdCommand);             Thread.Sleep(5000);         }                  if (!DwmIsCompositionEnabled())         {             try             {                 service.Stop();                 service.WaitForStatus(ServiceControllerStatus.Stopped);                 service.Start();                 service.WaitForStatus(ServiceControllerStatus.Running);             }             catch             {
              }         }     }     return DwmIsCompositionEnabled(); }
 
  |