在.NET中,检测同一程序的实例是否已在运行的最可靠方法是什么?此外,将命令行参数传递给已经运行的实例的最佳方法是什么(例如,打开特定文档)?
答案 0 :(得分:3)
在.NET程序中似乎有三种众所周知的实现单实例应用程序的方法:进程方法,Mutex方法和Visual Basic方法。
迈克尔·科文顿在他的提示{2}中讨论了前两个。有一个Ensuring that only a single instance of a .NET application is running更详细地讨论了Mutex方法,包括获取现有应用程序的窗口句柄,以便您可以(以某种方式)与它进行通信。
另一个CodeProject article描述了如何使用Microsoft.VisualBasic命名空间中的类(可从C#访问)来实现单实例应用程序。
我对第三种方法一点也不熟悉。在前两个中,它们都有效,但正如链接文章中指出的那样,Mutex方法看起来更强大。我不知道为什么选择Mutex作为要使用的命名对象。任何命名的同步对象(EventWaitHandle,Mutex,Semaphore等)都可以工作。
与现有应用程序进行通信会带来更多问题。我建议你研究使用命名管道,如果你需要做的就是向正在运行的应用程序发送一个相对较小的消息。查看CodeProject article了解详情。
我还应该注意,如果你担心安全性,你需要保护你使用的任何通信方法。任何具有足够权限的应用程序都可以通过命名管道向正在运行的应用程序发送信息。
答案 1 :(得分:1)
您可以使用.Net远程处理(.Net 2.0)或WCF(.Net 3.5)在相同或不同计算机上的程序之间进行通信。
您无法将命令行参数传递给已在运行的程序。您可以使用您想要的任何方法将任何数据传递给它,但它必须有意识地处理这些数据。它不会神奇地用作命令行参数
答案 2 :(得分:0)
我不知道这是不是最好的方法。我使用一个单独的对象,它基本上只是一个容纳命名互斥锁的地方。如果应用程序尝试运行两次,它会检查互斥锁是否正在使用,如果是,则会停止执行,因此无法运行两次。
然而,我不确定如何与已经运行的应用程序对话。
答案 3 :(得分:0)
“将命令行参数传递给已经运行的实例的最佳方法是什么(例如打开特定文档)?
不幸的是我不相信这是可能的。应用程序可以使用Console.ReadLine()从标准输入获取输入,但这与传入命令行参数不同。
通过.NET进行进程间通信还有其他几种方法。 .NET Remoting和WCF,以及您自己的自定义套接字协议。
您可以使用System.Diagnostics命名空间来收集正在运行的进程列表。
答案 4 :(得分:-1)
要确定应用程序是否正在运行,请不要使用Mutex,因为它有很大的开销。使用
using System.Diagnostics;
public bool IsProcessOpen(string name)
{
foreach (Process clsProcess in Process.GetProcesses) {
if (clsProcess.ProcessName.Contains(name)) return true;
}
return false;
}
您提供的有关此“其他应用程序”的信息越多越好。如果您开发了“其他应用程序”,则可以将某些数据序列化到其他应用程序,以便让它知道您希望它获取的其他信息。查看.NET框架XMLSerializer。您甚至可以使用数据库条目执行简单的操作。您可以使用UDP数据包。有很多方法可以与另一个程序进行通信。问题是,其他程序是什么?