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, ...
随机推荐
- Java学习之旅(day.09)
封装 把数据包装起来,给你能看的,不能看的包装起来不让你看 该露的露,该藏的藏 程序设计要求"高内聚,低耦合". 高内聚指类的内部数据操作细节自己完成,不允许外部干涉: 低耦合指仅 ...
- k8s快捷命令
查看node使用率: for i in `kubectl get nodes|awk '{print $1}'|sed '1d'`;do echo "=========>" ...
- YiShaAdmin:一款基于.NET Core Web + Bootstrap的企业级快速开发框架
前言 今天大姚给大家分享一款基于.NET Core Web + Bootstrap的企业级快速后台开发框架.权限管理系统,代码简单易懂.界面简洁美观(基于MIT License开源,免费可商用):Yi ...
- Istio(六):Istio弹性(超时&重试)和故障注入
目录 一.模块概览 二.系统环境 三.弹性(超时&重试) 3.1 弹性 四.故障注入 4.1 故障注入 五.实战:观察错误注入 5.1 在 Grafana.Zipkin 和 Kiali 中观察 ...
- 【C#】预处理指令的学习 条件编译
预处理指令,我的理解是,编译器在编译过程中所做的指令,能根据用户定义的条件选择性的编译代码. 比如在debug下要打印些信息,然而release之后,不能出现debug的信息,这个时候就能用预处理指令 ...
- IDEA使用——生成超文本格式的(HTML)JavaDoc
概述 在大型项目中不免会有很多对外暴露的方法与接口,那我们就需要在类或者方法上面按照JavaDoc标准编写注释,就比如这样: 前面我们也提到过在Idea中可以将鼠标停留在方法名上,然后点击F2查看方法 ...
- truffle 框架complie错误。
第一次使用trulle框架编译合约发现编译失败,原因是没有在truffle-config.js文件中加入编译器版本. module.exports = { // See <http://truf ...
- js 求任意两数之间的和
知识点:函数的传参,函数的返回值 函数的传参 函数的参数包括以下两种类型: 1.形参:在定义函数时,声明的参数变量仅在函数内部可见: 2.实参:在调用函数时,实际传入的值. 示例 我们在定义函数的时候 ...
- containerd 源码分析:创建 container(三)
文接 containerd 源码分析:创建 container(二) 1.2.2.2 启动 task 上节介绍了创建 task,task 创建之后将返回 response 给 ctr.接着,ctr 调 ...
- C语言-使用malloc导致的奔溃问题
在使用malloc.memset.free的过程中,出现了程序奔溃,大致现象如下. 程序的实现大致如下: #include <stdio.h> #include <stdlib.h& ...