原文:DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

网上关于C#单例运行程序的方法都是比较简单,有些甚至是无法实现功能的,不知道他们试没试过就发帖,因为自己之前都是用第三方控件DevExpress,单例运行也是用它本身自带的一个方法,调用此方法需要引用DevExpress的DevExpress.DevAV.v17.1.Data.dll


  1. static void Main()
  2. {
  3. var appName= Process.GetCurrentProcess().ProcessName;
  4. using (DevExpress.Internal.DevAVDataDirectoryHelper.SingleInstanceApplicationGuard(appName, out exit))
  5. {
  6. if (exit)
  7. return;
  8. Application.EnableVisualStyles();
  9. Application.SetCompatibleTextRenderingDefault(false);
  10. Application.Run(new Form1());
  11. }
  12. }

以前懒,看到有现成的就拿现成的,也没去想具体如何实现,刚好有人问起,才决定去看看源码,发现DevExpress的这个方法原来是用了Mutex来实现的,整合了一下资料,重新写一个供C#桌面应用程序通用的单例运行方法,代码如下:

其中需要引用以下命名空间:


  1. using System;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. using System.Security;
  6. using System.Threading;

  1. /// <summary>
  2. /// 单实例应用程序--by涛神
  3. /// </summary>
  4. public class SingleInstanceApplication
  5. {
  6. /// <summary>
  7. /// 判断应用是否运行
  8. /// </summary>
  9. /// <param name="processName"></param>
  10. /// <param name="exit"></param>
  11. /// <returns></returns>
  12. public static IDisposable Guard(out bool exit)
  13. {
  14. Process currentProcess = Process.GetCurrentProcess();
  15. var processName = currentProcess.ProcessName;
  16. Mutex mutex = new Mutex(true, processName, out bool createNew);
  17. if (createNew)
  18. {
  19. exit = false;
  20. }
  21. else
  22. {
  23. Process[] processesByName = Process.GetProcessesByName(currentProcess.ProcessName);
  24. int num = 0;
  25. while (num < (int)processesByName.Length)
  26. {
  27. Process process = processesByName[num];
  28. if (process.Id == currentProcess.Id || !(process.MainWindowHandle != IntPtr.Zero))
  29. {
  30. num++;
  31. }
  32. else
  33. {
  34. WinApiHelper.SetForegroundWindow(process.MainWindowHandle);
  35. WinApiHelper.RestoreWindowAsync(process.MainWindowHandle);
  36. break;
  37. }
  38. }
  39. exit = true;
  40. }
  41. return mutex;
  42. }
  43. private static class WinApiHelper
  44. {
  45. [SecuritySafeCritical]
  46. public static bool IsMaxmimized(IntPtr hwnd)
  47. {
  48. WinApiHelper.Import.WINDOWPLACEMENT wINDOWPLACEMENT = new WinApiHelper.Import.WINDOWPLACEMENT();
  49. if (!WinApiHelper.Import.GetWindowPlacement(hwnd, ref wINDOWPLACEMENT))
  50. {
  51. return false;
  52. }
  53. return wINDOWPLACEMENT.showCmd == WinApiHelper.Import.ShowWindowCommands.ShowMaximized;
  54. }
  55. [SecuritySafeCritical]
  56. public static bool RestoreWindowAsync(IntPtr hwnd)
  57. {
  58. return WinApiHelper.Import.ShowWindowAsync(hwnd, (WinApiHelper.IsMaxmimized(hwnd) ? 3 : 9));
  59. }
  60. [SecuritySafeCritical]
  61. public static bool SetForegroundWindow(IntPtr hwnd)
  62. {
  63. return WinApiHelper.Import.SetForegroundWindow(hwnd);
  64. }
  65. private static class Import
  66. {
  67. [DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
  68. public static extern bool GetWindowPlacement(IntPtr hWnd, ref WinApiHelper.Import.WINDOWPLACEMENT lpwndpl);
  69. [DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
  70. public static extern bool SetForegroundWindow(IntPtr hWnd);
  71. [DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
  72. public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
  73. public enum ShowWindowCommands
  74. {
  75. Hide,
  76. Normal,
  77. ShowMinimized,
  78. ShowMaximized,
  79. ShowNoActivate,
  80. Show,
  81. Minimize,
  82. ShowMinNoActive,
  83. ShowNA,
  84. Restore,
  85. ShowDefault,
  86. ForceMinimize
  87. }
  88. public struct WINDOWPLACEMENT
  89. {
  90. public int length;
  91. public int flags;
  92. public WinApiHelper.Import.ShowWindowCommands showCmd;
  93. public Point ptMinPosition;
  94. public Point ptMaxPosition;
  95. public Rectangle rcNormalPosition;
  96. }
  97. }
  98. }
  99. }

调用的demo如下,亲测可以,若无法实现的请留言讨论(本文章是原创文章,转载请标明,盗版必究,觉得文章对你帮助的可以点个赞表示支持一下,谢谢):


  1. static void Main()
  2. {
  3. using(SingleInstanceApplication.Guard(out bool exit))
  4. {
  5. if (exit)
  6. return;
  7. Application.EnableVisualStyles();
  8. Application.SetCompatibleTextRenderingDefault(false);
  9. Application.Run(new Form1());
  10. }
  11. }

DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法的更多相关文章

  1. java——多线程——单例模式的static方法和非static方法是否是线程安全的?

    单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...

  2. synchronized 修饰在 static方法和非static方法的区别

    Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...

  3. Java中synchronized 修饰在static方法和非static方法的区别

    [问题描述]关于Java中synchronized 用在实例方法和对象方法上面的区别 [问题分析]大家都知道,在Java中,synchronized 是用来表示同步的,我们可以synchronized ...

  4. 关于C#单例Singleton的看法和使用

    首先明白一点,什么是单例模式? 单例模式是指一个类在一个应用程序运行时仅仅实例化一次,以后所有的调用都使用第一次实例化的对象,是应用程序级别的,与session,用户等无关,它比全局参数或静态类方式更 ...

  5. iOS——Swift开发中的单例设计模式(摘译,非原创)

    最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子 ...

  6. java static成员变量方法和非static成员变量方法的区别

    这里的普通方法和成员变量是指,非静态方法和非静态成员变量首先static是静态的意思,是修饰符,可以被用来修饰变量或者方法. static成员变量有全局变量的作用       非static成员变量则 ...

  7. 表单元素的submit()方法和onsubmit事件

    1.表单元素中出现了name="submit"的元素 2.elemForm.submit();不会触发表单的onsubmit事件 3.动态创建表单时遇到的问题 表单元素拥有subm ...

  8. 表单元素的submit()方法和onsubmit事件(转)

    1.表单元素中出现了name="submit"的元素 2.elemForm.submit();不会触发表单的onsubmit事件 3.动态创建表单时遇到的问题 表单元素拥有subm ...

  9. static方法和非static方法的区别

    ●生命周期(Lifecycle):静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭. ...

随机推荐

  1. 搭建Keepalived+LNMP架构web动态博客 实现高可用与负载均衡

    环境准备: 192.168.193.80  node1 192.168.193.81 node2 关闭防火墙 [root@node1 ~]# systemctl stop firewalld #两台都 ...

  2. 动态规划—distinct-subsequences

    题目: Given a string S and a string T, count the number of distinct subsequences of T in S. A subseque ...

  3. luogu4061 大吉大利,晚上吃鸡!

    链接 最短路径\(dag\),一道好题. 题目大意:求一张图中满足下列要求的点对\((i,j)\)数量: 所有最短路径必定会经过 \(i\) 点和 \(j\) 点中的任意一点. 不存在一条最短路同时经 ...

  4. Thread类与Runnable接口

    Runnable 先看看源码中对Runnable的声明 @FunctionalInterface public interface Runnable { /** * When an object im ...

  5. python tkinter画圆

    x0=150    #圆心横坐标 y0=100    #圆心纵坐标 canvas.create_oval(x0-10,y0-10,x0+10,y0+10)    #圆外矩形左上角与右下角坐标 canv ...

  6. QTimer不能同时使用两个,用QTimerEvent (QT)

    最近写程序的时候有个界面想定两个QTimer定时器,不同时间干不同的事: QTimer *timer1 = new QTimer(this); QTimer *timer2 = new QTimer( ...

  7. idea返回git上历史版本

    1.首先找到之前想要返回得版本号 2.直接下载此版本号即可 在这里填入1步骤得版本号即可检出,其实这个检出利时版本和检出其他分支是同一个道理

  8. 微信公众号号开发(Java)

    参考:http://www.cnblogs.com/fengzheng/p/5023678.html http://www.cnblogs.com/xdp-gacl/p/5151857.html 一: ...

  9. swan.after

    解释: swan.after可以拦截所有当前运行小程序对于API的调用,默认传入function时,只在API函数调用的返回阶段拦截.如果传入Object,则可以选择拦截的阶段(例如: 返回阶段.回调 ...

  10. Xcode编辑器之快捷键的使用

    一,快捷键图标 图标 键盘 ⌘ Command ⌃ Control ⌥ Option ⇧ Shift 二, 常用快捷键 文件快捷键 快捷键 键盘  描述 ⌘N  command + N 新文件 ⇧⌘N ...