最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在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. postgresql性能优化1:min和max的性能

    select max(datatime) as id from mytable ---全表检索,时间慢执行时间5分钟 select max(datatime) as id from mytable w ...

  2. CSS布局概念与技术教程

    以下是一份CSS布局学习大纲,它涵盖了基本到高级的CSS布局概念和技术 引言 欢迎来到CSS教程!如果你已经掌握了HTML的基础知识,那么你即将进入一个全新的世界,通过学习CSS(Cascading ...

  3. 定了!AIRIOT新品发布会,6月6日北京见。

    随着物联网.大数据.AI技术的成熟和演进,智能物联网技术正在加速.深入渗透至各行业应用. AIRIOT物联网平台作为赋能数字经济发展和产业转型的数字基座,由航天科技控股集团股份有限公司(股票代码:00 ...

  4. python ddddocr图片验证码详解

    安装 下载地址:https://pypi.tuna.tsinghua.edu.cn/simple/ddddocr/ 安装命令: pip install D:\ChromeCoreDownloads\d ...

  5. webapi创建WCF WebService+WCF WebService远程服务调用

    首先需要引入soapcore包 这个包提供了所需的类和soap终结点中间件. 引入这个这个包之后,我们需要定义提供的服务. 这里我写了一个用于查询省份面积的服务. 省份信息服务 /// <sum ...

  6. mvn install:install-file -Dfile=D:\Clipper1.jar -DgroupId=de.lighti -DartifactId=Clipper -Dversion=6.4.2 -Dpackaging=jar

    mvn install:install-file -Dfile=D:\Clipper1.jar -DgroupId=de.lighti -DartifactId=Clipper -Dversion=6 ...

  7. 流式响应Web小工具实践

    作为一位拥有多年经验的老程序员,我对于提升Web应用性能和用户体验有些兴趣.今天,我要和大家聊聊一个非常实用的技术--流式响应(Streaming Response). 首先,流式响应到底是什么呢?简 ...

  8. protoc-gen-go: error:inconsistent package names: , prototest

    如果你已经安装proto ,以及go生成proto插件.但还是报这种错误,请看一下是否 protoc --go_out=./ *.proto 指令打错了

  9. 莫烦tensorflow学习记录 (5)什么是过拟合 (Overfitting)

    什么是过拟合 (Overfitting) 莫烦讲的非常通俗易懂可以看看https://mofanpy.com/tutorials/machine-learning/tensorflow/intro-o ...

  10. Linux设备驱动--异步通知

    注:本文是<Linux设备驱动开发详解:基于最新的Linux 4.0内核 by 宋宝华 >一书学习的笔记,大部分内容为书籍中的内容. 书籍可直接在微信读书中查看:Linux设备驱动开发详解 ...