最近公司需要实现一个基于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. php实现随机数字、字母的验证码

     php实现随机数字.字母的验证码 可自定义生成验证码文字的大小.数量.干扰项等等,也可以自定义验证文字的字体... 废话不多说,直接上代码: 1.classgd.class.php <?php ...

  2. HBase TableExistsException: hbase:namespace

    这个报错一般存在于独立安装Zookeeper集群中. 报这个错的操作时这样的, 先停掉了了Hbase formatZK后重启Hbase 启动hbase shell 后HMaster挂掉,看log里就有 ...

  3. 【bzoj 3252】攻略

    题意 我们想到一个贪心,就是每次找到根路径前缀和最大的一个点,取走这条路径,同时把这条路径上的点权变成\(0\) 正确性显然 进一步发现我们需要从树上选择\(m\)条链使得链的总和最大 于是我们考虑换 ...

  4. [AHOI2009]最小割

    题目 最小割的可行边和必须边 可行边\((u,v)\)需要满足以下两个条件 满流 残量网络中不存在\(u\)到\(v\)的路径 这个挺好理解的呀,如果存在还存在路径的话那么这条边就不会是瓶颈了 必须边 ...

  5. 关于onscroll函数兼容各浏览器的方法分析

    关于window.onscroll函数兼容各浏览器的方法分析 1.当前文档的渲染模式是决定onscroll函数兼容性根本原因 目前浏览器的排版引擎有三种模式:怪异模式(Quirks mode).接近标 ...

  6. Ubuntu16.04如何彻底删除Apache2

    虽然作为运维人员通常情况不建议随意删除Linux系统上面的任何软件,主要指生产环境下,测试环境也不能太随意. 但是有的时候,比如系统环境要变一变,我们就需要替换一些淘汰的软件,对此我们一般都会删除. ...

  7. [转] Eclipse安装SVN插件

    eclipse里安装SVN插件,一般来说,有三种方式: 1. 直接下载SVN插件,将其解压到eclipse的对应目录里 2. 使用eclipse 里Help菜单的“Install New Softwa ...

  8. Source Insight 创建工程(linux-2.6.22.6内核源码)

    1. 软件设置 安装完Source Insight,需要对其进行设置添加对“.S”汇编文件的支持: 2. 新建linux-2.6.22.6工程 1)选择工程存放的路径: 2)下载linux-2.6.2 ...

  9. 微信小程序<每日查看>开发总结

    之前一直在做iOS平台的App和SDK开发,发现微信小程序还蛮有意思的,花了将近几天的时间,从看书学习到萌发想法,最后开发出一款小应用,现在花点时间总结一番!作为自我勉励和后续继续学习动力- 先上效果 ...

  10. python中的控制流

    ifpython条件语句是通过一条或多条语句的执行结果(True或false)来决定执行的代码块 if语句用于控制程序的执行,基本形式为:if 判断条件:执行语句....elif判断语句:执行语句.. ...