最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在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进行进程间通讯的更多相关文章

  1. C#进程间通讯技术-整理。

    原文:C#进程间通讯技术-整理. 扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1) ...

  2. .Net 利用消息在进程间通讯实现进程互操作

    有时候我们会遇到需要在两个进程间通过某种方式实现互操作,方法有很多,例如你可以尝试让两个进程持续监视一个外部文件,由此文件记录各自进程的数据:还有可以使用网络端口实现进程间通讯.共享一片内存区域记录及 ...

  3. Node.js - 阿里Egg的多进程模型和进程间通讯

    前言 最近用Egg作为底层框架开发项目,好奇其多进程模型的管理实现,于是学习了解了一些东西,顺便记录下来.文章如有错误, 请轻喷 为什么需要多进程 伴随科技的发展, 现在的服务器基本上都是多核cpu的 ...

  4. C# 进程间通讯

    扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1)共享内存 包括:内存映射文件,共享 ...

  5. wpf进程间通讯

    wpf进程间通讯 在联想智能识别项目中,需要用到进程间通讯,并且是低权限向高权限发送消息.首先声明一下,此项目是wpf的. 首先先简要说一下什么时候会用到进程间通讯,如:在Windows程序中,各个进 ...

  6. Windows进程间通讯(IPC)----WM_COPYDATA

    WM_COPYDATA通讯思路 通过向其他进程的窗口过程发送WM_COPYDATA消息可以实现进程间通讯. 只能通过SendMessage发送WM_COPYDATA消息,而不能通过PostMessag ...

  7. Windows进程间通讯(IPC)----消息队列

    消息队列 windows系统是通过消息驱动的,每移动一下鼠标,点击一下屏幕都会产生一个消息.这些消息会先被放在windows的一个系统消息队列(先进先出)中,windows系统会为每一个GUI线程创建 ...

  8. Android进程间通讯

    最近研究了一下Android进程间通讯,原来只是会用,但是只是会用是不行滴,就来研究一下. 刚开始看的时候,我的头是这么大,看了一夜的时候,头就变成这样了,,吓得宝宝赶紧上床休息了,. 先喝喝茶讲个故 ...

  9. Android进程间通讯之messenger

    这两天在看binder,无意间在文档看到messenger这么个东西,感觉这个东西还挺有意思的,给大家分享一下. 平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都 ...

  10. [转]Windows 下的进程间通讯及数据共享

    http://blog.codingnow.com/2005/10/interprocess_communications.html Windows 下有很多方法实现进程间通讯,比如用 socket, ...

随机推荐

  1. 网络数据流分析工具TcpEngine V1.0.0教程-1

    概述 目前主流的网络数据分析工具主要有两类,一类是http协议分析工具,如fiddler,这类工具擅长对字符串类型协议分析:另一类是原始网络数据包的监听分析,如Wireshark,这类工具擅长分析网络 ...

  2. 国产Linux音视频聊天程序开发遇到的坑及解决:相互听不到对方声音?

    最近完成了一个银河麒麟上的视频聊天项目,在我们开发机上测试一切正常后,提交给甲方测试.结果发现在甲方的某些银河麒麟V10的电脑上,听不到声音. 这个问题,使用<Avalonia 实现跨平台的IM ...

  3. 【C#】操作word 【Aspose.Words】

    上图是要填充的word模板,就是一个接口说明文档.那个像书名号括起来的东西就是要替换的,这个东西并不是键盘输入的书名号,它是文档部件的一种,要插入这个东西需要: 打开模板word文件,用office打 ...

  4. 网络广告代理商是如何通过Cookie收集用户信息的

    更多博文请关注:https://blog.bigcoder.cn 不知道大家有没有这样的经历,我在某宝上搜索一个商品,然后再打开其它网站,它会非常"智能"的给我推荐同一商品. 这样 ...

  5. Android 12(S) MultiMedia(十一)从MPEG2TSExtractor到MPEG2-TS

    本节主要学习内容是看看MPEG2TSExtractor是如何处理TS流的. 相关代码位置: frameworks/av/media/extractors/mpeg2/MPEG2TSExtractor. ...

  6. Uni-app极速入门(二) - 登录demo

    需求 背景 1.进入小程序,默认页面判断用户是否已经登录,已经登录则进入首页,没有登录则进入登录页面 2.首页为tabbar,包括首页和设置页,设置页可以退出登录,回到登录页面 页面流转 graph ...

  7. MVCC(多版本并发控制)详解

    在 MySQL InnoDB存储引擎下,RC.RR 基于 MVCC 进行并发事务控制, MVCC 是基于"数据版本"对并发事务进行访问 用一个例子来解释一下,下面是一张事务执行流程 ...

  8. vue 的directives一个坑

    大江东去,浪淘尽,千古风流人物.故垒西边,人道是,三国周郎赤壁.乱石穿空,惊涛拍岸,卷起千堆雪.江山如画,一时多少豪杰.遥想公瑾当年,小乔初嫁了,雄姿英发.羽扇纶巾,谈笑间,樯橹灰飞烟灭.故国神游,多 ...

  9. js整数类型

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  10. linux系统下,安装maven教程

    1.下载 官网:https://maven.apache.org/download.cgi 2.上传包 将下载好的maven安装包apache-maven-3.8.6-bin.tar.gz放在磁盘的 ...