7

我想检查用户何时双击应用程序图标,该应用程序的另一个实例尚未运行。

我阅读了有关 My.Application 的信息,但我仍然不知道该怎么做。

4

11 回答 11

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();
        }
    }
于 2008-12-24T12:49:11.467 回答
6

在 VB .NET 中有一个IsSingleInstance布尔属性可以为您完成这项工作。

在 VB 中(取自此处):

Public Class Program
        Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase

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



End Class

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

// 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。

于 2008-12-24T13:35:22.043 回答
3

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

在 Application 选项卡中,您还可以单击View Application Events按钮,以创建一个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
于 2008-12-24T13:44:19.530 回答
2

Scott Hanselman 对此有很好的文章。代码在 C# 中,但我想将它移植到 VB 会很容易。

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

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

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

于 2008-12-24T13:08:36.920 回答
2

在 VB.NET 中,单实例应用程序只是项目属性页上的一个复选框。您还可以捕获My.Application.StartupNextInstance事件,让您的单个实例在另一个副本启动时执行某些操作。例如,这可以用于类似 MDI 的行为,即在原始实例中打开请求的文档。

在幕后,它封装了一些互斥量和 IPC goo - 请参阅WindowsFormApplicationBase - 并且也可以在 C# 中使用。

于 2008-12-24T13:51:16.117 回答
2

通过上面的提示,我发现了如何使我的应用程序成为单个实例,但我仍然必须去另一个站点才能找到确切的方法。这是我如何做到这一点的简单图片。这很容易,我希望它可以帮助其他有同样需求的人,因为我确信 OP 在 7 年前解决了这个问题: 在此处输入图像描述

于 2015-08-23T21:30:01.130 回答
1

使用Mutex. 实际上,aMutex可以用字符串命名,并且在 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);
}

从这篇文章

于 2008-12-24T12:46:13.643 回答
1

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

您还可以使用 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

让我知道这是否有帮助!联合部队

于 2008-12-24T13:44:52.587 回答
0

为您的应用分配一些唯一标识符,例如硬编码的 guid,并创建一个 Mutex 实例,在该实例中将互斥锁分配给该标识符。如果它引发异常,则表示您的应用程序已经在运行(因为它成功地创建了互斥锁)

于 2008-12-24T12:51:12.337 回答
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;
    }
于 2008-12-24T13:20:49.093 回答
-1

最常见的模式是使用单例模式。由于您没有指出一种语言,我将假设您在这里指的是 C# - 如果不是,则大多数 OO 语言中的原则仍然相同。

这篇文章应该能给你一些帮助。

于 2008-12-24T12:25:11.080 回答