C# 通过copydata实现进程间通信
最近公司需要实现一个基于copydata进程间通信的功能。原来一直没有接触过Windows的进程通信,这次正好可以学习一下。
程序是基于Winform的,下面直接上代码。
公共类:
public class ImportFromDLL
{
public const int WM_COPYDATA = 0x004A; //启用非托管代码
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public int dwData; //not used
public int cbData; //长度
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
} [DllImport("User32.dll")]
public static extern int SendMessage(
IntPtr hWnd, // handle to destination window
int Msg, // message
IntPtr wParam, // first message parameter
ref COPYDATASTRUCT pcd // second message parameter
); [DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("Kernel32.dll", EntryPoint = "GetConsoleWindow")]
public static extern IntPtr GetConsoleWindow(); }
发送方:
private void SendMessage()
{
//声明变量
string filepath = @"D:\GetMsg.exe";//接收消息程序路径
string strText= "hello world!";//发送的消息//遍历系统中运行的进程,获取接收消息的进程
Process[] processes = Process.GetProcesses();
Process process = null;
foreach (Process p in processes)
{
try
{
//这两个进程的某些属性一旦访问就抛出没有权限的异常
if (p.ProcessName != "System" && p.ProcessName != "Idle")
{
if (p.ProcessName == "GetMsg")
{
process = p;
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} //如果接收消息的进程未运行,则开启程序
if (process == null)
{//启动接收消息程序
process = System.Diagnostics.Process.Start(filepath);
Thread.Sleep(100);//等待接收消息的程序完全打开,否则消息不能发送成功。
} //接收端的窗口句柄
IntPtr hwndRecvWindow = process.MainWindowHandle; //自己的进程句柄
IntPtr hwndSendWindow = Process.GetCurrentProcess().Handle; //填充COPYDATA结构
ImportFromDLL.COPYDATASTRUCT copydata = new ImportFromDLL.COPYDATASTRUCT();
copydata.cbData = Encoding.Default.GetBytes(strText).Length; //长度 注意不要用strText.Length;
copydata.lpData = strText;//内容 //发送消息
ImportFromDLL.SendMessage(hwndRecvWindow, ImportFromDLL.WM_COPYDATA, hwndSendWindow, ref copydata); return;
}
接收方:
protected override void WndProc(ref Message m)
{
if (m.Msg == ImportFromDLL.WM_COPYDATA)//根据Message.Msg区分消息类型,ImportFromDLL.WM_COPYDATA为发送方定义的消息类型
{
ImportFromDLL.COPYDATASTRUCT copyData = (ImportFromDLL.COPYDATASTRUCT)m.GetLParam(typeof(ImportFromDLL.COPYDATASTRUCT));//获取数据
MessageBox.Show(copyData.lpData);
}
base.WndProc(ref m);
}
注:
1、发送方和接收方均可以用C++、JAVA等实现,此处就不再做讨论。
2、在发送方。判断到接收方尚未开启,就执行打开接收方程序的代码,在打开的同时,使用了线程等待:
Thread.Sleep();//等待接收消息的程序打开,否则消息不能发送成功
若不想使用线程等待,又想传递消息给接收方,则可以考虑使用以下开启进程的重载方法:
public static Process Start(string fileName, string arguments);
public static Process Start(string fileName, string userName, SecureString password, string domain);
public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain);
具体使用说明,可参照API文档。
C# 通过copydata实现进程间通信的更多相关文章
- WM_COPYDATA进程间通信方案
连续在两个公司使用WM_COPYDATA实现进程间通信了,整理一下 具体步骤: 一. 进程A通过ShellExecute启动进程B, 将用于通信的窗口句柄hWndA(已强转为int值)通过命令行参 ...
- 利用WM_COPYDATA消息实现进程间通信
进程间通信最简单的方式就是发送WM_COPYDATA消息,下面通过例子来实现. 发送WM_COPYDATA消息: SendMessage(hRecvWnd, WM_COPYDATA, (WPARAM) ...
- 进程间通信之WM_COPYDATA方式反思,回顾和总结
许多Windows程序开发者喜欢使用WM_COPYDATA来实现一些进程间的简单通信(笔者也正在学习共享内存的一些知识来实现一些更高级的通信),这篇文章描述了笔者在使用这项技术时候的一些总结以及所遇到 ...
- C++进程间通信
# C++进程间通信 # 进程间通讯的四种方式:剪贴板.匿名管道.命名管道和邮槽 ## 剪切板 ## //设置剪切板内容 CString str; this->GetDlgItemText(ID ...
- android:使用Messenger进行进程间通信(一)
Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...
- PHP 进程间通信——消息队列(msg_queue)
PHP 进程间通信--消息队列 本文不涉及PHP基础库安装.详细安装说明,请参考官网,或期待后续博客分享. 1.消息队列函数准备 <?php//生成一个消息队列的key$msg_key = ft ...
- WM_COPYDATA实现的不同进程间通信
进程间通信,通过SendMessage向另一进程发送WM_COPYDATA消息,实现不同进程间的消息通信. 需求:已写好一个工具软件,想在不更改当前的软件开发的前提下,实现为后面新开发的软件提供数据推 ...
- Linux学习笔记(12)-进程间通信|匿名管道
Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...
- 【linux草鞋应用编程系列】_3_ 进程间通信
一.进程间通信 linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存. 信号和套 ...
随机推荐
- mysql分页(ajax)
分页有多种方式,mysql的limit是个不错的选择,通过ajax实现异步刷新,将当前页数和每页数量传入后台即可 1. 首先后台要拿到总记录数和所需显示数据列表,所以要分别写两个sql方法 我这里是通 ...
- ubuntu16.04安装visual-studio-code
微软主页的安装说明,https://code.visualstudio.com/docs/setup/linux 有一点英语基础就能看懂,写的很好,一切以官方文档为主 方法一:可以使用umake ...
- 死磕salt系列-salt文章目录汇总
死磕salt系列-salt入门 死磕salt系列-salt配置文件 死磕salt系列-salt grains pillar 配置 死磕salt系列-salt 常用modules 死磕salt系列-sa ...
- JWinner:一个私人定制的快速开发框架,为理想而生
关于JWinner JWinner是一个JAVA项目的快速开发框架,他已经实现了大多数项目开发之前需要进行的一些必备工作,还有很多在开发过程中可能会用到的工具集. JWinner的诞生并不是一蹴而就的 ...
- P2278 [HNOI2003]操作系统
题目描述 写一个程序来模拟操作系统的进程调度.假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的.其中运行优先级用自然数表示,数字越大,则优先级越高. 如果一个进程到达的时 ...
- python 二维数组键盘输入
m = int(input()) grid = [[] for i in range(m)] for i in range(m): line = input().split(' ') for j in ...
- Elasticsearch + logstash + kibana 配置
Elasticsearch 配置 Elasticsearch不仅仅是Lucene和全文搜索,我们还能这样去描述它: 分布式的实时文件存储,每个字段都被索引并可被搜索 分布式的实时分析搜索引擎 可以扩展 ...
- Spring源码分析(二十五)finishRefresh
摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在 Spring 中还提供了 Lifecycle 接口, Lifecy ...
- 如何解析json字符串及返回json数据到前端
前言:最近需要实现的任务是:写若干个接口,并且接口中的请求数据是json格式,然后按照请求参数读取前端提前整理好的json数据,并且将json数据返回到服务器端. 主要的工具:Gson 2.8.2 ...
- 【LeetCode415】Add Strings
题目描述: 解决思路: 此题较简单,和前面[LeetCode67]方法一样. Java代码: public class LeetCode415 { public static void main(St ...