WPF防止程序多次运行

简介: WPF防止程序多次运行
 /// <summary>  
    /// App.xaml 的交互逻辑  
    /// </summary>  
    public partial class App : Application  
    {  
        System.Threading.Mutex mutex;  
        public App()  
        {  
            this.Startup += new StartupEventHandler(App_Startup);  
        }  
        void App_Startup(object sender, StartupEventArgs e)  
        {  
            bool ret;  
            mutex = new System.Threading.Mutex(true, "ElectronicNeedleTherapySystem", out ret);  
            if (!ret)  
            {  
                MessageBox.Show("已有一个程序实例运行");  
                Environment.Exit(0);  
            }  
        }  
    }  

    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        private static System.Threading.Mutex mutex;
        protected override void OnStartup(StartupEventArgs e)
        {
            mutex = new System.Threading.Mutex(true, "OnlyRun_CRNS");
            if (mutex.WaitOne(0, false))
            {
                base.OnStartup(e);
            }
            else
            {
                MessageBox.Show("程序已经在运行!", "提示");
                this.Shutdown();
            }
        }
    }

public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            if (EnsureInstance())
            {
                return;
            }
            if (new LoginView().ShowDialog()==true)
            {
                new MainView().ShowDialog();
            }
            Application.Current.Shutdown();
        }
        /// 该函数设置由不同线程产生的窗口的显示状态
        /// </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 SW_SHOWNOMAL = 1;
        private static void HandleRunningInstance(Process instance)
        {
            ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOMAL);//显示
            SetForegroundWindow(instance.MainWindowHandle);//当到最前端
        }
        private static Process[] RuningInstance()
        {
            Process currentProcess = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);
            return processes.Where(x => x.Id != currentProcess.Id).ToArray();
        }
        private static bool EnsureInstance()
        {
            var intance = RuningInstance();
            var select = false;
            if (intance != null && intance.Count() > 0)
            {
                var result = MessageBox.Show(string.Format(CultureInfo.CurrentCulture,
                       $"软件已经在后台运行{intance.Count()}个实例!\r\n" +
                       $"路径:\r\n{GetProcessPath(intance)}\r\n\n" +
                       "请选择:\n" +
                       "1.关闭后台程序重新运行\t[是]\n" +
                       "2.显示后台程序\t\t[否]\n" +
                       "3.保留后台程序并启动新程序\t[取消]\n"),
                    "LoginManagement", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                switch (result)
                {
                    case MessageBoxResult.Yes:
                        KillProcess(intance);
                        break;
                    case MessageBoxResult.No:
                    case MessageBoxResult.None:
                        Array.ForEach(intance, x => HandleRunningInstance(x));
                        select = true;
                        break;
                    case MessageBoxResult.Cancel:
                        break;
                    default:
                        break;
                }
            }
            return select;
        }
        private static string GetProcessPath(Process[] processes)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < processes.Count(); i++)
            {
                sb.Append($"{i + 1}:{processes[i].MainModule.FileName}\n");
            }
            return sb.ToString();
        }
        private static void KillProcess(Process[] processes)
        {
            foreach (var p in processes)
            {
                p.Kill();
                if (!p.HasExited)
                {
                    MessageBox.Show(string.Format(CultureInfo.CurrentCulture, "进程关闭失败!请手动确认进程已关闭"),
                    "LoginManagement", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
    }
目录
相关文章
|
24天前
|
前端开发 C# Windows
在WPF程序中实现PropertyGrid功能
【11月更文挑战第15天】PropertyGrid 是一个用户界面组件,用于直观地查看和编辑对象属性。在 WPF 中可通过组合 Expander 和 DataGrid 实现基本功能,或使用第三方库 PropertyTools 获得更强大特性,包括属性验证和类型特定编辑器。
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
477 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
4月前
|
C#
WPF/C#:程序关闭的三种模式
WPF/C#:程序关闭的三种模式
94 0
|
6月前
|
C#
WPF/C#:程序关闭的三种模式
WPF/C#:程序关闭的三种模式
90 3
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
WPF从外部文件或者程序集加载样式或其他静态资源
WPF从外部文件或者程序集加载样式或其他静态资源
WPF从外部文件或者程序集加载样式或其他静态资源
|
Java C# 程序员
WPF程序中的弱事件模式
原文:WPF程序中的弱事件模式 在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源。但是,GC有的时并不是按照我们所期望的方式工作。 例如,我想实现一个在窗口的标题栏中实时显示当前的时间,一个比较常规的做法如下:     var...
1152 0
|
C# Windows
WPF:如何为程序添加splashScreen?
原文:WPF:如何为程序添加splashScreen? 大家是否还记得在Windows Forms程序中如何实现splashScreen吗?我们一般都会使用Microsoft.VisualBasic.dll中提供的那个WindowsFormsApplicationBase类型,它有一个所谓的splashscreen属性,可以指定为一个窗体的。
896 0
|
C# API
在WPF程序中将控件所呈现的内容保存成图像
原文:在WPF程序中将控件所呈现的内容保存成图像 有的时候,我们需要将控件所呈现的内容保存成图像保存下来,例如:InkCanvas的手写墨迹,WebBrowser中的网页等。可能有人会说,这个不就是截图嘛,找到控件的坐标和大小,调用截图API不就可以了嘛。
1134 0
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件