Javascript 带C/C+的终端服务器上的IPC+;一个nw.js/node.js/node-native-module(C+;+;)?
我有一个Win32 DLL(C++),它作为插件加载到另一个应用程序中。DLL启动一个nw.js实例(ShellExecuteEx和SEE_MASK_NOCLOSEPROCESS)并在DLL卸载时结束(通过ShellExecuteEx的hInstance)。我需要一种向nw进程发送字符串(普通ansi)并检索答案(也是字符串)的方法。旧方法是一个简单的http请求,其响应在主体中。但在开发过程中环境发生了变化,“包”应用程序dll nw由同一用户多次运行,多个用户在同一台机器(终端服务器)上运行。所以端口列表是“不可能的”(是随机端口或单例nw,但不是) 我找到了不同的方法:Javascript 带C/C+的终端服务器上的IPC+;一个nw.js/node.js/node-native-module(C+;+;)?,javascript,c++,node.js,ipc,nw.js,Javascript,C++,Node.js,Ipc,Nw.js,我有一个Win32 DLL(C++),它作为插件加载到另一个应用程序中。DLL启动一个nw.js实例(ShellExecuteEx和SEE_MASK_NOCLOSEPROCESS)并在DLL卸载时结束(通过ShellExecuteEx的hInstance)。我需要一种向nw进程发送字符串(普通ansi)并检索答案(也是字符串)的方法。旧方法是一个简单的http请求,其响应在主体中。但在开发过程中环境发生了变化,“包”应用程序dll nw由同一用户多次运行,多个用户在同一台机器(终端服务器)上运行
- 套接字端口列表问题
- wm_copydata/wm_…-需要一个带有隐藏窗口的自定义nw插件(无本地nw方式);无请求-响应系统
- RPC-端口列表问题
- DDE—没有本地javascript方式(找到一个使用.net的模块);在我以前的delphi时代,DDE不是一个简单的任务,它失败了很多次,没有逻辑
- 共享记忆-没有经验;期望值:异步、触发器?,无本机javascript方式
- 共享文件-没有经验;期望值:异步、触发器(文件更改时的观察者),但存在同步问题,可能是原生js方式
- 命名管道-无经验;期望值:win32 api和类似于聊天系统(管道内[send broadcast]和管道外[receive broadcast],或两者合一)?如果是,我可以对所有实例使用一个名称,使用唯一标识符并等待正确答案
var server = net.createServer(function(stream) {
stream.on('data', function(c) {
console.log('data:', c.toString());
});
stream.on('end', function() {
//server.close();
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
更新2-我的解决方案
通过命名管道和简化版本的,我找到了一个工作方法
nw.js中的服务器:
var server = net.createServer(function(req) {
req.on('data', function(c) {
console.log(c.toString());
req.write('123|Hello World', 'ascii');
});
});
server.listen('\\\\.\\pipe\\MyAppDynamicGUID');
< C++中的客户端(没有永久连接,奇怪的字符串处理,简化的错误处理):
static std::string PipenameA=“\\\.\\pipe\\MyAppDynamicGUID”;
#定义BUFSIZE 512
std::string SendPipeRequestA(std::string sRequest){
DWORD dwToWrite、DWWRITED、dwRead;
成功;
char chBuf[BUFSIZE];
向量缓冲区;
HANDLE hPipe=CreateFileA(PipenameA.c_str(),GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(hPipe==无效的句柄值)
返回“-1 |管道错误1(连接)”;
dwToWrite=(lstrlenA(sRequest.c_str())+1)*sizeof(char);
bSuccess=WriteFile(hPipe,sRequest.c_str(),dwToWrite,&dwwrited,NULL);
如果(!b成功)
返回“-1 |管道错误2(写入)”;
做{
bSuccess=ReadFile(hPipe,chBuf,BUFSIZE*sizeof(char),&dwRead,NULL);
如果(!bSuccess&&GetLastError()!=错误\u更多\u数据)
打破
insert(buffer.end(),chBuf,chBuf+dwRead);
}而(!b成功);
std::字符串响应(&buffer[0]);
闭柄(hPipe);
返回sResponse.c_str();
}
//Jonny你会得到基于意见的答案,请注意这一点 您可以将数据作为命令行参数注入JS模块 例如
start nw.js MyData
并使用process.argv
在JS中获取它
现在,将数据返回到C++可执行文件/DLL有点棘手。 如果您shell执行该进程,您就可以拥有该进程的句柄。
您可以从JS部件将数据打印到标准输出中,并通过从进程句柄获取标准输出句柄在本机应用程序中读取数据 使用自定义url注册你的nw.js应用程序应该是一种优雅的方式。 例如“github://”、“thunder://”、“twitter://” 在windows上,您可以查看: 使用自定义url,您可以在单实例模式下向nw.js提供简单的参数。见:
如果需要更多数据,base64可能会有所帮助,甚至可以通过LZ字符串压缩方法提供更多数据。问题不在于开始参数。我需要一个永久的可能性发送消息。stdin和stdout也是一个想法,但nw本身不可能用stdXY编写。另外,我不确定对std的读写对于dll来说是否太复杂,因为这部分需要一个额外的线程。dll等待主应用程序的调用,std上的等待会阻塞整个应用程序。
static std::string PipenameA = "\\\\.\\pipe\\MyAppDynamicGUID";
#define BUFSIZE 512
std::string SendPipeRequestA(std::string sRequest) {
DWORD dwToWrite, dwWritten, dwRead;
BOOL bSuccess;
char chBuf[BUFSIZE];
std::vector<char> buffer;
HANDLE hPipe = CreateFileA(PipenameA.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE)
return "-1|Pipe-Error 1 (connect)";
dwToWrite = (lstrlenA(sRequest.c_str())+1)*sizeof(char);
bSuccess = WriteFile(hPipe, sRequest.c_str(), dwToWrite, &dwWritten, NULL);
if (!bSuccess)
return "-1|Pipe-Error 2 (write)";
do {
bSuccess = ReadFile(hPipe, chBuf, BUFSIZE*sizeof(char), &dwRead, NULL);
if (!bSuccess && GetLastError() != ERROR_MORE_DATA)
break;
buffer.insert(buffer.end(), chBuf, chBuf + dwRead);
} while (!bSuccess);
std::string sResponse(&buffer[0]);
CloseHandle(hPipe);
return sResponse.c_str();
}