本文分享下回到桌面性能的实现办法,成果与快捷键(Win+D)雷同。
实现办法
Windows回到桌面性能的实现形式有多种,能够模仿快捷键,也能够执行如下办法。其中办法一须要援用Shell32.dll,办法为增加援用,抉择COM找到"Microsoft Shell Controls and Automation",选中并确认,还须要将其嵌入互操作类型置为false。
// 办法一,[参考链接](https://stackoverflow.com/questions/41598951/programmatically-show-the-desktop)Shell32.ShellClass objShel = new Shell32.ShellClass();objShel.ToggleDesktop();// 办法二,[参考链接](https://social.msdn.microsoft.com/Forums/vstudio/en-US/a27ca1e4-bd02-434b-8d02-06553c35f3d5/show-desktop-program-no-working)Type shellType = Type.GetTypeFromProgID("shell.application");object shell = Activator.CreateInstance(shellType);shellType.InvokeMember("ToggleDesktop", BindingFlags.InvokeMethod, null, shell, new object[] { });
问题
失常状况下,这两个办法都能够胜利执行。
然而,明天碰到一台设施操作未胜利。场景是WPF利用收到udp音讯时,执行回到桌面操作失败。
看到有网友说执行上述代码时,需在STA thread中执行,否则会报错。办法一是须要在STA thread中执行的,然而并不能解决该问题。
再次剖析问题时发现,当WPF利用为以后流动窗口时,操作执行胜利,否则执行失败。因而,先激活窗口,再执行上述代码就能够胜利解决该问题了。
在出问题的设施上,应用简略的Show()、Active()办法激活窗口是不行的,只会在任务栏闪动图标,应用大佬提供的激活窗口的办法能够胜利激活。
该问题的难点在于并不是所有设施都存在该问题,我手中有两台设施,操作系统是一样的,但一台是好的,一台是不行的。出问题的设施代码是执行了的,不晓得为什么没有成果,必须将利用置为流动窗口才行,有理解该问题的小伙伴欢送探讨。
本文测试demo的局部代码如下,具体可见Github。
// Wpf主窗口public partial class MainWindow : Window{ public MainWindow() { InitializeComponent(); InitLogger(); InitUdpThread(); showDesktop = Method1; Logger.LogMessage(Severity.Info, $"start process, Main Thread id: {Thread.CurrentThread.ManagedThreadId}"); } private void InitLogger() { var file = new FileLogger("log.txt"); Logger.LogMessage(Severity.Info, "Init logger success"); } private void InitUdpThread() { Thread udpThread = new Thread(new ThreadStart(GetUdpMessage)); udpThread.IsBackground = true; udpThread.Start(); } private void GetUdpMessage() { UdpClient udpClient = null; try { udpClient = new UdpClient(10001); } catch (Exception) { Logger.LogMessage(Severity.Error, "create udp client failed"); return; } Logger.LogMessage(Severity.Info, "create udp client success"); IPEndPoint remotePoint = null; while (true) { try { byte[] receiveData = udpClient.Receive(ref remotePoint); string receiveString = Encoding.Default.GetString(receiveData); Logger.LogMessage(Severity.Info, $"receive udp message: {receiveString}"); if (receiveString.ToLower().Contains("showdesktop")) showDesktop?.Invoke(); } catch (Exception e) { Logger.LogMessage(Severity.Error, e.Message); } } } private void Button_Click(object sender, RoutedEventArgs e) { if (sender is Button btn) { switch (btn.Name) { case "method1": showDesktop = Method1; Logger.LogMessage(Severity.Info, "turn to method1"); break; case "method2": showDesktop = Method2; Logger.LogMessage(Severity.Info, "turn to method2"); break; case "activeFirst": showDesktop = ActiveFirst; Logger.LogMessage(Severity.Info, "turn to activeFirst method"); break; default: break; } } } private void Method1() { Thread newSta = new Thread(()=> { Shell32.ShellClass objShel = new Shell32.ShellClass(); objShel.ToggleDesktop(); Logger.LogMessage(Severity.Info, $"Current Thread id: {Thread.CurrentThread.ManagedThreadId}"); }); newSta.TrySetApartmentState(ApartmentState.STA); newSta.Start(); } private void Method2() { Type shellType = Type.GetTypeFromProgID("Shell.Application"); object shellObject = System.Activator.CreateInstance(shellType); shellType.InvokeMember("ToggleDesktop", System.Reflection.BindingFlags.InvokeMethod, null, shellObject, null); Logger.LogMessage(Severity.Info, $"Current Thread id: {Thread.CurrentThread.ManagedThreadId}"); } private void ActiveFirst() { App.Current.Dispatcher.Invoke(new Action(() => { Win32Api.SetWindowToForegroundWithAttachThreadInput(this); Method2(); })); } private Action showDesktop;}