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

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

独立观察员 2019年6月12日

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

 

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

    public class BoundObject
    {
        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
        static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);

        /// <summary>
        /// 是否关闭:1-隐藏  2-关闭
        /// 用法:onclick="javascript:alert('1');BoundObject.CloseFlag('1');"
        /// </summary>
        public void CloseFlag(string flag)
        {
            if (flag == "1")
            {
                System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("CefApp");
                if (processes.Length >= 1)
                {
                    Console.WriteLine($"当前系统中有该程序在运行,将隐藏该程序");
                    //ShowWindow(processes[0].MainWindowHandle, 0);  //隐藏;
                    ShowWindow(processes[0].MainWindowHandle, 6);    //最小化;
                }
            }
            else if (flag == "2")
            {
                Console.WriteLine($"程序即将退出...");
                Environment.Exit(0);
            }
        }
    }

 

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

 

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

CefSharp.Wpf.ChromiumWebBrowser webView = new CefSharp.Wpf.ChromiumWebBrowser();

var bindScriptOption = new CefSharp.BindingOptions();
bindScriptOption.CamelCaseJavascriptNames = false;

webView.RegisterJsObject("BoundObject", new BoundObject(), bindScriptOption);

 

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

System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("CefApp");
if (processes.Length >= 1)
{
    Console.WriteLine($"当前系统中已有该程序在运行,将唤起该程序");
    ShowWindow(processes[0].MainWindowHandle, 3); //对隐藏程序不起作用;
}
else
{
    string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "External", "Cef", "CefApp.exe");
    System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(path);
    info.WorkingDirectory = Path.GetDirectoryName(path);
    System.Diagnostics.Process.Start(info);

    Thread.Sleep(1000 * 3);
}

 

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

 

以上就是本文全部内容。

【转载请注明出处 Http://dlgcy.com】

打印本文

发表评论