独立观察员 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 == "")
{
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("CefApp");
if (processes.Length >= )
{
Console.WriteLine($"当前系统中有该程序在运行,将隐藏该程序");
//ShowWindow (processes [0].MainWindowHandle, 0); // 隐藏;
ShowWindow(processes[].MainWindowHandle, ); // 最小化;
}
}
else if (flag == "")
{
Console.WriteLine($"程序即将退出...");
Environment.Exit();
}
}
}

关键的就是 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 >= )
{
Console.WriteLine($"当前系统中已有该程序在运行,将唤起该程序");
ShowWindow(processes[].MainWindowHandle, ); // 对隐藏程序不起作用;
}
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( * );
}

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

以上就是本文全部内容。

http://dlgcy.com/dotnet-single-program/

[.NET] 控制只启动单个指定外部程序的更多相关文章

  1. WinForm程序,实现只启动一个实例

    前言:在我们做的软件中,当点击图标运行时,正常的需求是只需要启动一个软件的实例,这是非常重要的一点,不然就显得我们的软件非常的山寨,笔者在工作中经常遇到同事没有注意这一点,看是不重要,实则非常的重要, ...

  2. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    [Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...

  3. 【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

    大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单, ...

  4. 如何让程序(如java Hello)只启动一次?

    如何让程序(如java Hello)只启动一次? 摘自http://bbs.csdn.net/topics/50488704 总结一下,关于让Java程序只运行一个实例的问题,其实质是JVM之间通信的 ...

  5. MFC 只启动一个程序实例

    问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...

  6. springboot打包去除资源文件,启动时指定配置文件位置,使用log4j2替换默认logback

    springboot打包时,去掉资源文件 <build> <resources> <resource> <directory>src/main/reso ...

  7. 让vs只启动自己想调试的站点

    VS中里面多个WEB项目如何只启动一个? 每次启动时,右下角都会出现一堆的 网站有10来个.即使设置了默认启动项目, 但每次按F5启动,或者哪怕是在项目上右键启动新实例 右下角都会出现这一堆的站点 有 ...

  8. img只显示图片一部分 或 css设置背景图片只显示图片指定区域

    17:14 2016/3/22img只显示图片一部分 或 css设置背景图片只显示图片指定区域 background-position: 100% 56%; 设置背景图片显示图片的哪个坐标区域,图片左 ...

  9. WinFrom 只启动一个exe,并且获得焦点

    只启动一个exe方法: using System; using System.Collections.Generic; using System.Runtime.InteropServices; us ...

随机推荐

  1. String字符串是不变对象,内容一旦创建不可改变,若改变一定会创建新对象

    package seday01;/** * 字符串是不变对象,内容一旦创建不可改变,若改变一定会创建新对象* @author xingsir */public class StringDemo { p ...

  2. jpa分页

    法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特定数据库的查询) public interface UserRepository extends JpaRepository<Use ...

  3. django7-cookie与session

    1.有状态服务与无状态服务 服务实例存储了客户端的数据 ,那么这就是个有状态服务 服务实例不存储客户端数据 ,让其他缓存存储客户端数据 ,这就是无状态服务 ,http就是无状态的 2.什么是cooki ...

  4. cent OS 7 服务器 相关设置

    1. 不能联网, 很有可能是默认网络没有启动,需要手动启动 打开文件: vi /etc/sysconfig/network-scripts/ifcfg-ens33 如下: 如果是 no 改为 yes, ...

  5. 「SAP技术」SAP MM 事务代码ME17的用法

    SAP MM 事务代码ME17的用法 1,如下采购信息记录需要被归档: PIR号码,5300007816   2, ME12打上删除标记,   3, 事务代码ME17做归档 3.1 创建archive ...

  6. setValueForKeysWithDictionary的底层实现

    setValueForKeysWithDictionary这个方法会遍历字典, 然后调用setValue:forKeyPath: 根据字符串,进行属性匹配: (1)根据key,到当前模型当中,去找有没 ...

  7. Ubantu搭建虚拟环境

    配置虚拟环境 Ubantu16.0.4 1.安装python虚拟环境 sudo apt-get install virtualenv 2.vrtaulenvwrapper是virtualenv的扩展包 ...

  8. 1. Go语言—初始

    一.golang语言特性 1. 垃圾回收 内存自动回收,再也不需要开发人员管理内存 开发人员专注业务实现,降低了心智负担 只需要new分配内存,不需要释放 2. 天然并发 从语言层面支持并发,非常简单 ...

  9. C++标准库删除字符串中指定字符,比如空格

    参见:https://zh.cppreference.com/w/cpp/algorithm/remove 使用 erase 和 remove 配合. #include <algorithm&g ...

  10. ESP8266 LUA脚本语言开发: 外设篇-GPIO输出高低电平

    前言 所有的LUA开发API参考 https://nodemcu.readthedocs.io/en/master/en/modules/gpio/ 原理图 让GPIO2输出高电平只需 gpio.mo ...