目录

介绍

概念化这个混乱

编码此混乱


  • 下载SingletonIPC.zip-4.5 KB

介绍

有时,您可能会在某个应用程序中没有必要两次启动主应用程序,但是您可能希望通过传递其他命令行参数来再次运行该应用程序。这样,您可以运行该应用程序,它将打开您的程序,然后您可以再次运行该应用程序,并将其他命令行信息传递给已运行的应用程序。例如,当您想让现有应用程序从命令行打开新文件时,这很有用。因此它像这样处理:

C:\Foo> MyApp myfile1.txt
C:\Foo> MyApp myfile2.txt myfile3.txt

在这种情况下,MyApp仅在第一次启动实际的应用程序。第二次,它检测到它已经在运行,并简单地将传入的命令行发送到已经运行的应用程序进行处理。

概念化这个混乱

为了提供此功能,我们对该应用程序有两个主要方面。

首先,该应用程序需要检测它是否已经在运行,并且根据它是否已经在运行,它将执行不同的操作。

其次,我们需要一种使两个进程进行通信的方法。在这种情况下,主应用程序将等待子序列启动产生的命令行数据。

第一个方面很容易。我们使用命名的互斥锁来防止主应用程序代码两次启动。该用户的所有正在运行的进程都可以看到已命名的互斥锁。

第二个方面要困难一点,但幸运是也不是很难。我们将使用.NET的命名管道功能来促进主应用程序(服务器)与后续启动(客户端)之间的通信。该用户的所有正在运行的进程也可以看到命名管道。

编码此混乱

我们使用的代码在这里给出,几乎是完整的。我只是在这里取消了using指令,以节省一些空间。

class Program
{        static string _AppName= Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().GetName().Name);static void Main(string[] args){// we need to get our app name so that we can create unique names for our mutex and our pipevar notAlreadyRunning = true;// wrap the meat of the application code with a named mutex so it runs only onceusing (var mutex = new Mutex(true, _AppName + "Singleton", out notAlreadyRunning)){if (notAlreadyRunning){// do additional work here, startup stuffConsole.WriteLine("Running. Press any key to exit...");// ...// now process our initial main command line_ProcessCommandLine(args);// start the IPC sink.var srv = new NamedPipeServerStream(_AppName+"IPC", PipeDirection.InOut,1,PipeTransmissionMode.Message,PipeOptions.Asynchronous);// it's easier to use the AsyncCallback than it is to use Tasks here:// this can't block, so some form of async is a mustsrv.BeginWaitForConnection(new AsyncCallback(_ConnectionHandler), srv);// block here until exitConsole.ReadKey();// if this was a windows forms app you would put your "Applicantion.Run(new MyForm());" here// finally, run any teardown code and exitsrv.Close();}else // another instance is running{// connect to the main appvar cli = new NamedPipeClientStream(".",_AppName + "IPC",PipeDirection.InOut);cli.Connect();var bf = new BinaryFormatter();// serialize and send the command linebf.Serialize(cli, args);cli.Close();// and exit}}}static void _ConnectionHandler(IAsyncResult result){var srv = result.AsyncState as NamedPipeServerStream;srv.EndWaitForConnection(result);// we're connected, now deserialize the incoming command linevar bf = new BinaryFormatter();var inargs = bf.Deserialize(srv) as string[];// process incoming command line_ProcessCommandLine(inargs);srv.Close();srv = new NamedPipeServerStream(_AppName + "IPC", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);srv.BeginWaitForConnection(new AsyncCallback(_ConnectionHandler), srv);}static void _ProcessCommandLine(string[] args){// we received some command line// arguments.// do actual work hereConsole.Write("Command line recieved: ");for(var i = 0;i<args.Length;++i){Console.Write(args[i]);Console.Write(" ");}Console.WriteLine();}
}

这里有很多事情要做。

让我们从顶部开始,获取将用于标识应用程序的互斥锁和命名管道的应用程序名称。

接下来,我们创建一个命名的互斥体,并将我们的主要应用程序代码包装在此块中。这样可以防止应用启动其主要部分两次。

如果尚未运行,我们要做的第一件事就是运行任何应用程序初始化代码,然后处理所有命令行参数。然后,我们启动基于命名管道的IPC服务器,每当我们从该应用程序的后续实例获得连接时,该服务器便注册一个回调。我们已经注册的回调函数读取传入的命令行数据并处理传入的传入参数。最后,我们阻塞直到退出,在本例中使用Console.ReadKey(),但实际上,您将要创建自己的退出条件。对于Windows窗体应用程序,您可以通过调用Application.Run()来阻塞主应用程序窗体,而不是Console.ReadKey()。

现在,如果它已经在运行,我们所要做的就是打开之前创建的主应用程序实例的命名管道,并序列化命令行数据,将其发送到管道中,然后关闭管道连接并退出。

在_ConnectionHandler() 中,我们处理每个传入的连接时,从管道读取任何命令行参数,然后我们实际上重新启动命名的管道服务器,因为由于某种原因,它喜欢在结束连接后自行关闭。我尚未确定这是设计使然还是由于某种问题,但此解决方法似乎很好。

在_ProcessCommandLine() args中,我们进行参数处理。在演示中,我们所做的所有工作都是将其输出到控制台上,但实际上,您将要做更多的事情,例如基于参数打开文件。

C#中具有进程间通信的Singleton应用程序相关推荐

  1. Python中的进程间通信

    Python中的进程间通信 文章目录 Python中的进程间通信 1 进程间通信 1.1 概念 1.2进程间通信方法 各种进程间通信 1. 基于信号量(Semaphore)的IPC 2 基于信号(Si ...

  2. 如何在ASP.NET Core中编写自定义日志记录提供程序

    目录 介绍 如何实现所需的接口 基础类和附件 FileLoggerProvider具体类及其附件 1. ConfigureLogging() 2. appsettings.json文件 介绍 源代码可 ...

  3. Android中的进程间通信(IPC机制)

    记得上次阿里电话面试就问,Android中的进程间通信有哪些?当时没怎么总结过,就只说了一个AIDL.今天就来总结总结吧. 什么是进程间通信? 顾名思义,两个进程之间进行数据交换的过程,那什么又是进程 ...

  4. vue和react相同点_我在React和Vue中创建了相同的应用程序。 这是区别。

    vue和react相同点 by Sunil Sandhu 由Sunil Sandhu 我在React和Vue中创建了相同的应用程序. 这是区别. (I created the same app in ...

  5. unity 程序win7在进程里运行_Win7系统中unity web player是什么程序

    unity web player是什么程序,可不可以卸载?下面教程给大家详细讲解"unity web player"程序.以及可以不可以卸载!一起去看看吧! 如果你安装好Win7没 ...

  6. java jmf 视屏监控的核心代码_Java中利用JMF编写摄像头拍照程序_java

    我把程序分为两种,有趣的和无趣的,最近做了几个有趣的项目,其中一个,应当就算是摄像头拍照程序了.用于现场拍照,生成照片,主要用到java Media Framework(JMF). 首先到SUN下载最 ...

  7. 能在xcode5中开发基于IOS7sdk的应用程序兼容ios4.3之后的系统吗?

    能在xcode5中开发基于IOS7sdk的应用程序兼容ios4.3之后的系统吗? 转载于:https://www.cnblogs.com/ygm900/p/3472859.html

  8. JAVA用多线程反而变慢了_Java中使用多线程不能明显提高程序效率的一些原因

    java中使用多线程不能明显提高程序效率的一些原因. 使用多个线程来处理多任务的时候,效率肯定是有提高的.但是必须要慎用,否则容易出现问题. 1.多线程主要是为了充分利用多核cpu,大内存这些资源. ...

  9. java程序并行机制_Java语言具有多种优点和特点,下列选项中,______反映了Java程序并行执行机制的特点。A.多线程B.健...

    Java语言具有多种优点和特点,下列选项中,______反映了Java程序并行执行机制的特点.A.多线程B.健 更多相关问题 根据句意及首字母完成单词1. -What c__________ is i ...

最新文章

  1. win7下的iis配置
  2. 博途项目服务器,博图服务器客户端架构
  3. 03_Weblogic之配置简单域:启动和配置域,使用模板创建域,使用控制台
  4. 程序员初涉江湖 宜步步为赢(转-1) 作者:IT168 职业发展顾问Leo
  5. c语言编程被当作病毒,为什么这个微不足道的C程序被检测为病毒?
  6. eclipse 优化。
  7. python爬虫ip代理池_爬虫教程-Python3网络爬虫开发——IP代理池的维护
  8. 你写过哪些原创的风骨傲气,热血沸腾的句子?
  9. git clone 遇到的坑
  10. java字段映射成其他字段名称_java字段与数据库字段映射
  11. c语言二级考试题库及答案,c语言二级考试题库
  12. 【51单片机】基于51单片机的时钟电子锁设计
  13. 计算机群星闪耀时-记计算机界的大牛们
  14. infor wms 中英文对照_视听盛宴 I纸牌屋揭露美国政治权力运作(16中英、纯英、无字幕可切换视频+中英文全剧本+全季音频)...
  15. linux内核支持浮点吗,浅谈linux kernel对于浮点运算的支持
  16. thinkadmin 单页面多个富文本初始化
  17. [摘抄]给终身学习者的建议
  18. Linux下使用GPG(GnuPG)加密及解密文件
  19. C2000 系列DSP使用Syscfg配置CLB模块记录
  20. Sea of nodes 中译文

热门文章

  1. mac android手机调试,mac os开发android应用通过usb真机调试
  2. python随机生成验证码_Python生成随机验证码
  3. c语言定义92bit位变量,Keil C51对C语言的关键词扩展之四: bit
  4. 网络拓扑图画图工具_一款功能强大的免费在线作图工具
  5. android textview获取背景颜色,android – 从textview获取背景颜色而不使用ColorDrawable(API 11)...
  6. c语言程序优化设计,C程序设计语言的教学策略优化设计
  7. 正版python怎么下载_怎么下载官网python并安装
  8. 关于前段与后端数据库的连接
  9. Ubuntu16.04下 shell脚本中C语言形式的for循环用法
  10. Linux C语言在用户态实现一个低时延通知(eventfd)+轮询(无锁队列ring)机制的消息队列