只想实现一个简单的进程建通信,有什么快速实现方式?
1 进程单例需求 / Windows 消息与 IMessageFilter
如果需求是实现一个进程单例,在启动第二个进程时,期望能自动唤起第一个进程的窗口。
可以参见:
C#/WPF 仅启动一个进程实例 - J.晒太阳的猫 - 博客园
但有个问题,如果实现了最小化到托盘(WPF/.net core WPF 系统托盘支持)这个功能,则这个唤醒将会失效。
原因:窗口隐藏之后,将不会接收到 windows 消息。详情和怎么解,可以看: C#向无窗口的进程发送消息_C#教程_脚本之家
但这个实现依赖于 WinForm,在 WPF 下是不生效的。(Message Filters in WPF ?)
所以,如果是 WinForm 程序,可以通过 IMessageFilter
实现简单的进程间通信,发个指令还是 OK 的。
2 WPF 程序
WPF 可以使用远程代理实现。
RemotingServices 类 (System.Runtime.Remoting) | Microsoft Docs
简单的实现如下:
- 服务端(被调用端)
// 服务端可以被代理调用的类
internal class OneServiceRemoteProvider : MarshalByRefObject
{
public string DoSomething(string parameter)
{
// do something
}
}
// 服务端初始化代码:
public const string ServiceIpcPortName = "B7262FBA-0498-46BF-B4D5-E6D54A1A636B"; // 定义一个 IPC 端口
var remoteProvider = new OneServiceRemoteProvider();
// 将 remoteProvider/OneServiceRemoteProvider 设置到这个路由,你还可以设置其它的 MarshalByRefObject 到不同的路由。
RemotingServices.Marshal(remoteProvider, "one");
ChannelServices.RegisterChannel(new IpcChannel(ServiceIpcPortName), false);
- 客户端(调用端)
var oneRemoteProvider = (OneServiceRemoteProvider)Activator.GetObject(typeof(OneServiceRemoteProvider), $"ipc://{ServiceIpcPortName}/one");
// 在这里就可以通过 oneRemoteProvider 实现对服务端的远程调用了。
其它问题:
1 参数仅能传递基础类型,不支持事件和委托,如果传递引用类型,需要可序列化。
2 这里的服务端和客户端只是逻辑概念,只要知道对方的 IPC 端口号和路由地址,就可以实现调用。
3 .net core / .net core WPF 程序
.net core 已经不在提供 Remoting 的支持,.NET Framework technologies unavailable on .NET Core - .NET Core | Microsoft Docs
所以,得另想办法,微软官方推荐的就是 Pipe . System.IO.Pipes Namespace | Microsoft Docs
在 .net framework 下也可以用。
Pipe 使用示例:
// 待续
c# - Example of Named Pipes - Stack Overflow