如何强制C# .net应用程序在Windows中只运行一个实例?
可能重复:
什么是创建单个实例应用程序的正确方法?
我更喜欢以下类似的互斥锁解决方案。因为这样,如果应用程序已经加载,它会重新聚焦于该应用程序。
using System.Threading;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool createdNew = true;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
{
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}
如果想要在 .net (C#) 中强制运行程序的唯一实例,可以在 program.cs 文件中使用以下代码:
public static Process PriorProcess()
// Returns a System.Diagnostics.Process pointing to
// a pre-existing process with the same name as the
// current one, if any; or null if the current process
// is unique.
{
Process curr = Process.GetCurrentProcess();
Process[] procs = Process.GetProcessesByName(curr.ProcessName);
foreach (Process p in procs)
{
if ((p.Id != curr.Id) &&
(p.MainModule.FileName == curr.MainModule.FileName))
return p;
}
return null;
}
[STAThread]
static void Main()
{
if (PriorProcess() != null)
{
MessageBox.Show("Another instance of the app is already running.");
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
Process.GetProcessesByName
会抛出异常。 - George T这是我在应用程序中使用的:
static void Main()
{
bool mutexCreated = false;
System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );
if( !mutexCreated )
{
if( MessageBox.Show(
"slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
"slimKEYS already running",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question ) != DialogResult.Yes )
{
mutex.Close();
return;
}
}
// The usual stuff with Application.Run()
mutex.Close();
}
单例应用程序的另一种方法是检查它们的哈希值。 在尝试使用互斥锁解决问题后(没有达到我的要求),我通过以下方式使其正常运行:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public Main()
{
InitializeComponent();
Process current = Process.GetCurrentProcess();
string currentmd5 = md5hash(current.MainModule.FileName);
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
if (process.Id != current.Id)
{
try
{
if (currentmd5 == md5hash(process.MainModule.FileName))
{
SetForegroundWindow(process.MainWindowHandle);
Environment.Exit(0);
}
}
catch (/* your exception */) { /* your exception goes here */ }
}
}
}
private string md5hash(string file)
{
string check;
using (FileStream FileCheck = File.OpenRead(file))
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] md5Hash = md5.ComputeHash(FileCheck);
check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower();
}
return check;
}
它仅通过进程ID检查MD5摘要。
如果找到此应用程序的实例,则会将焦点放在运行的应用程序上并退出自身。
您可以重命名它或对文件进行任何操作。如果MD5哈希值相同,则不会打开两次。
是否有人对此有建议?我知道已经有答案了,但也许有人正在寻找互斥替代方案。
"MyApplicationName"
应该是程序集的名称、解决方案/项目的名称还是 GUI 窗口的标题?似乎两种方式都可以工作(使用"MyApplicationName"
也可以)。 - user1021726ShowWindow(process.MainWindowHandle, SW_RESTORE)
来将其恢复。 https://dev59.com/k2455IYBdhLWcg3wD_sB 提供了详细信息。SW_RESTORE是9(来自http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633548%28v=vs.85%29.aspx)。 - davidm_uk