c#只运行一个示例,并把当前程序 显示到最桌面
最近程序写的有问题,需要只运行一个实例,于是上网查 发现有两个方法,一个就是使用互斥量(System.Threading.Mutex),另一个就是使用进程名。
具体方法如下
互斥量
bool createNew;
using (System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out createNew))
{
if (createNew)
{
//这里写你需要运行的主程序
}
else
{
MessageBox.Show("应用程序已经在运行中...")
System.Environment.Exit(0);
}
}
进程名
Process[] processes = System.Diagnostics.Process.GetProcessesByName(Application.CompanyName);
if (processes.Length > 1)
{
MessageBox.Show("应用程序已经在运行中。。");
System.Environment.Exit(0);
}
else
{
//这里写你需要运行的主程序
}
但是这两种方法都是会提示你 有一个进程正在运行了,对于有用户界面的操作来说 十分不友好,最好是 如果有程序已经在运行了直接把正在运行的程序摆在桌面上,这样感觉就会更友好一些,代码如下
需要调用win32 的api
#region <<窗口状态码>>
/// <summary>
/// 关闭窗口
/// </summary>
private const int WIN_CLOSE = 0;
/// <summary>
/// 正常大小显示窗口
/// </summary>
private const int WIN_NOMAIL = 1;
/// <summary>
/// 最小化窗口
/// </summary>
private const int WIN_MIN = 2;
/// <summary>
/// 最大化窗口
/// </summary>
private const int WIN_MAX = 3;
#endregion
#region <<win32 api>>
/// <summary>
/// 该函数设置由不同线程产生的窗口的显示状态
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
/// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// 把窗口展示出来
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="nCmdShow">窗口状态码</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
#endregion
#region<<封装函数>>
/// <summary>
/// 将进程的窗口显示到桌面最前端
/// </summary>
/// <param name="instance">进程</param>
private static void HandleRunningInstance(Process instance)
{
/*这里需要注意的是 根据自己的需要决定使用 ShowWindowAsync 还是 ShowWindow */
ShowWindowAsync(instance.MainWindowHandle, WIN_NOMAIL);
SetForegroundWindow(instance.MainWindowHandle);
}
/// <summary>
/// 查找当前进程是否有跟自己一样的进程
/// </summary>
/// <returns>进程</returns>
private static Process RuningInstance()
{
Process currentProcess = Process.GetCurrentProcess();
Process[] Processes = Process.GetProcessesByName(currentProcess.ProcessName);
foreach (Process process in Processes)
{
if (process.Id != currentProcess.Id)
{
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\") == currentProcess.MainModule.FileName)
{
return process;
}
}
}
return null;
}
#endregion
调用方法
public static void Main(string[] args)
{
/*判断是不是重复打开本程序*/
Process process = RuningInstance();
if (process == null)
{
/*进程种没有前程序,new一个新实例来运行(App 是你要运行的主程序)*/
App app = new App();
app.Run();
}
else
{
/*进程种有当前程序,把找的的进程激活,并显示到桌面上*/
HandleRunningInstance(process);
}
}