前言
要保证程序唯一,有两种方式
- 新程序启动时发现已启动就自动退出
- 新程序启动发现已启动关闭之前的程序
关闭新进程
根据进程
代码语言:javascript复制protected override void OnStartup(StartupEventArgs e)
{
checkProcess();
}
private void checkProcess()
{
Console.WriteLine("程序启动");
//获取欲启动进程名
string ProcessName = Process.GetCurrentProcess().ProcessName;
//检查进程是否已经启动,已经启动则显示报错信息退出程序。
if (Process.GetProcessesByName(ProcessName).Length > 1)
{
MessageBox.Show("当前程序已在运行,请勿重复运行。");
Environment.Exit(1);//退出程序
return;
}
}
互斥锁
代码语言:javascript复制private void checkProcess()
{
//控制当前程序已经打开(即启动)
//利用Mutex互斥量实现同时只有一个进程实例在运行
//互斥锁(Mutex)
//互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。
//互斥锁可适用于一个共享资源每次只能被一个线程访问的情况
bool flag;
string ProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
Mutex hMutex = new Mutex(true, ProcessName, out flag);
hMutex.WaitOne(0, false);
//上面的参数说明:
//第一个参数【initiallyOwned】:true:指示调用线程是否应具有互斥体的初始所有权
//第二个参数【name】:程序唯一name,(当前操作系统中)判定重复运行的标志
//第三个参数【createdNew】:返回值,如果检测到已经启动则返回(false)。
if (!flag)
{
MessageBox.Show("当前程序已在运行,请勿重复运行。");
Environment.Exit(1);//退出程序
return;
}
}
根据事件
代码语言:javascript复制private void checkProcess()
{
Console.WriteLine("程序启动");
bool createNew;
string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
new EventWaitHandle(false, EventResetMode.AutoReset, strProcessName, out createNew);
if (!createNew)
{
MessageBox.Show("当前程序已在运行,请勿重复运行。");
Current.Shutdown();
Environment.Exit(0);
return;
}
}
关闭旧进程
代码语言:javascript复制private static void StopSameProcess()
{
var current = Process.GetCurrentProcess();
string strProcessName = current.ProcessName;
var processList = Process.GetProcessesByName(strProcessName);
foreach (var process in processList)
{
if (process.Id == current.Id) continue;
try
{
MessageBox.Show("当前程序已在运行,请勿重复运行。");
process.Kill(); //结束进程
}
catch (Exception)
{
}
}
}
让进程对应的窗口显示
代码语言:javascript复制[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(int hWnd);
public static void DoOnProcess(string processName)
{
var allProcs = Process.GetProcessesByName(processName);
if (allProcs.Length > 0)
{
Process proc = allProcs[0];
int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
SetForegroundWindow(hWnd);
}
}
两者结合
关闭新进程,旧进程窗口获取焦点
代码语言:javascript复制[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(int hWnd);
private void checkProcess()
{
Console.WriteLine("程序启动");
Process current = Process.GetCurrentProcess();
//获取欲启动进程名
string strProcessName = Process.GetCurrentProcess().ProcessName;
var processList = Process.GetProcessesByName(strProcessName);
if (processList.Length > 1)
{
MessageBox.Show("当前程序已在运行,请勿重复运行。");
foreach (var process in processList)
{
if (process.Id == current.Id) continue;
int hWnd = FindWindow(null, process.MainWindowTitle.ToString());
SetForegroundWindow(hWnd);
}
Environment.Exit(1);//退出程序
return;
}
}