c#只运行一个示例,并把当前程序 显示到最桌面

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);
   }
}
原文地址:https://www.cnblogs.com/wuyaxiansheng/p/13626719.html