欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[.NET] 控制只启动单个指定外部程序

程序员文章站 2022-03-20 13:05:14
有的时候我们程序需要启动外部程序来配合实现某些功能,比如启动一个 Cef 相关程序来承载网页。那么如果那个外部程序并没有实现单例启动,我们程序去启动它的时候就有可能启动了多个,这样轻则造成系统卡顿,重则引发 Bug。这肯定是我们不想看到的,所以本文来探讨如何在启动某个外部程序时,始终只会启动一个。 ......

有的时候我们程序需要启动外部程序来配合实现某些功能,比如启动一个 cef 相关程序来承载网页。那么如果那个外部程序并没有实现单例启动,我们程序去启动它的时候就有可能启动了多个,这样轻则造成系统卡顿,重则引发 bug。这肯定是我们不想看到的,所以本文来探讨如何在启动某个外部程序时,始终只会启动一个。

 

先来看看外部程序(其实不用关心),其中有一个这样的类:

 1     public class boundobject
 2     {
 3         [dllimport("user32.dll", entrypoint = "showwindow", setlasterror = true)]
 4         static extern bool showwindow(intptr hwnd, uint ncmdshow);
 5  
 6         /// <summary>
 7         /// 是否关闭:1 - 隐藏  2 - 关闭
 8         /// 用法:onclick="javascript:alert ('1');boundobject.closeflag ('1');"
 9         /// </summary>
10         public void closeflag(string flag)
11         {
12             if (flag == "1")
13             {
14                 system.diagnostics.process[] processes = system.diagnostics.process.getprocessesbyname("cefapp");
15                 if (processes.length >= 1)
16                 {
17                     console.writeline($"当前系统中有该程序在运行,将隐藏该程序");
18                     //showwindow (processes [0].mainwindowhandle, 0);  // 隐藏;
19                     showwindow(processes[0].mainwindowhandle, 6);    // 最小化;
20                 }
21             }
22             else if (flag == "2")
23             {
24                 console.writeline($"程序即将退出...");
25                 environment.exit(0);
26             }
27         }
28     }

 

关键的就是 flag == “1” 里面的内容,先获取所有名为”cefapp” 的进程,如果大等 1,表示进程已经存在,这里是将其隐藏,用的是系统的 showwindow 方法。

 

另外,与本文无关,但是有助于理解使用场景的是:该程序为一个 cef 相关程序,以上的类可用于让 cef 中承载的网页能够通过 js 调用到这个 c# 的方法,进而进行隐藏或关闭控制。相关设置如下:

1 cefsharp.wpf.chromiumwebbrowser webview = new cefsharp.wpf.chromiumwebbrowser();
2  
3 var bindscriptoption = new cefsharp.bindingoptions();
4 bindscriptoption.camelcasejavascriptnames = false;
5  
6 webview.registerjsobject("boundobject", new boundobject(), bindscriptoption);

 

回归正题,现在来看看主程序里面:

 1 system.diagnostics.process[] processes = system.diagnostics.process.getprocessesbyname("cefapp");
 2 if (processes.length >= 1)
 3 {
 4     console.writeline($"当前系统中已有该程序在运行,将唤起该程序");
 5     showwindow(processes[0].mainwindowhandle, 3); // 对隐藏程序不起作用;
 6 }
 7 else
 8 {
 9     string path = path.combine(appdomain.currentdomain.basedirectory, "external", "cef", "cefapp.exe");
10     system.diagnostics.processstartinfo info = new system.diagnostics.processstartinfo(path);
11     info.workingdirectory = path.getdirectoryname(path);
12     system.diagnostics.process.start(info);
13  
14     thread.sleep(1000 * 3);
15 }

 

也是获取所有”cefapp” 进程,如果有则启动之前最小化的该程序,没有则启动新程序。因为使用 showwindow 隐藏程序后无法再显示出来,所以只能配合最小化来使用,所以两个程序都是全屏运行效果会比较好。

 

以上就是本文全部内容。