提问人:dotenv9 提问时间:11/6/2023 更新时间:11/6/2023 访问量:18
node.js 不会捕获异步 C++ .exe 文件的所有输出
Node.js Does Not Capture All Output from Asynchronous C++ .exe File
问:
Stack Overflow 社区!
我在将 Node.js 与异步 C++ 代码连接时遇到了问题。我有一个用 C++ 编写的可执行文件并编译成 .exe,它使用异步代码。具体而言,某些数据是从异步函数输出的,该函数在代码中的所有后续和类似命令之后执行。cout
问题在于,例如,当使用 或 从 Node.js 运行此 .exe 文件时,并非所有输出都被 Node.js 捕获。异步函数生成的数据似乎没有进入 Node.js 能够捕获的输出流。child_process.exec
child_process.spawn
下面是一个简化的 C++ 代码示例,演示了此问题:
const { spawn } = require('child_process')
const os = require('os')
const path = require('path')
const fs = require('fs')
let fetch
import('node-fetch').then(module => {
fetch = module.default
})
const Router = require('koa-router')
const router = new Router()
let apiScript = null
let accumulatedData = ""
let resolveScriptOutput
function waitForScriptResponse() {
return new Promise((resolve) => {
resolveScriptOutput = resolve
})
}
const ensureScriptRunning = async () => {
if (apiScript) return
const platform = os.platform()
try {
if (platform === 'linux') {
apiScript = spawn('bash', ['-c', './TestApp'], { stdio: ['pipe', 'pipe', 'pipe'] })
} else if (platform === 'win32') {
apiScript = spawn('ConsoleScrach', [], { stdio: ['pipe', 'pipe', 'pipe'] })
// apiScript = spawn(path.join(process.resourcesPath, 'ConsoleScrach.exe'), [], { stdio: ['pipe', 'pipe', 'pipe'] })
} else {
console.error("Unsupported OS platform")
return
}
apiScript.stderr.on('data', (data) => {
console.error(`Ошибка скрипта: ${data}`)
})
apiScript.on('close', (code) => {
console.log(`Процесс скрипта завершен с кодом ${code}`)
apiScript = null; // Позволяет перезапустить процесс при следующем запросе
})
apiScript.stdout.on('data', (data) => {
const outputData = data.toString().trim();
console.log(`Получены данные от скрипта в: ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()}`)
console.log('Получены данные от скрипта:', outputData);
accumulatedData += outputData;
const jsonMatch = outputData.match(/{[\s\S]*}/);
if (jsonMatch) {
try {
const jsonObject = JSON.parse(jsonMatch[0])
if (resolveScriptOutput) {
resolveScriptOutput(jsonObject)
resolveScriptOutput = null
}
// Очистите accumulatedData после успешного разбора JSON
accumulatedData = ""
} catch (parseError) {
console.error('Ошибка при попытке разобрать JSON:', parseError)
if (resolveScriptOutput) {
resolveScriptOutput({ error: 'Invalid JSON received' })
resolveScriptOutput = null
}
}
} else {
console.warn('Не найдено строк JSON в выводе');
}
});
} catch (error) {
console.error('Ошибка при запуске или обработке скрипта:', error)
}
}
router.post('/send-command', async (ctx) => {
const requestBody = JSON.stringify(ctx.request.body)
await ensureScriptRunning()
console.log('Отправка команды:', requestBody)
console.log(ctx.request.body)
try {
apiScript.stdin.write(requestBody + '\n', (err) => {
console.log(`Команда отправлена в исполняемый файл в: ${new Date().getHours()}:${new Date().getMinutes()}:${new Date().getSeconds()}`)
if (err) {
console.error('Ошибка при записи в stdin:', err)
ctx.status = 500
ctx.body = { error: 'Ошибка при отправке команды' }
return
}
})
const scriptResponse = await waitForScriptResponse()
ctx.body = scriptResponse
} catch (error) {
console.error('Произошла ошибка при обработке запроса:', error)
ctx.status = 500
ctx.body = { error: 'Внутренняя ошибка сервера' }
}
})
case 4: {
std::cout << "Starting case 4 start" << std::flush;
unsigned char comadStartEnd[] = { 0x07};
DWORD dwSize = sizeof(comadStartEnd);
DWORD dwBytesWritten = 0;
SendComTread(comadStartEnd, dwSize, dwBytesWritten);
std::cout << "Starting case 4 SendComTread end" << std::flush;
This SendComTread
void SendComTread(unsigned char* data, DWORD dwSize, DWORD dwBytesWritten)
{
BOOL iRet;
std::string message;
message += "SendComTread start";
uint8_t* SendBuff = new uint8_t[(dwSize + 4) * 2]{};
uint8_t* SendBuff2 = new uint8_t[(dwSize + 4) * 2]{ 0 };
memcpy(SendBuff, data, dwSize);
uint8_t crc = Crc8(SendBuff, dwSize);
memcpy(SendBuff + dwSize, &crc, sizeof(uint8_t));
int pos = cobsEncode(SendBuff, dwSize + 1, SendBuff2 + 1);
iRet = WriteFile(hSerial, SendBuff2, pos + 2, &dwBytesWritten, NULL);
message += std::to_string(iRet);
message += "SendComTread end";
std::cout << message << std::flush;
}
我希望看到程序的所有输出,包括 SendComTread 行,但是当我从 Node.js 运行它时,stdout 中缺少这一行。但是,如果我直接从命令行运行 .exe 文件,则所有输出都会正确显示。
如何确保 Node.js 正确捕获所有输出(包括异步输出)?
任何帮助将不胜感激。谢谢!
答: 暂无答案
评论