zoukankan      html  css  js  c++  java
  • C#:只运行一个程序

    一、通过系统事件

    1、实现如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Runtime.InteropServices;
    
    namespace Example
    {
        public class SinglonProgram
        {
    
            #region 字段
    
            //显示的主窗体
            private Form mainForm;
    
            //线程同步事件
            private static EventWaitHandle programWaitHandle;
    
            #endregion
    
            #region 属性
    
            #endregion
    
            #region 构造函数
    
            public SinglonProgram(Form showForm)
            {
                this.mainForm = showForm;
    
                //注册一个等待WaitHandle的委托
                ThreadPool.RegisterWaitForSingleObject(programWaitHandle, (obj, timeOut) =>
                {
                    ShowForm();
                },
                null, -1, false);
    
            }
    
            #endregion
    
            #region 私有函数  显示窗体、等
    
            /// <summary>
            /// 显示窗体
            /// </summary>
            private void ShowForm()
            {
                //在拥有mainForm窗体的线程上执行无参委托(Action)
                this.mainForm.Invoke(new Action(() =>
                    {
                        this.mainForm.Visible = true;
                        if(this.mainForm.WindowState == FormWindowState.Minimized)
                        {
                            this.mainForm.WindowState = FormWindowState.Normal;
                        }
                        this.mainForm.Show();
    
                        bool isForeground = SetForegroundWindow(this.mainForm.Handle);
                        MessageBox.Show(isForeground.ToString());
                    }
                ));
            }
    
            #endregion
    
            #region 公共函数  只有一个程序运行
    
            /// <summary>
            /// 是否创建了已命名的系统事件
            /// </summary>
            /// <returns></returns>
            public static bool isNamedSystemEvent()
            {
                bool createdNew;
                programWaitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, Application.ProductName, out createdNew);
                return !createdNew;
            }
    
            /// <summary>
            /// 确保只有一个程序运行
            /// </summary>
            public static void Confirm()
            {
                // 如果该命名事件已命名(运行实例已经存在),则发事件通知并退出
                if (isNamedSystemEvent())
                {
                    programWaitHandle.Set();    //将事件状态设置为终止状态,允许一个或多个等待线程继续
                    Environment.Exit(1);
                }
            }
    
            #endregion
    
            #region 接口函数 激活窗体且前端显示等
    
            /// <summary>
            /// 前端显示且激活窗体
            /// </summary>
            /// <param name="hWnd">窗体句柄</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
    
    
            #endregion
    
            #region 虚函数
    
            #endregion
        }
    }
    View Code

    2、调用如下:

     static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                SinglonProgram.Confirm();
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new frmMain());
            }
        }
    View Code

    二、通过查询线程

    具体如下:(测试时发现,不调试和调试区别下会产生两个程序)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Reflection;
    
    namespace Test
    {
        static class Program
        {
            /// <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);
            private const int WS_SHOWNORMAL = 1;
    
    
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Process instance = RunningInstance();
                if (instance == null)
                {
                    Form1 frm = new Form1();
                    Application.Run(new Form1());
                }
                else
                {
                    HandleRunningInstance(instance);
                }
    
            }
    
            /// <summary>
            /// 获取正在运行的实例,没有运行的实例返回null;
            /// </summary>
            public static Process RunningInstance()
            {
                Process current = Process.GetCurrentProcess();
                Process[] processes = Process.GetProcessesByName(current.ProcessName);
                foreach (Process process in processes)
                {
                    if (process.Id != current.Id)
                    {
                        if (Assembly.GetExecutingAssembly().Location.Replace("/", "\") == current.MainModule.FileName)
                        {
                            return process;
                        }
                    }
                }
                return null;
            }
    
            /// <summary>
            /// 显示已运行的程序。
            /// </summary>
            public static void HandleRunningInstance(Process instance)
            {
                ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //显示,可以注释掉
                SetForegroundWindow(instance.MainWindowHandle);            //放到前端
            }
    
        }
    }
    View Code

    三、互斥体

        /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Process instance = RunningInstance();
    
                bool blnIsRunning;
                Mutex mutexApp = new Mutex(false, Assembly.GetExecutingAssembly().FullName, out blnIsRunning);
                if (!blnIsRunning)
                {
                    MessageBox.Show("程序已经运行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }   
    
                Application.Run(new Form1());
    
            }
    View Code

    四、额外

    public void A()
            {
                //=====创建互斥体法:=====
                bool blnIsRunning;
                Mutex mutexApp = new Mutex(false, Assembly.GetExecutingAssembly().FullName, out blnIsRunning);
                if (!blnIsRunning)
                {
                    MessageBox.Show("程序已经运行!", "提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }   
            }
    
            public void B()
            {
                //保证同时只有一个客户端在运行   
                System.Threading.Mutex mutexMyapplication = new System.Threading.Mutex(false, "OnePorcess.exe");
                if (!mutexMyapplication.WaitOne(100, false))
                {
                    MessageBox.Show("程序" + Application.ProductName + "已经运行!", Application.ProductName,
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
    
            public void c()
            {
                //=====判断进程法:(修改程序名字后依然能执行)=====
                Process current = Process.GetCurrentProcess();
                Process[] processes = Process.GetProcessesByName(current.ProcessName);
                foreach (Process process in processes)
                {
                    if (process.Id != current.Id)
                    {
                        if (process.MainModule.FileName == current.MainModule.FileName)
                        {
                            MessageBox.Show("程序已经运行!", Application.ProductName,
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            return;
                        }
                    }
                }
            }
    View Code
  • 相关阅读:
    scp 指定端口(转)
    openshift 入门 部署 openshift-origin-server-v3.7.0
    kubernetes 网络模型
    故障排除--kubernetes 运维操作步骤 -- kubedns -- busybox -- nslookup 问题
    Service 服务发现的两种方式-通过案例来理解+服务外部访问类型+selector-label
    nmap 扫描端口 + iftop 实时监控流量
    Intellij IDEA 2016.3.4 注册激活--转
    laravel服务提供者类说明
    使用PHP实现命令模式(转)
    异步回收fork出的子进程(僵尸进程)
  • 原文地址:https://www.cnblogs.com/shenchao/p/4761310.html
Copyright © 2011-2022 走看看