从应用程序运行一个实例

我有一个Windows应用程序(C#),我需要将其配置为当时从应用程序运行一个实例,这意味着一个用户单击.exe文件并运行应用程序并且用户没有关闭第一个实例正在运行的应用程序,需要运行下一个实例,因此它应该出现在第一个实例而不是打开新实例。

任何人都可以帮我怎么做?

提前致谢

我经常通过检查具有相同名称的其他进程来解决此问题。 这样做的优点/缺点是你(或用户)可以通过重命名exe来“退出”检查。 如果您不希望这样,您可能会使用返回的Process对象。

string procName = Process.GetCurrentProcess().ProcessName; if (Process.GetProcessesByName(procName).Length == 1) { ...code here... } 

这取决于你的需要,我认为绕过检查没有重新编译是很方便的(它是一个服务器进程,有时作为服务运行)。

VB.Net团队已经实施了一个解决方案。 您将需要依赖Microsoft.VisualBasic.dll,但如果这不打扰你,那么这是一个很好的解决方案恕我直言。 请参阅以下文章的结尾: 单实例应用程序

以下是文章中的相关部分:

1)添加对Microsoft.VisualBasic.dll的引用2)将以下类添加到项目中。

 public class SingleInstanceApplication : WindowsFormsApplicationBase { private SingleInstanceApplication() { base.IsSingleInstance = true; } public static void Run(Form f, StartupNextInstanceEventHandler startupHandler) { SingleInstanceApplication app = new SingleInstanceApplication(); app.MainForm = f; app.StartupNextInstance += startupHandler; app.Run(Environment.GetCommandLineArgs()); } } 

打开Program.cs并添加以下using语句:

 using Microsoft.VisualBasic.ApplicationServices; 

将class级更改为以下内容:

 static class Program { ///  /// The main entry point for the application. ///  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); SingleInstanceApplication.Run(new Form1(), StartupNextInstanceEventHandler); } public static void StartupNextInstanceEventHandler(object sender, StartupNextInstanceEventArgs e) { MessageBox.Show("New instance"); } } 

编辑:修改问题后包括c#。 我的回答仅适用于vb.net应用程序

选中“ 制作单实例应用程序”复选框,以防止用户运行应用程序的多个实例。 清除此复选框的默认设置,允许运行多个应用程序实例。

您可以从项目 – >属性 – >应用程序选项卡执行此操作

资源

我们遇到了完全相同的问题。 我们尝试了流程方法,但如果用户无权读取有关其他流程的信息(即非管理员),则会失败。 所以我们实施了以下解决方案。

基本上我们尝试打开一个独家阅读文件。 如果失败(因为anohter实例已经这样做了),我们得到一个exception并且可以退出应用程序。

  bool haveLock = false; try { lockStream = new System.IO.FileStream(pathToTempFile,System.IO.FileMode.Create,System.IO.FileAccess.ReadWrite,System.IO.FileShare.None); haveLock = true; } catch(Exception) { System.Console.WriteLine("Failed to acquire lock. "); } if(!haveLock) { Inka.Controls.Dialoge.InkaInfoBox diag = new Inka.Controls.Dialoge.InkaInfoBox("App has been started already"); diag.Size = new Size(diag.Size.Width + 40, diag.Size.Height + 20); diag.ShowDialog(); Application.Exit(); } 

假设您正在使用C#

  static Mutex mx; const string singleInstance = @"MU.Mutex"; ///  /// The main entry point for the application. ///  [STAThread] static void Main() { try { System.Threading.Mutex.OpenExisting(singleInstance); MessageBox.Show("already exist instance"); return; } catch(WaitHandleCannotBeOpenedException) { mx = new System.Threading.Mutex(true, singleInstance); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } 

我会在这个场景中使用Mutex 。 或者, Semaphore也可以工作(但是Mutex似乎更合适)。

这是我的示例(来自WPF应用程序,但相同的原则应适用于其他项目类型):

 public partial class App : Application { const string AppId = "MY APP ID FOR THE MUTEX"; static Mutex mutex = new Mutex(false, AppId); static bool mutexAccessed = false; protected override void OnStartup(StartupEventArgs e) { try { if (mutex.WaitOne(0)) mutexAccessed = true; } catch (AbandonedMutexException) { //handle the rare case of an abandoned mutex //in the case of my app this isn't a problem, and I can just continue mutexAccessed = true; } if (mutexAccessed) base.OnStartup(e); else Shutdown(); } protected override void OnExit(ExitEventArgs e) { if (mutexAccessed) mutex?.ReleaseMutex(); mutex?.Dispose(); mutex = null; base.OnExit(e); } } 

我发现这个代码 ,它的工作!

  ///  /// The main entry point for the application. /// Limit an app.to one instance ///  [STAThread] static void Main() { //Mutex to make sure that your application isn't already running. Mutex mutex = new System.Threading.Mutex(false, "MyUniqueMutexName"); try { if (mutex.WaitOne(0, false)) { // Run the application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { MessageBox.Show("An instance of the application is already running.", "An Application Is Running", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Application Error 'MyUniqueMutexName'", MessageBoxButtons.OK, MessageBoxIcon.Information); } finally { if (mutex != null) { mutex.Close(); mutex = null; } } }