最近公司需要实现一个基于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实现进程间通信的更多相关文章

  1. WM_COPYDATA进程间通信方案

    连续在两个公司使用WM_COPYDATA实现进程间通信了,整理一下 具体步骤: 一.   进程A通过ShellExecute启动进程B, 将用于通信的窗口句柄hWndA(已强转为int值)通过命令行参 ...

  2. 利用WM_COPYDATA消息实现进程间通信

    进程间通信最简单的方式就是发送WM_COPYDATA消息,下面通过例子来实现. 发送WM_COPYDATA消息: SendMessage(hRecvWnd, WM_COPYDATA, (WPARAM) ...

  3. 进程间通信之WM_COPYDATA方式反思,回顾和总结

    许多Windows程序开发者喜欢使用WM_COPYDATA来实现一些进程间的简单通信(笔者也正在学习共享内存的一些知识来实现一些更高级的通信),这篇文章描述了笔者在使用这项技术时候的一些总结以及所遇到 ...

  4. C++进程间通信

    # C++进程间通信 # 进程间通讯的四种方式:剪贴板.匿名管道.命名管道和邮槽 ## 剪切板 ## //设置剪切板内容 CString str; this->GetDlgItemText(ID ...

  5. android:使用Messenger进行进程间通信(一)

    Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...

  6. PHP 进程间通信——消息队列(msg_queue)

    PHP 进程间通信--消息队列 本文不涉及PHP基础库安装.详细安装说明,请参考官网,或期待后续博客分享. 1.消息队列函数准备 <?php//生成一个消息队列的key$msg_key = ft ...

  7. WM_COPYDATA实现的不同进程间通信

    进程间通信,通过SendMessage向另一进程发送WM_COPYDATA消息,实现不同进程间的消息通信. 需求:已写好一个工具软件,想在不更改当前的软件开发的前提下,实现为后面新开发的软件提供数据推 ...

  8. Linux学习笔记(12)-进程间通信|匿名管道

    Linux的进程间通信有几种方式,包括,管道,信号,信号灯,共享内存,消息队列和套接字等-- 现在一个个的开始学习! ----------------------------------------- ...

  9. 【linux草鞋应用编程系列】_3_ 进程间通信

    一.进程间通信        linux下面提供了多种进程间通信的方法, 管道.信号.信号量.消息队列.共享内存.套接字等.下面我们分别 介绍管道.信号量.消息队列.共享内存.        信号和套 ...

随机推荐

  1. python第九课——while死循环

    2.3.无限循环/死循环: 何时发生无限循环? 循环条件永远为True,就出现了无限循环 [注意] 无限循环是需要避免的,因为它极其占用系统资源: 但是配合我们之后讲的break等关键字,就会变得更有 ...

  2. ES6新特性2:变量的解构赋值

    本文摘自ECMAScript6入门,转载请注明出处. ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring).不仅适用于var命令,也适用于let和c ...

  3. Python:基础知识(二)

    常用模块 urllib2 :用于发送网络请求,获取数据 (Pyhton2中的urllib2工具包,在Python3中分拆成了urllib.request和urllib.error两个包.) json: ...

  4. RANSAC与 最小二乘(LS, Least Squares)拟合直线的效果比较

    代码下载地址: 1.Matlab版本:http://pan.baidu.com/s/1eQIzj3c.进入目录后,请自行定位到该博客的源代码与数据的目录“

  5. JIRA使用方法,简易图解

          我们公司要用版本控制(SVN)和过程管理(JIRA)相配合开发软件,所以两个都得用喽!     JIRA是集项目计划.任务分配.需求管理.错误跟踪于一体的商业软件.JIRA创建的问题类型包 ...

  6. 通过条件注解@Conditional细粒度的选择bean实例

    在进行spring进行开发时,当某个接口有多种实现方式并且我们只想让一种生效时,比如声明如下一个接口和两个实现: public interface LanggageService { String s ...

  7. select * from * with ur

    DB2中,共有四种隔离级:RS,RR,CS,UR,DB2提供了这4种不同的保护级别来隔离数据.隔离级是影响加锁策略的重要环节,它直接影响加锁的范围及锁的持续时间.两个应用程序即使执行的相同的操作,也可 ...

  8. java课设数据库打包报错

    最近在交java课设时把东西打包给老师遇到许多奇葩问题, 首先是数据库复制时提示: 这是数据库与SQL server服务没有分离(我用的是SQLserver暂时,对于其他的,我以后会继续尝试)可以进行 ...

  9. 学习java前端 两种form表单提交方式

    第一种:原生方式 注意点:button标签的style为submit <form action="/trans/doTrans.do" method="post&q ...

  10. window.open 防止浏览器拦截

    https://blog.csdn.net/sinat_37255207/article/details/89374416 网上试了很多方法 最终只有一种可以 var newWin = window. ...