C#使用SendMessage进行进程间通讯
最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在OnStartup事件中通过StartupEventArgs获取文件名然后进行操作即可。操作之后发现当软件已经启动了(单例运行),那么将无法将参数传给业务层。原因是因为跨进程了,那么我们可以通过窗口句柄的方式来进行通讯。
1 public partial class App : Application
2 {
3 private static Mutex AppMutex;
4 public App()
5 {
6
7 }
8
9 protected override void OnStartup(StartupEventArgs e)
10 {
11 //获取启动参数
12 var param = string.Empty;
13 if (e.Args.Length > 0)
14 {
15 param = e.Args[0].ToString();
16 }
17
18 //WpfApp8 = 你的项目名称
19 AppMutex = new Mutex(true, "WpfApp8", out var createdNew);
20
21 if (!createdNew)
22 {
23 var current = Process.GetCurrentProcess();
24
25 foreach (var process in Process.GetProcessesByName(current.ProcessName))
26 {
27 if (process.Id != current.Id)
28 {
29 Win32Helper.SetForegroundWindow(process.MainWindowHandle);
30 Win32Helper.SendMessageString(process.MainWindowHandle, param);
31 break;
32 }
33 }
34 Environment.Exit(0);
35 }
36 else
37 {
38 base.OnStartup(e);
39 }
40 }
41 }
1 public class Win32Helper
2 {
3 [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
4 public static extern bool SetForegroundWindow(IntPtr hWnd);
5
6 /// <summary>
7 /// 发送消息
8 /// </summary>
9 /// <param name="hWnd"></param>
10 /// <param name="Msg"></param>
11 /// <param name="wParam"></param>
12 /// <param name="lParam"></param>
13 /// <returns></returns>
14 [DllImport("user32.dll")]
15 public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
16
17 // 声明常量
18 public const int WM_COPYDATA = 0x004A;
19
20 // 定义 COPYDATASTRUCT 结构
21 [StructLayout(LayoutKind.Sequential)]
22 public struct COPYDATASTRUCT
23 {
24 public IntPtr dwData;
25 public int cbData;
26 public IntPtr lpData;
27 }
28
29 /// <summary>
30 /// 发送字符串消息
31 /// </summary>
32 /// <param name="hWnd"></param>
33 /// <param name="message"></param>
34 public static void SendMessageString(IntPtr hWnd, string message)
35 {
36 if (string.IsNullOrEmpty(message)) return;
37
38 byte[] messageBytes = Encoding.Unicode.GetBytes(message + '\0'); // 添加终止符
39
40 COPYDATASTRUCT cds = new COPYDATASTRUCT();
41 cds.dwData = IntPtr.Zero;
42 cds.cbData = messageBytes.Length;
43 cds.lpData = Marshal.AllocHGlobal(cds.cbData);
44 Marshal.Copy(messageBytes, 0, cds.lpData, cds.cbData);
45 try
46 {
47 SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
48 }
49 finally
50 {
51 //释放分配的内存,即使发生异常也不会泄漏资源
52 Marshal.FreeHGlobal(cds.lpData);
53 }
54 }
55 }
1 public partial class MainWindow : Window
2 {
3 public MainWindow()
4 {
5 InitializeComponent();
6 }
7
8 protected override void OnSourceInitialized(EventArgs e)
9 {
10 base.OnSourceInitialized(e);
11
12 HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
13 hwndSource.AddHook(WndProc);
14 }
15
16 private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
17 {
18 if (msg == WM_COPYDATA)
19 {
20 COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
21 string receivedMessage = Marshal.PtrToStringUni(cds.lpData);
22
23 Console.WriteLine("收到消息:" + receivedMessage);
24
25 //TODO:业务处理
26 MessageBox.Show(receivedMessage);
27
28 handled = true;
29 }
30
31 return IntPtr.Zero;
32 }
33 }

C#使用SendMessage进行进程间通讯的更多相关文章
- C#进程间通讯技术-整理。
原文:C#进程间通讯技术-整理. 扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1) ...
- .Net 利用消息在进程间通讯实现进程互操作
有时候我们会遇到需要在两个进程间通过某种方式实现互操作,方法有很多,例如你可以尝试让两个进程持续监视一个外部文件,由此文件记录各自进程的数据:还有可以使用网络端口实现进程间通讯.共享一片内存区域记录及 ...
- Node.js - 阿里Egg的多进程模型和进程间通讯
前言 最近用Egg作为底层框架开发项目,好奇其多进程模型的管理实现,于是学习了解了一些东西,顺便记录下来.文章如有错误, 请轻喷 为什么需要多进程 伴随科技的发展, 现在的服务器基本上都是多核cpu的 ...
- C# 进程间通讯
扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1)共享内存 包括:内存映射文件,共享 ...
- wpf进程间通讯
wpf进程间通讯 在联想智能识别项目中,需要用到进程间通讯,并且是低权限向高权限发送消息.首先声明一下,此项目是wpf的. 首先先简要说一下什么时候会用到进程间通讯,如:在Windows程序中,各个进 ...
- Windows进程间通讯(IPC)----WM_COPYDATA
WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...
- Windows进程间通讯(IPC)----消息队列
消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...
- Android进程间通讯
最近研究了一下Android进程间通讯,原来只是会用,但是只是会用是不行滴,就来研究一下. 刚开始看的时候,我的头是这么大,看了一夜的时候,头就变成这样了,,吓得宝宝赶紧上床休息了,. 先喝喝茶讲个故 ...
- Android进程间通讯之messenger
这两天在看binder,无意间在文档看到messenger这么个东西,感觉这个东西还挺有意思的,给大家分享一下. 平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都 ...
- [转]Windows 下的进程间通讯及数据共享
http://blog.codingnow.com/2005/10/interprocess_communications.html Windows 下有很多方法实现进程间通讯,比如用 socket, ...
随机推荐
- Your lock file does not contain a compatible set of packages. Please run composer update.
执行composer install遇到错误:Your requirements could not be resolved to an installable set of packages. 这是 ...
- MindSponge分子动力学模拟——体系控制(2024.05)
技术背景 在传统的分子动力学模拟软件中,对于分子体系的控制,例如控制体系的相对位置亦或是绝对位置,通常都是通过施加一些约束算法来实现的.例如用于限制化学键的LINCS算法,又比如水分子体系非常常用的S ...
- EasyUI框架Datagrid(数据表格)的实现,以及Datagrid的分页显示(详解)
在前端页面中使用EasyUI框架时,通常会使用EasyUI自带的datagrid(数据表格)样式,下面我们对datagrid样式进行简单的介绍,并且会对datagrid的分页显示进行详细的介绍. Ea ...
- MahApps.Metro的MVVM模式解析(二) 主题功能
MahApps.Metro的MVVM模式解析(二) 主题功能 MahApps.Metro是一个开源的WPF框架,旨在为WPF应用程序提供现代和漂亮的用户界面. 在MahApps.Metro中提供了切换 ...
- protoc-gen-go: error:inconsistent package names: , prototest
如果你已经安装proto ,以及go生成proto插件.但还是报这种错误,请看一下是否 protoc --go_out=./ *.proto 指令打错了
- C#命令行参数解析库System.CommandLine介绍
命令行参数 平常在日常的开发过程中,会经常用到命令行工具.如cmd下的各种命令. 以下为sc命令执行后的截图,可以看到,由于没有输入任何附带参数,所以程序并未执行任何操作,只是输出了描述和用法. 系统 ...
- unaipp 发送验证码倒计时
view代码 <view class="margin-top" @tap="getCheckNum()"> <view class=" ...
- 使用Python实现深度学习模型:序列到序列模型(Seq2Seq)
本文分享自华为云社区<使用Python实现深度学习模型:序列到序列模型(Seq2Seq)>,作者: Echo_Wish. 序列到序列(Seq2Seq)模型是一种深度学习模型,广泛应用于机器 ...
- idea mapper xml 文件报红
在使用 idea 打开 mapper 文件,出现一下报红错误: 可以看到数据表和字段都是红色的. 解决方案 打开设置,window版本是打开Settings: 找到 Languages & F ...
- kettle从入门到精通 第十六课 kettle 映射 (子转换)02
1.上节讲的子映射里面只有一个转换(类似一个java类里面只有一个公共方法),本次讲解的有两个,实际上可以有任意多个(一个java类里面有多个公共方法).两个转换分别计算x+y和x*y. 2.命名参数 ...