进程间通信
时间:2021-07-14
本文章向大家介绍进程间通信,主要包括进程间通信使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
不得不说,workaround很香,然而还是要谨慎使用,因为有时候我们为了cover之前的workaround,又不得不继续寻找新的workaround。。。
正是因为嵌入外部应用,将视觉窗口嵌入子控件后,出现了新的问题,就是之前提过的,视觉使用的插件(log4net)不兼容嵌入模式,嵌入后,视觉界面的窗口无法显示log,为了解决这一问题,采用了进程间通信的方式,通过视觉应用发送log数据到上位机程序,间接实现在窗口上显示视觉log数据。
进程间通信主要是通过调用User32.dll中的SendMessage函数来实现的
//定义结构体,用于进程间发送/接收消息
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
//调用SendMessage函数
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
private const int WM_COPYDATA = 0x004A;
接收消息:
/// <summary>
/// 当一个应用程序传递数据给另一个应用程序时发送此消息
/// </summary>
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
IntPtr handle = hwndSource.Handle;
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
}
/// <summary>
/// 接收窗口消息
/// </summary>
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr IParam, ref bool handled)
{
if (msg == WM_COPYDATA)
{
COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(IParam, typeof(COPYDATASTRUCT));
string rec = cds.lpData;
//接收到消息后逻辑处理
logHelper.VisionLog(rec);
if (rec == "接收到的消息")
{
...
}
}
return hwnd;
}
发送消息:
/// <summary>
/// 发送信息
/// </summary>
public static void SendExternalApp(string msg)
{
Process[] processes = Process.GetProcessesByName(ExternalAppName);
if (processes.Length == 1)
{
IntPtr hWnd = processes[0].MainWindowHandle;
byte[] sByte = System.Text.Encoding.Default.GetBytes(msg);
int len = sByte.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)0;
cds.cbData = len + 1;
cds.lpData = msg;
SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
}
else if (processes.Length > 1)
{
MessageBox.Show($"{ExternalAppName}进程多开,请关闭多余进程后重试");
}
else
{
MessageBox.Show($"{ExternalAppName}进程未开启,发送信息失败");
}
}
发送方应用使用同样的代码(修改ExternalAppName值),即可以实现两个进程间的相互通信。
原文地址:https://www.cnblogs.com/stanchen/p/15012293.html
- 12.观察者/状态模式
- 数据补丁中需要注意的几个问题(r5笔记第21天)
- 简单对比MySQL和Oracle中的一个sql解析细节 (r5笔记第40天)
- 关于Oracle和MySQL中的无密码登录 (r5笔记第39天)
- 快速定位隐蔽的sql性能问题及调优(r5笔记第38天)
- 关于统计信息过期的性能落差(r5笔记第36天)
- 系统级alias vs Oracle ADR功能(r5笔记第35天)
- 关于收缩数据文件的尝试(r5笔记第34天)
- 搭建dataguard碰到的几个小问题(r5笔记第33天)
- TP-LINK 远程代码执行漏洞 CVE-2017-13772 趣谈
- 执行计划中的COLLECTION ITERATOR PICKLER FETCH导致的性能问题 (r5笔记第49天)
- dataguard switchover的自动化脚本实现 (r5笔记第48天)
- 曲折的dump导入及问题分析(r5笔记第47天)
- 对一道if-else相关的程序题的简单分析(r5笔记第45天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 使用GANs生成时间序列数据:DoppelGANger论文详解
- CentOS 7使用samba共享文件夹的完整步骤
- Linux环境使用crontab命令设置定时周期性执行任务【含php执行代码】
- linux系统报xfs_vm_releasepage警告问题的处理方法
- linux系统报tcp_mark_head_lost错误的处理方法
- Pandas的列表值处理技巧,避免过多循环加快处理速度
- 详解Linux iptables常用防火墙规则
- Linux文件权限与群组修改命令详解
- Spring-IOC-从单例缓存中获取单例 Bean
- Linux上为你的任务创建一个自定义的系统托盘指示器
- 14个Seaborn数据可视化图
- Linux中的进程守护supervisor安装配置及使用
- 《JavaScript数据结构与算法》读书笔记
- 《JavaScript函数式编程指南》读书笔记
- 冒泡排序