C# 进程间通信(一)

Introduction

最近接到一个任务,需要把两个exe间的通信模式由 COM 改为非 COM 的模式。

原因是在win10 UAC模式下,部分COM调用会产生 " No such interface supported" 的错误。

估计给微软开case,他们也会像往常一样糊弄过去。

具体缘由也不细说了,这里主要记录一下除了COM以外,C# IPC (Inter-Process Communication) 的几种主要方法。


Scenario

现有 A.exe  B.exe 两个进程,这两个进程没有父子关系,且位于不同的目录。

现在需要 A 按顺序控制 B 执行一些操作。

B 中的方法: 1. Lock()    2. InitData()    3. Run()    4.GetStatus()

前三个方法只需要返回 True False 给 A 就可以了,第四个方法需要返回当前 Status (一个自定义类,包含状态号码和描述信息)


SendMessage

首先想到的是用 Win API: SendMessage WM_COPYDATA

这个原理上很简单,A send message 给 B, B 接收到message后执行一些逻辑,期间 A 阻塞直到 SendMessage 返回。

由于期间牵扯到托管类型与非托管类型的转换,网上各种博客的代码大多是不能拿来就用的。

这里推荐MSDN的一个示例代码:https://code.msdn.microsoft.com/windowsapps/CSReceiveWMCOPYDATA-dbbc7ed7

对于B的前三个方法,SendMessage都是管用的, 但是第四个方法要求返回一个类。

SendMessage 不能改变返回类型,也无法由 B.exe 更改 lParam 传递回 A.exe 。

MS DOC: The receiving application should consider the data read-only. The lParam parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by lParam. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer.

只能让 B 在收到消息后再发一条给 A 作为返回信息。这样就大大增加了通讯的复杂度。

我这里的需求,要考虑其他方法进行 IPC 。


System.IO.Pipes

Anonymous Pipes & Named Pipes 有什么区别,应该用哪个?

An anonymous pipe is an unnamed, one-way pipe that typically transfers data between a parent process and a child process. Anonymous pipes are always local; they cannot be used for communication over a network.

关键词:one-way pipe,parent and child, always local

named pipe is a named, one-way or duplex pipe for communication between the pipe server and one or more pipe clients. All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles, and provides a separate conduit for client/server communication. The use of instances enables multiple pipe clients to use the same named pipe simultaneously. Named pipes can be used to provide communication between processes on the same computer or between processes on different computers across a network.

关键词:duplex pipe, multiple pipe clients, across a network

由此,区别很明显了,Named Pipes 适用于更复杂的需求,双向管道,多个Client进程,跨网络等。

虽然匿名管道似乎足够了,但这里我还是打算使用命名管道,谁知道需求会不会提升呢?

示例代码中包含了 Native Method 和 Managed Method 两种模式。

示例代码:https://code.msdn.microsoft.com/windowsapps/CSNamedPipeServer-4c760c2c  

ReadMode 采用 PipeTransmissionMode.Message

示例代码中可看到,这种模式下管道只能 read,write 字节数组,而我想传一个自定义类型的对象。

这里就需要用到C#的序列化和类型转换。

string >> bytes:  System.Text.Encoding.UTF8.GetBytes(myString)

bytes >> stream: var stream = new MemoryStream(bs)

stream >> object: var formatter = new BinaryFormatter();    myObj = formatter.Deserialize(stream);

object >> stream: var formatter = new BinaryFormatter();    formatter.Serialize(stream, myObj);

stream >> bytes:  stream.ToArray();

bytes >> string: System.Text.Encoding.UTF8.GetString(bs)

按照上面的套路,发送时:object >> stream >> bytes    接收时:bytes >> stream >> object

还有一点需要注意,就是两个进程传递一个对象,该对象的类不能分别在两个Project中定义(虽然同名但不会被识别为同一个类)。这里我将MyClass定义在一个单独的 dll 中。两个Project都需要引用这个dll 。简单的数据也可以封装为Dictionary<string,string>  或 List < Dictionary <string,string>>  这种形式,这样就不用去单独搞一个dll两边加了。

OK 基本的通信方式确定了,接下来需要处理两个进程通信时的多线程问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,279评论 0 10
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,351评论 0 23
  • 回想2008年,你能想到什么?奥运会开幕式上一个一个印在天上的大脚印?还是扎堆出生的奥运宝宝?那一年,值得称道的,...
    adamant555阅读 133评论 0 0
  • 王晴觉得她一生寻寻觅觅的,是心目中那个最完美的爱情和完美的情人。 刚刚开始记事那会,觉得爸爸的手臂强劲有力,总能把...
    叶子很忙阅读 225评论 2 0
  • 在建军九十周年来临之际,在慰问青岛武警支队的舞台上,民族舞组合《美丽的中国梦》引来了台下官兵的一阵阵掌声,一个矫健...
    崇芳阅读 842评论 1 2