美文网首页程序员
C# 进程间通信(一)

C# 进程间通信(一)

作者: Lance李永乐 | 来源:发表于2019-04-02 15:07 被阅读0次

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 基本的通信方式确定了,接下来需要处理两个进程通信时的多线程问题。

相关文章

  • C# 进程间通信(一)

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

  • C# 进程间通信

    使用SendMessage向另一进程发送WM_COPYDATA消息 Send端: Get端: 参考文档: c# 进...

  • C#命名管道通信

    C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI、发消息等。但在Windows下面发消息需...

  • linux进程间通信(1)

    一、进程通信概述 1、什么是进程间通信?什么是线程间通信? 进程间通信: 进程间通信就指的是用户空间中进程A与进程...

  • 进程间的通信

    进程间的通信主要分为本机器进程间的通信和不同机器间进程的通信。本文主要描述本机进程间的通信。 一、传统Linux的...

  • 第二十三章 进程间通信介绍(一)

    本章目标: 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对...

  • 进程管理(五)进程间通信、死锁

    (一)进程间通信 除了同步和互斥外,进程间还有其他的通信手段。 进程间的通信 --> IPC (InterProc...

  • c#使用SendMessage进程间通信

    使用SendMessage向另一进程发送WM_COPYDATA消息 Send端: using System; us...

  • 进程间通信

    进程间通信 进程空间相对独立,资源无法相互获取,此时在不同进程间通信需要专门方法 进程间通信就是在不同的进程间进行...

  • 进程间通信,线程间通信

    进程间通信 进程间通信又称IPC(Inter-Process Communication),指多个进程之间相互通信...

网友评论

    本文标题:C# 进程间通信(一)

    本文链接:https://www.haomeiwen.com/subject/kwvmbqtx.html