.Net程序间的通讯与控制
发送端:
复制代码
static void main(string[] args)
{
console.writeline("请输入接收器路径:");
string path = console.readline();
console.writeline("请输入接收器启动参数:");
string para = console.readline();
processstartinfo pi = new processstartinfo();
pi.filename = @path;
pi.arguments = para;
try
{
process.start(pi);
}
catch
{
console.writeline("找不到接收器或出现错误!");
}
console.readkey();
}
复制代码
接收端:
复制代码
static void main(string[] args)
{
if (args.length == 0)
{
console.writeline("未接到信息!");
}
else
{
foreach (string s in args)
{
console.writeline(s);
}
}
console.readkey();
}
复制代码
这样我们就可以用程序a启动程序b,根据a传入的参数,程序b做出相应的处理。不过在wpf中,就没法直接用main中的args参数了。对于wpf,可以用下面的方式处理:
1.在app.xaml 中删除 startupuri,并添加startup
复制代码
<application x:class="wpfapplication65.app"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
startup="application_startup" >
<application.resources>
</application.resources>
</application>
复制代码
2.在app.xaml.cs中填写startup的内容
复制代码
private void application_startup(object sender, startupeventargs e)
{
mainwindow mw = new mainwindow();
foreach(string s in e.args)
{
mw.txtshow.text += s;
}
mw.show();
}
复制代码
这样就可以获取传入的参数了。
但是再改一下需求,我们不仅仅通过程序启动的时候传入参数,而是需要给一个已经启动的程序传入参数,那么就需要用进程通信了ipc了。ipc需要用到windows api,下面将介绍一下wpf实现进程间的通信。
1.新建数据的结构体类库
新建一个类库,类库内容如下:
复制代码
using system;
using system.collections.generic;
using system.linq;
using system.runtime.interopservices;
using system.text;
using system.threading.tasks;
namespace datastruct
{
[structlayout(layoutkind.sequential)]
public struct datastruct
{
public intptr dwdata;
public int cbdata; // 字符串长度
[marshalas(unmanagedtype.lpstr)]
public string lpdata; // 字符串
}
}
复制代码
2.新建信息帮助类库
新建一个类库,引用上一步的结构体类库,类库内容如下:
复制代码
using system;
using system.collections.generic;
using system.linq;
using system.runtime.interopservices;
using system.text;
using system.threading.tasks;
namespace messagehelper
{
public class messagehelper
{
public const int wm_download_completed = 0x00aa;
public const int wm_copydata = 0x004a;
[dllimport("user32.dll", entrypoint = "findwindow")]
public static extern intptr findwindow(string lpclassname, string lpwindowname);
[dllimport("user32.dll", entrypoint = "sendmessage")]
public static extern int sendmessage(intptr wnd, int msg, int wp, ref datastruct.datastruct cds);
}
}
复制代码
3.发送端
首先引用前两部的类库
发送有两种方式:
a.通过进程名
复制代码
var lstprocess = process.getprocessesbyname(txtprocess.text);
if (lstprocess.length > 0)
{
process proc = lstprocess[0];
datastruct.datastruct cds;
cds.dwdata = intptr.zero;
cds.lpdata = txtmsg.text;
cds.cbdata = system.text.encoding.default.getbytes(txtmsg.text).length + 1;
int fromwindowhandler = 0;
messagehelper.messagehelper.sendmessage(proc.mainwindowhandle, messagehelper.messagehelper.wm_copydata, fromwindowhandler, ref cds);
}
复制代码
注意:使用这种方法,如果窗体的showintaskbar=false,也就是不在任务栏显示的话,那么是没有办法通过mainwindowhandle获取窗口的。
b.通过窗口名
复制代码
intptr hwnd = messagehelper.messagehelper.findwindow(null, txttitle.text);
if (hwnd != intptr.zero)
{
datastruct.datastruct cds;
cds.dwdata = intptr.zero;
cds.lpdata = txtmsg.text;
cds.cbdata = system.text.encoding.default.getbytes(txtmsg.text).length + 1;
// 消息来源窗体
int fromwindowhandler = 0;
messagehelper.messagehelper.sendmessage(hwnd, messagehelper.messagehelper.wm_copydata, fromwindowhandler, ref cds);
}
复制代码
注意:使用这种方法,如果有多个窗口的title是一样的,也是会有冲突的。
4.接收端
首先还是先引用前两步的类库。
复制代码
public mainwindow()
{
initializecomponent();
loaded += new routedeventhandler(window_loaded);
}
private void window_loaded(object sender, routedeventargs e)
{
(presentationsource.fromvisual(this) as hwndsource).addhook(new hwndsourcehook(this.wndproc));
}
intptr wndproc(intptr hwnd, int msg, intptr wparam, intptr lparam, ref bool handled)
{
if (msg == messagehelper.messagehelper.wm_copydata)
{
datastruct.datastruct cds = (datastruct.datastruct)system.runtime.interopservices.marshal.ptrtostructure(lparam, typeof(datastruct.datastruct));
txtshow.text = cds.lpdata;
}
return hwnd;
}
推荐阅读
-
PHP程序与服务器端通讯的方法_PHP教程
-
.NET CORE与Spring Boot编写控制台程序应有的优雅姿势
-
Net程序员讲JavaSpringBoot系列:Yml与JSON、XML的区别
-
NET程序的代码混淆、加壳与脱壳
-
.net core i上 K8S(四).netcore程序的pod管理,重启策略与健康检查
-
FA1204电子天平与PC机间的串口通信程序设计
-
.Net程序间的通讯与控制
-
【nodejs原理&源码赏析(5)】net模块与通讯的实现
-
.NET5控制台程序使用EF连接MYSQL数据库的方法
-
Asp.net SignalR 让实时通讯变得简单二--把SignalR寄宿到控制台程序中