C#唯一进程的处理Winform/WPF

2024-06-18 16:12

本文主要是介绍C#唯一进程的处理Winform/WPF,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C#唯一进程的处理

  • 1.使用进程(Process)判断
    • winform
    • WPF
    • 执行效果:
  • 2.使用互斥体(Metux)实现
    • winform
    • WPF
    • 实现效果:

在C#客户端(Winform/WPF)开发过程中,有的情况需要确保程序的唯一性,如果启动同时启动同一个程序多次,可能导致数据,通信等异常。下面有两种方法来实现唯一进程

1.使用进程(Process)判断

需要引入SwitchToThisWindow,用于将已启动程序切换到最前显示。

使用Process获取同名的程序,判断是否有同名但是不同Id的进程,如有,则关闭当前程序;如果没有,则进行正常启动。

具体代码示例如下:

winform

internal static class Program
{[DllImport("user32.dll")]public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Process current = Process.GetCurrentProcess();Process[] processes = Process.GetProcessesByName(current.ProcessName);foreach (Process process in processes){if (process.Id != current.Id){ //根据进程ID排除当前进程MessageBox.Show("系统已启动");IntPtr handle = process.MainWindowHandle;//将原进程显示在最前SwitchToThisWindow(handle, true);current.Close();return;}}//正常启动程序Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}
}

WPF

在App.xaml.cs中重写OnStartup程序,然后添加下面代码

  [DllImport("user32.dll")]public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);protected override void OnStartup(StartupEventArgs e){Process currentProcess = Process.GetCurrentProcess(); //获取当前进程//获取当前运行程序完全限定名string currentFileName = currentProcess.MainModule.FileName;Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);foreach (Process process in processes){if (process.Id != currentProcess.Id){ //根据进程ID排除当前进程MessageBox.Show("系统已启动");IntPtr handle = process.MainWindowHandle;//将原进程显示在最前SwitchToThisWindow(handle, true);Application.Current.Shutdown();return;}}base.OnStartup(e);}

执行效果:

第二次启动,显示弹窗,然后关闭之后显示第一个程序窗体。

在这里插入图片描述

2.使用互斥体(Metux)实现

基本实现方式一样,只是一开始判断使用使用互斥体Metux进行判断,选择一个字符串进行创建,如果未存在,则为True,继续创建,如果已经存在了,则为False,关闭当前进程,显示原进程。

winform

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp1
{internal static class Program{/// <summary>/// 焦点切换指定的窗口,并将其带到前台/// </summary>/// <param name="hWnd"></param>/// <param name="fAltTab"></param>[DllImport("user32.dll")]public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){bool createdNew;Mutex mutex = new Mutex(true, "ED4D323242424324242ERS", out createdNew); // 使用唯一的GUID作为互斥锁名称//if (!createdNew){var current = Process.GetCurrentProcess();var processes = Process.GetProcessesByName(current.ProcessName);var process = processes.FirstOrDefault(x => x.Id == current.Id);if (process != null){MessageBox.Show("系统已启动");IntPtr handle = process.MainWindowHandle;SwitchToThisWindow(handle, true);}current.Close();return;}Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}}
}

WPF

在App.xaml.cs中重写OnStartup程序,然后添加下面代码

 using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;namespace WpfApp1
{/// <summary>/// Interaction logic for App.xaml/// </summary>public partial class App : Application{[DllImport("user32.dll")]public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);protected override void OnStartup(StartupEventArgs e){bool createdNew;Mutex mutex = new Mutex(true, "ED4D324324242ERS", out createdNew); // 使用唯一的GUID作为互斥锁名称if (!createdNew){var current = Process.GetCurrentProcess();var processes = Process.GetProcessesByName(current.ProcessName);var process = processes.FirstOrDefault(x => x.Id == current.Id);if (process != null){IntPtr handle = process.MainWindowHandle;SwitchToThisWindow(handle, true);}Application.Current.Shutdown();}//正常启动base.OnStartup(e);}}
}

实现效果:

效果一样
在这里插入图片描述

这篇关于C#唯一进程的处理Winform/WPF的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072473

相关文章

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin