【问题标题】:How can I prevent launching my app multiple times?如何防止多次启动我的应用程序?
【发布时间】:2013-02-13 10:42:17
【问题描述】:

我使用 ClickOnce 安装部署了我的 C# WinForms 应用程序。一切正常(经过大量工作):),但现在我面临一个问题:

每当我单击“开始”菜单中的应用程序快捷方式时,都会启动一个新实例。我需要避免这种情况。

如何防止多次启动?

【问题讨论】:

标签: c# deployment clickonce


【解决方案1】:

使用此代码:

[STAThread]
static void Main() 
{
   using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
   {
      if(!mutex.WaitOne(0, false))
      {
         MessageBox.Show("Instance already running");
         return;
      }

      Application.Run(new Form1());
   }
}

来自The Misunderstood Mutex

【讨论】:

  • 我使用了与上面不同的互斥代码,它在本地工作,但是一旦我开始使用 ClickOnce,它就不起作用了。上面的代码在 ClickOnce 中对我有用
  • @harag - 很高兴为您提供帮助 :) 如果对您有用,请投票给答案
  • 您从哪里获得 appGuid?
  • 如果你使用没有显式 main 方法的 C#/WPF 怎么办?我不想显式声明一个 main,因为它是自动生成的,带有一些额外的内容。
【解决方案2】:

当启动你的应用程序时,main 总是调用Application.Run()。查看您的 STAThread-Main 方法和 Application.Run 测试之前是否有您的 .exe 正在运行的实例。

Process p = Process.GetProcesses();
//check for your .exe

在此处查看this 帖子。

【讨论】:

    【解决方案3】:

    关于这件事确实有很好的话题。你可以在这里找到它:using Mutext。

    【讨论】:

      【解决方案4】:

      在程序启动时检查相同的进程是否已经在运行:

      using System.Diagnostics;
      
      static void Main(string[] args)
      {
         String thisprocessname = Process.GetCurrentProcess().ProcessName;
      
         if (Process.GetProcesses().Count(p => p.ProcessName == thisprocessname) > 1)
            return;           
      }
      

      【讨论】:

      【解决方案5】:

      使用Mutex 是可行的方法,因为猜测进程名称充满了缺陷和麻烦。看看这个真的很好illustration

      【讨论】:

      【解决方案6】:

      有时**Mutex** 在某些区域不起作用。就像在控制台应用程序中使用一样。所以我尝试使用 WMI 查询。

      试试这个,它会起作用的。

              /// <summary>
              /// The main entry point for the application.
              /// </summary>
              [STAThread]
              static void Main()
              {
                  if (!isStillRunning())
                  {
                     Application.Run(new Form1());
                   }
                   else {
                       MessageBox.Show("Previous process still running.",
                          "Application Halted", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                       Application.Exit();
                   }      
              }
      
              //***Uses WMI Query
              static bool isStillRunning() {
                  string processName = Process.GetCurrentProcess().MainModule.ModuleName;
                  ManagementObjectSearcher mos = new ManagementObjectSearcher();
                  mos.Query.QueryString = @"SELECT * FROM Win32_Process WHERE Name = '" + processName + @"'";
                  if (mos.Get().Count > 1)
                  {
                     return true;
                  }
                  else
                     return false;
              }
      

      希望对你有帮助。

      【讨论】:

        【解决方案7】:

        我一直用的是

        bool checkSingleInstance()
            {
                string procName = Process.GetCurrentProcess().ProcessName;
                // get the list of all processes by that name
        
                Process[] processes = Process.GetProcessesByName(procName);
        
                if (processes.Length > 1)
                {
        
                    return true;
                }
                else
                {
                    return false;
                }
            }
        

        【讨论】:

          【解决方案8】:

          解决Windows窗体应用程序禁止再次运行应用程序(重新打开应用程序)。

          1-首先添加Class RunAlready.cs

          2-从Program.cs中的RunAlready.cs调用方法processIsRunning()

          程序.cs:

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Threading.Tasks;
          using System.Windows.Forms;
          
          namespace Tirage.MainStand
          {
          static class Program
          {
          
              /// <summary>
              /// The main entry point for the application.
              /// </summary>
              [STAThread]
              static void Main()
              {
                  PublicClass.Class.RunAlready RunAPP = new PublicClass.Class.RunAlready();
                  string outApp = RunAPP.processIsRunning("Tirage.MainStand");
          
                  Application.EnableVisualStyles();
                  Application.SetCompatibleTextRenderingDefault(false);
                  MainStand_FrmLogin fLogin = new MainStand_FrmLogin();
                  if (outApp.Length == 0)
                  {
          
                      if (fLogin.ShowDialog() == DialogResult.OK)
                      {
                          Application.Run(new MainStand_masterFrm());
          
                      }
                  }
                  else MessageBox.Show( "Instance already running");
          
                }
              }
           }
          

          类 RunAlready:

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Text;
          using System.Threading.Tasks;
          
          namespace PublicClass.Class
          {
            public  class RunAlready
              {
                public  string processIsRunning(string process)
                  {
                  string xdescription = "";
                  System.Diagnostics.Process[] processes =
                      System.Diagnostics.Process.GetProcessesByName(process);
                  foreach (System.Diagnostics.Process proc in processes)
                  {
                      var iddd = System.Diagnostics.Process.GetCurrentProcess().Id;
                      if (proc.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
                      {
                          xdescription = "Application Run At time:" + proc.StartTime.ToString() + System.Environment.NewLine;
                          xdescription += "Current physical memory : " + proc.WorkingSet64.ToString() + System.Environment.NewLine;
                          xdescription += "Total processor time : " + proc.TotalProcessorTime.ToString() + System.Environment.NewLine;
                          xdescription += "Virtual memory size : " +         proc.VirtualMemorySize64.ToString() + System.Environment.NewLine;
                      }
                  }
          
          
                  return xdescription;
              }
          }
          }
          

          【讨论】:

            【解决方案9】:
             if (Process.GetProcesses().Count(p => p.ProcessName == "exe name") > 1)
                {
                    foreach (var process in 
             Process.GetProcessesByName("exe name"))
                    {
                        process.Kill();
                    }
                }
            

            【讨论】:

              【解决方案10】:

              在 WPF 中,您可以在 App.xaml.cs 文件中使用此代码:

              private static System.Threading.Mutex _mutex = null;
              
              protected override void OnStartup(StartupEventArgs e)
              {
                  string mutexId = ((System.Runtime.InteropServices.GuidAttribute)System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false).GetValue(0)).Value.ToString();
                  _mutex = new System.Threading.Mutex(true, mutexId, out bool createdNew);
                  if (!createdNew) Current.Shutdown();
                  else Exit += CloseMutexHandler;
                  base.OnStartup(e);
              }
              protected virtual void CloseMutexHandler(object sender, EventArgs e)
              {
                  _mutex?.Close();
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-06-13
                • 2022-01-02
                • 1970-01-01
                • 2012-01-19
                • 2011-10-25
                • 1970-01-01
                相关资源
                最近更新 更多