C# 限制应用程序的多个实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1207105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Restrict multiple instances of an application
提问by Lloyd Powell
Okay, so i've created my c# application, created an installer for it and have it working installed on my machine.
好的,所以我已经创建了我的 c# 应用程序,为它创建了一个安装程序,并将它安装在我的机器上。
The problem is, when the user opens the application exe twice, there will be two instances of the application running. I only ever want one instance of the application to be running at any time, how do I go about doing this?
问题是,当用户打开应用程序 exe 两次时,将有两个应用程序实例在运行。我只想在任何时候运行一个应用程序实例,我该怎么做?
Thanks for your help,
谢谢你的帮助,
采纳答案by Anton Gogolev
The common technique for this is to create a named Mutex
and check for its presence on application start.
对此的常用技术是创建一个命名Mutex
并在应用程序启动时检查它的存在。
Code from DDJ:
来自 DDJ 的代码:
class App : Form
{
Mutex mutex;
App()
{
Text = "Single Instance!";
mutex = new Mutex(false, "SINGLE_INSTANCE_MUTEX");
if (!mutex.WaitOne(0, false))
{
mutex.Close();
mutex = null;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
mutex.ReleaseMutex();
base.Dispose(disposing);
}
static void Main()
{
App app = new App();
if (app.mutex != null) Application.Run(app);
else MessageBox.Show("Instance already running");
}
}
回答by Alex Black
回答by ckittel
I don't know the environment that you are operating in, but something to keep in mind about 'single-instance applications' is how you define single-instance. If the application can be run on multiple workstations at the same time, using a common datasource, is that an issue? Likewise, what about a terminal-services situation (or a "run as" situation) where more than one user is logged into the same computer, do you want to restrict the application in such a way that only one instance per-user, per-computer? Or are you okay with it simply being one instance per user?
我不知道您正在运行的环境,但是关于“单实例应用程序”需要记住的是您如何定义单实例。如果应用程序可以在多个工作站上同时运行,使用一个公共数据源,这是一个问题吗?同样,对于超过一个用户登录到同一台计算机的终端服务情况(或“运行方式”情况),您是否希望以这样一种方式限制应用程序:每个用户、每个用户只有一个实例? -计算机?或者您是否同意它只是每个用户一个实例?
The answer to these might lead you in one direction over another. For example, we have a 'single-instance' application with the scope being a group of computers. Only one user is allowed on within that group of workstations. We managed this by have a table in our shared data-source that tracked currently connected users. This is a maintenance issue as you need to be sure that table is 100% accurate all the time. Handling things like unexpected power outages on the workstation, leaving "bogus" records in that table took some careful handling.
这些问题的答案可能会将您引向一个方向而不是另一个方向。例如,我们有一个“单实例”应用程序,其范围是一组计算机。在该组工作站中只允许一个用户使用。我们通过在我们的共享数据源中有一个表来跟踪当前连接的用户来管理它。这是一个维护问题,因为您需要确保该表始终 100% 准确。处理工作站上意外断电之类的事情,在该表中留下“虚假”记录需要一些小心处理。
回答by lance
With thanks to Messrs.Allenand Powell:
static void Main()
{
using (Mutex mutex = new Mutex(false, @"Global\" + appGuid)) {
if (!mutex.WaitOne(0, false)) {
string processName = GetProcessName();
BringOldInstanceToFront(processName);
}
else {
GC.Collect();
Application.Run(new Voting());
}
}
}
private static void BringOldInstanceToFront(string processName) {
Process[] RunningProcesses = Process.GetProcessesByName(processName);
if (RunningProcesses.Length > 0) {
Process runningProcess = RunningProcesses[0];
if (runningProcess != null) {
IntPtr mainWindowHandle = runningProcess.MainWindowHandle;
NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_SHOWMINIMIZED);
NativeMethods.ShowWindowAsync(mainWindowHandle, (int) WindowConstants.ShowWindowConstants.SW_RESTORE);
}
}
}
回答by nWorx
i solved this problem by this
我通过这个解决了这个问题
[STAThread]
static void Main()
{
Process[] result = Process.GetProcessesByName("ApplicationName");
if (result.Length > 1)
{
MessageBox.Show("There is already a instance running.", "Information");
System.Environment.Exit(0);
}
// here normal start
}
it is simple, but i had hardly time to check for better solutions.
这很简单,但我几乎没有时间检查更好的解决方案。