2021-05-25

Win32Api -

本文分享下回到桌面功能的实现方法,效果与快捷键(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;}








原文转载:http://www.shaoqun.com/a/760831.html

跨境电商:https://www.ikjzd.com/

网络星期一:https://www.ikjzd.com/w/80

easybuy:https://www.ikjzd.com/w/2162


本文分享下回到桌面功能的实现方法,效果与快捷键(Win+D)相同。实现方法Windows回到桌面功能的实现方式有多种,可以模拟快捷键,也可以执行如下方法。其中方法一需要引用Shell32.dll,方法为添加引用,选择COM找到"MicrosoftShellControlsandAutomation",选中并确认,还需要将其嵌入互操作类型置为false。//方法一,[参考链接](
yeepay:https://www.ikjzd.com/w/2574
西集网:https://www.ikjzd.com/w/1353
环球华网:https://www.ikjzd.com/w/1063
初恋突然来访 只为和我上床:http://www.30bags.com/a/252673.html
美国失业率高的情况下,电商有什么机会?2020年美国失业率增长至多少?:https://www.ikjzd.com/articles/120192
卖家通病 | 流量高没转化率怎么办?:https://www.ikjzd.com/articles/18115

No comments:

Post a Comment