У меня есть Win32-DLL (C ++), которая загружается как плагин в другое приложение. DLL запускает экземпляр nw.js (ShellExecuteEx и SEE_MASK_NOCLOSEPROCESS) и завершает его при выгрузке DLL (с помощью hInstance ShellExecuteEx). Мне нужен способ отправить строку (обычный ansi) в nw-процесс и получить ответ (также строку). По старинке был простой http-запрос с ответом в теле. Но среда изменяется во время разработки, «пакет» app-dll-nw запускается несколько раз одним и тем же пользователем, а несколько пользователей запускаются на одном компьютере (терминальном сервере). Таким образом, перечисление портов «невозможно» (да, случайные порты или синглтон nw, но нет).
Я нашел разные способы:
Что такое хороший и простой способ общения, такой как http-way, но без сети?
Обновление 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();
}
// Джонни
Ответы, которые вы получите, будут основаны на мнении, знайте об этом.
Вы можете вставить данные в модуль JS в качестве аргумента командной строки
например
start nw.js MyData
и получить его в JS с process.argv
,
Теперь отправка данных обратно в исполняемые файлы / библиотеки C ++ немного сложна.
если вы выполняете процесс shell-оболочки, вы можете иметь дескриптор к нему.
Вы можете распечатать данные в стандартный вывод из части JS и прочитать их в собственном приложении, получив дескриптор STDOUT из дескриптора процесса.
Зарегистрировать ваше приложение nw.js с пользовательским URL-адресом должно быть элегантным способом.
Такие как «github: //», «thunder: //», «twitter: //»
На окнах вы можете взглянуть на:
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.