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, ...
随机推荐
- Unity新的MeshData API学习
在新版本的Unity中提供了MeshDataArray和MeshData等多个API,使Mesh数据操作支持多线程:以更好的支持DOTS. API文档:https://docs.unity3d.com ...
- OpenStack 的 SR-IOV 虚拟机热迁移
目录 文章目录 目录 前言列表 前言 SR-IOV Pass-through 虚拟机热迁移的问题 基于 macvtap 层的 SR-IOV 虚拟机热迁移 Workaround SR-IOV Pass- ...
- 微信小程序 canvas 手写签名(2d)
canvas 2d 目前支持预览,不支持真机调试 index.wxml <canvas type="2d" id="canvas" bindtouchmo ...
- centos7系统的七个运行级别和设置默认运行级别
一.系统七个运行级别概述 0 系统停机模式,系统默认运行级别不能设置为0,否则不能正常启动,机器关的 1 单用户模式,root权限,用于系统维护,禁止远程登陆,就像Windows下的安全模式登录 2 ...
- 【c#】 重复鼠标键盘动作
这个先录制好要重复的鼠标和键盘的操作,然后就能重复的执行保存的这些动作,这个是我从csdn下载的,原本不支持录制键盘动作. + 符号 开始/暂停录制 / 播放/暂停动作 - 退出程序 主要是用到了 ...
- c#事件的实际应用场景
最简单的定义事件的语法 public event Action<bool> Refreash; 先介绍这个Action 这个Action是委托的快速实现方式,我用.net framewor ...
- Android OpenMAX(四)OMX Core
假设我们已经写好了所有的OMX组件,有vdec.venc.adec.aenc,接下来问题来了,我们应该如何管理这些组件呢(创建.销毁)?这一篇文章我们向上一层学习OMX Core提供的标准API. O ...
- Rainbond 5.5 发布,支持Istio和扩展第三方Service Mesh框架
Rainbond 5.5 版本主要优化扩展性.服务治理模式可以扩展第三方 ServiceMesh 架构,兼容kubernetes 管理命令和第三方管理平台. 主要功能点解读: 1. 支持 Istio, ...
- 腾讯蓝鲸平台部署v5.1版本[去坑]
腾讯蓝鲸平台部署 1. 环境准备 #1. 基础优化 ulimit -SHn 655360 yum remove mysql-devel -y && yum install mysql- ...
- 面向对象编程 es5和es6的构造函数
/* 面向对象编程 本质 创建一个对象 可以用 属性属性值的 方式 存储 数据参数 ...