限制应用程序的多个实例

时间:2022-01-02 10:55:53

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,

谢谢你的帮助,

5 个解决方案

#1


9  

The common technique for this is to create a named Mutex and check for its presence on application start.

常见的技术是创建一个名为Mutex并检查它在应用程序启动时的存在。

See this or this.

看到这个或这个。

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");
    }
}

#2


8  

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.

这很简单,但我没有时间检查更好的解决方案。

#3


4  

With thanks to Messrs. Allen and Powell:

感谢Allen和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);
            }
        }
    }

#5


0  

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%准确。处理工作站上意外断电等事情,在该表中留下“伪造”记录需要小心处理。

#1


9  

The common technique for this is to create a named Mutex and check for its presence on application start.

常见的技术是创建一个名为Mutex并检查它在应用程序启动时的存在。

See this or this.

看到这个或这个。

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");
    }
}

#2


8  

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.

这很简单,但我没有时间检查更好的解决方案。

#3


4  

With thanks to Messrs. Allen and Powell:

感谢Allen和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);
            }
        }
    }

#4


#5


0  

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%准确。处理工作站上意外断电等事情,在该表中留下“伪造”记录需要小心处理。