如何确保有一个应用程序实例正在运行

时间:2008-12-24 12:19:12

标签: vb.net single-instance

我想检查用户双击应用程序图标时该应用程序的另一个实例是否已在运行。

我读到了My.Application,但我仍然不知道该怎么做。

11 个答案:

答案 0 :(得分:8)

这是我用过的东西......(.NET 2.0上的C#)

    [STAThread]
    private static void Main(string[] args)
    {
        //this follows best practices on
        //ensuring that this is a single instance app.
        string mutexName = "e50cf829-f6b9-471e-8d9f-67eac3699f09";
        bool grantedOwnership;
        //we prefix the mutexName with "Local\\" to allow this to run under terminal services.
        //The "Local\\" prefix forces this into local user space.
        //If we want to forbid this in TS, use the "Global\\" prefix.
        Mutex singleInstanceMutex = new Mutex(true, "Global\\" + mutexName, out grantedOwnership);
        try
        {
            if (!grantedOwnership)
            {
                MessageBox.Show("Error: X is already running.\n\nYou can only run one copy of X at a time.", "X", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                Application.Exit();
            }
            else
            {
                Application.Run(new X(args));
            }
        }
        finally
        {
            singleInstanceMutex.Close();
        }
    }

答案 1 :(得分:6)

在VB .NET中,有一个IsSingleInstance布尔属性可以帮你完成工作。

在VB中(取自here):

Public Class Program
        Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase

       Public Sub New()
            Me.IsSingleInstance = True
        End Sub



End Class

以下是您在C#中使用它的方法(取自here):

// SingleInstanceApplication.cs
class SingleInstanceApplication : WindowsFormsApplicationBase {

 // Must call base constructor to ensure correct initial 
 // WindowsFormsApplicationBase configuration
 public SingleInstanceApplication() {

  // This ensures the underlying single-SDI framework is employed, 
  // and OnStartupNextInstance is fired
  this.IsSingleInstance = true;
 }
}


// Program.cs
static class Program {
 [STAThread]
 static void Main(string[] args) {
  Application.EnableVisualStyles();
  SingleInstanceApplication application = 
   new SingleInstanceApplication();
  application.Run(args);
 }
}

确保在项目中引用Microsoft.VisualBasic.dll。

答案 2 :(得分:3)

打开您的项目属性(应用程序选项卡)并选中制作单实例应用程序选项。

在“应用程序”选项卡中,您还可以单击查看应用程序事件按钮,以创建 ApplicationEvents.vb 类,您可以在其中处理第二个实例事件:

Partial Friend Class MyApplication
    Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
        ' Bring First Instance to Foreground
        e.BringToForeground = True
        ' Pass Second Instance Command Line to First Instance
        AppShared.DoSomethingWithCommandLine(e.CommandLine)
    End Sub
End Class

答案 3 :(得分:2)

斯科特汉塞尔曼有一篇很好的文章。代码在C#中,但我想将它移植到VB很容易。

http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx

如果不能满足您的需求,还有一篇关于该主题的文章:

http://www.codeproject.com/KB/cs/cssingprocess.aspx

答案 4 :(得分:2)

在VB.NET中,单个实例应用只是a checkbox on the Project property page。您还可以捕获My.Application.StartupNextInstance事件,以便在启动另一个副本时让您的单个实例执行某些操作。例如,这可以用于在原始实例中打开所请求文档的MDI行为。

在幕后,这包含了很多互斥和IPC goo - 请参阅WindowsFormApplicationBase - 并且也可以在C#中使用。

答案 5 :(得分:2)

通过上面的提示,我发现了如何让我的应用程序成为一个实例,但我仍然必须去另一个网站,以确切了解如何。这是一个简单的图片,我是如何做到这一点的。这很容易,我希望它可以帮助其他人有相同的需求,因为我确信OP在7年前解决了这个问题: enter image description here

答案 6 :(得分:1)

使用Mutex。实际上,Mutex可以用字符串命名,并且在CLR中是唯一的。

示例代码:

try
{
mutex = Mutex.OpenExisting(mutexName);
//since it hasn’t thrown an exception, then we already have one copy of the app open.
MessageBox.Show(”A copy of Todo 3.0 is already open. Please check your system tray (notification area).”,
“Todo 3.0″, MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(0);
}
catch (Exception Ex)
{
//since we didn’t find a mutex with that name, create one
Debug.WriteLine(”Exception thrown:” + Ex.Message + ” Creating a new mutex…”);
mutex = new Mutex(true, mutexName);
}

从此post

答案 7 :(得分:1)

如果您的应用程序是在VB.NET 2.0-3.5中,保持程序的单个实例运行的最简单方法是使用“Windows应用程序框架属性”。要实现这一目标,请右键单击项目名称并转到“属性”。在那里,选择“Make single instance appliation”复选框。

您还可以使用ApplicationEvents.vb向用户显示他们第二次运行您的程序。您可以通过选择“查看应用程序事件”按钮在同一属性窗口中轻松创建/查看。在那里,您可以选择MyApplication_StartupNextInstance子并在那里输入代码,如下所示:

Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
    MessageBox.Show("This program is already running.  If you do not see the program running, please check your " _
        & "Windows Task Manager for this program name in the 'Processes' Tab." & vbNewLine & vbNewLine & "WARNING: " _
        & " If you terminate the process, you will terminate the only instance of this program!", My.Application.Info.ProductName.ToString _
        & " is Running!", MessageBoxButtons.OK, MessageBoxIcon.Warning)

End Sub

如果这有帮助,请告诉我! JFV

答案 8 :(得分:0)

为您的应用分配一些唯一标识符,例如硬编码的guid,并创建一个Mutex实例,您可以在其中为该标识符指定互斥锁。如果它抛出一个异常,那么意味着你的应用程序已经在运行(因为它成功设法创建了互斥锁)

答案 9 :(得分:0)

我认为将样本放在这里而不是链接会更容易。

    [STAThread]
    static void Main()
    {
        if (!IsAppAlreadyRunning())
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1()); /* Change Form1 for your main Form */
        }
        else
        {
            MessageBox.Show("Application is already running!");
        }
    }

    public static bool IsAppAlreadyRunning()
    {
        Process currentProcess = Process.GetCurrentProcess();
        return (IsAppAlreadyRunning(currentProcess.Id, 
                                    currentProcess.ProcessName));
    }

    private static bool IsAppAlreadyRunning(int ID, string Name)
    {
        bool isAlreadyRunning = false;
        Process[] processes = Process.GetProcesses();
        foreach (Process process in processes)
        {
            if (ID != process.Id)
            {
                if (Name == process.ProcessName)
                {
                    isAlreadyRunning = true;
                    break;
                }
            }
        }
        return isAlreadyRunning;
    }

答案 10 :(得分:-1)

执行此操作的最常见模式是使用Singleton模式。由于你没有指出一种语言,我假设你在这里指的是C# - 如果没有,大多数OO语言的原则仍然是相同的。

This文章应该会给你一些帮助。