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);
                }
            }
        }
    }
目录
相关文章
|
7月前
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
267 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
WPF界面无法正常显示(资源引用,如转换器),但程序正常运行
|
Java C# 程序员
WPF程序中的弱事件模式
原文:WPF程序中的弱事件模式 在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源。但是,GC有的时并不是按照我们所期望的方式工作。 例如,我想实现一个在窗口的标题栏中实时显示当前的时间,一个比较常规的做法如下:     var...
1090 0
|
C#
WPF程序 双击exe自动申请“以管理员方式运行”权限
原文:WPF程序 双击exe自动申请“以管理员方式运行”权限 实现方式: 在 xxx.exe 目录下包含其对应的清单文件(xxx.exe.manifest); 用记事本打开 manifest 文件,将文件中的项:更改为:
1328 0
|
C#
【msdn wpf forum翻译】如何在wpf程序(程序激活时)中捕获所有的键盘输入,而不管哪个元素获得焦点?
原文:【msdn wpf forum翻译】如何在wpf程序(程序激活时)中捕获所有的键盘输入,而不管哪个元素获得焦点?原文链接:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cf884a91-c135-447d-b16b-214d2d9e9972 有时有些特殊的程序需要这样处理。
957 0
|
C#
WPF整理-Mutex确保Application单例运行
原文:WPF整理-Mutex确保Application单例运行 有时我们不希望我们的WPF应用程序可以同时运行有多个实例,当我们试图运行第二个实例的时候,已经运行的实例也应该弹出来。 我们可以用Mutex来实现 打开App.
1315 0
|
C#
WPF 启动唯一程序(项目,exe,实例)
原文:WPF 启动唯一程序(项目,exe,实例) 描述:用户多次快速开启WPF程序的时候  只运行起来 一个 程序(exe) 其他多开的 进程 自动关闭掉 App.xaml.cs文件   1 protected override void OnStartup(Startu...
1245 0
|
C# Windows
WPF:如何为程序添加splashScreen?
原文:WPF:如何为程序添加splashScreen? 大家是否还记得在Windows Forms程序中如何实现splashScreen吗?我们一般都会使用Microsoft.VisualBasic.dll中提供的那个WindowsFormsApplicationBase类型,它有一个所谓的splashscreen属性,可以指定为一个窗体的。
862 0
|
C# API
在WPF程序中将控件所呈现的内容保存成图像
原文:在WPF程序中将控件所呈现的内容保存成图像 有的时候,我们需要将控件所呈现的内容保存成图像保存下来,例如:InkCanvas的手写墨迹,WebBrowser中的网页等。可能有人会说,这个不就是截图嘛,找到控件的坐标和大小,调用截图API不就可以了嘛。
1091 0
|
3天前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库