带有 C/C++ 和 nw.js/node.js/node-native-module (C++) 的终端服务器上的 IPC?

Posted

技术标签:

【中文标题】带有 C/C++ 和 nw.js/node.js/node-native-module (C++) 的终端服务器上的 IPC?【英文标题】:IPC on Terminal Server with C/C++ an nw.js/node.js/node-native-module (C++)? 【发布时间】:2015-06-28 10:51:11 【问题描述】:

我有一个 Win32-DLL (C++),它作为插件加载到另一个应用程序中。 DLL 启动一个 nw.js 实例(ShellExecuteEx 和 SEE_MASK_NOCLOSEPROCESS)并在 DLL 卸载时结束它(通过 ShellExecuteEx 的 hInstance)。我需要一种将字符串(普通 ansi)发送到 nw 进程并检索答案(也是字符串)的方法。旧的方式是一个简单的 http-request,响应在 body 中。但是在开发过程中环境发生了变化,“包”app-dll-nw由同一用户多次运行,多个用户在同一台​​机器(终端服务器)上运行。所以端口列表是“不可能的”(是的随机端口或单例 nw,但没有)。

我找到了不同的方法:

socket - 端口列表问题 wm_copydata/wm_... - 需要一个带有隐藏窗口的自定义 nw 插件(没有原生 nw 方式);没有请求响应系统 RPC - 端口列表问题 DDE - 没有原生 javascript 方式(找到了一个使用 .net 的模块);在我以前的 delphi 时代,DDE 不是那么简单的任务,它多次失败,没有逻辑。 共享内存 - 没有经验;期望:异步、触发?,没有原生 javascript 方式 共享文件 - 没有经验;期望:异步,触发器(文件更改的观察者)但同步问题,本机 js 方式可能 命名管道 - 没有经验;期望:win32-api 和类似聊天系统(管道内 [发送广播] 和管道外 [接收广播],或两者合二为一)?如果是,我可以对所有实例使用一个名称并使用唯一标识符并等待正确答案。

什么是一种像 http 方式但没有网络的又好又简单的通信方式?

更新 1:节点模块“net”能够为命名管道创建服务器。第一次测试,将一个字符串从 dll 发送到 nw,成功了。

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 - 我的解决方案

通过命名管道和https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx 的简化版本,我找到了一种工作方法。

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";
#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();

// 强尼

【问题讨论】:

【参考方案1】:

您将获得的答案将基于意见,请注意这一点。

您可以将数据作为命令行参数注入到 JS 模块中 例如 start nw.js MyData 并使用process.argv 将其放入 JS 中。

现在,将数据发送回 C++ 可执行文件/DLL 有点棘手。 如果你用 shell 执行这个过程,你可以拥有它的句柄。 您可以将数据从 JS 部分打印到标准输出中,并通过从进程句柄中获取标准输出句柄在本机应用程序中读取它。

【讨论】:

问题不在于起始参数。我需要一个永久的可能性来发送消息。 stdin 和 stdout 也是一个想法,但 nw 没有原生的可能性来用 stdXY 编写。另外,我不确定对 dll 的 std 读写是否复杂,因为这部分需要一个额外的线程。 dll 等待主应用程序的调用,等待 std 阻塞整个应用程序。【参考方案2】:

使用自定义 url 注册您的 nw.js 应用程序应该是一种优雅的方式。 如“github://”、“thunder://”、“twitter://”

在windows上你可以看看:

https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx

使用自定义 url,您可以在单实例模式下将简单的参数传递给 nw.js。见:

https://github.com/nwjs/nw.js/wiki/Handling-files-and-arguments#open-file-with-existing-app

如果需要更多数据,base64 可能会有所帮助,甚至可以通过 LZ-String 压缩方法提供更多数据。

【讨论】:

以上是关于带有 C/C++ 和 nw.js/node.js/node-native-module (C++) 的终端服务器上的 IPC?的主要内容,如果未能解决你的问题,请参考以下文章

18 个惊人的 Angular 开源项目

带有原始音频记录和播放示例的跨平台 C/C++ 库

无法在带有 VS2017 的 Windows 10 上安装和使用 gRPC C/C++

如何从 python 调用带有 Char** 参数和 int* 参数的 C 方法?

如何在 C/C++ 中使用带有 OpenSSL 的静态链接

使用带有扩展和自定义功能的 groupby