22
This commit is contained in:
@@ -41,6 +41,17 @@ static RE_REQUIRE: Lazy<Regex> =
|
|||||||
|
|
||||||
const INLINE_ENTRY: &str = "__inline_entry__.js";
|
const INLINE_ENTRY: &str = "__inline_entry__.js";
|
||||||
|
|
||||||
|
/// Windows:子进程不创建可见控制台窗口(避免运行 node.exe 时闪黑框)。
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn hide_console_window(cmd: &mut Command) {
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
|
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||||
|
cmd.as_std_mut().creation_flags(CREATE_NO_WINDOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn hide_console_window(_cmd: &mut Command) {}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum NodeError {
|
pub enum NodeError {
|
||||||
#[error("node.exe 未找到(请检查 resources/nodejs/ 是否存在)")]
|
#[error("node.exe 未找到(请检查 resources/nodejs/ 是否存在)")]
|
||||||
@@ -125,6 +136,13 @@ fn build_file_runner(entry_script: &str) -> String {
|
|||||||
}};
|
}};
|
||||||
}})();
|
}})();
|
||||||
|
|
||||||
|
/** Windows 管道子进程:write 后立刻 process.exit 会触发 libuv UV_HANDLE_CLOSING 断言 */
|
||||||
|
function writeAsync(stream, chunk) {{
|
||||||
|
return new Promise((resolve, reject) => {{
|
||||||
|
stream.write(chunk, (err) => (err ? reject(err) : resolve()));
|
||||||
|
}});
|
||||||
|
}}
|
||||||
|
|
||||||
(async () => {{
|
(async () => {{
|
||||||
let raw = "";
|
let raw = "";
|
||||||
process.stdin.setEncoding("utf8");
|
process.stdin.setEncoding("utf8");
|
||||||
@@ -134,29 +152,45 @@ fn build_file_runner(entry_script: &str) -> String {
|
|||||||
require("./{entry_script}");
|
require("./{entry_script}");
|
||||||
|
|
||||||
if (typeof globalThis.__nodejsMain !== "function") {{
|
if (typeof globalThis.__nodejsMain !== "function") {{
|
||||||
process.stderr.write(
|
await writeAsync(
|
||||||
"__EVT__" + JSON.stringify({{
|
process.stderr,
|
||||||
|
"__EVT__" +
|
||||||
|
JSON.stringify({{
|
||||||
type: "log",
|
type: "log",
|
||||||
level: "error",
|
level: "error",
|
||||||
msg: "脚本未注册 globalThis.__nodejsMain",
|
msg: "脚本未注册 globalThis.__nodejsMain",
|
||||||
}}) + "\n"
|
}}) +
|
||||||
|
"\n"
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exitCode = 1;
|
||||||
|
return;
|
||||||
}}
|
}}
|
||||||
try {{
|
try {{
|
||||||
const result = await globalThis.__nodejsMain(params);
|
const result = await globalThis.__nodejsMain(params);
|
||||||
process.stdout.write(
|
await writeAsync(
|
||||||
"__RESULT__" + JSON.stringify(result === undefined ? null : result) + "\n"
|
process.stdout,
|
||||||
|
"__RESULT__" +
|
||||||
|
JSON.stringify(result === undefined ? null : result) +
|
||||||
|
"\n"
|
||||||
);
|
);
|
||||||
process.exit(0);
|
|
||||||
}} catch (e) {{
|
}} catch (e) {{
|
||||||
const msg = (e && (e.stack || e.message)) || String(e);
|
const msg = (e && (e.stack || e.message)) || String(e);
|
||||||
process.stderr.write(
|
await writeAsync(
|
||||||
|
process.stderr,
|
||||||
"__EVT__" + JSON.stringify({{ type: "log", level: "error", msg }}) + "\n"
|
"__EVT__" + JSON.stringify({{ type: "log", level: "error", msg }}) + "\n"
|
||||||
);
|
);
|
||||||
process.exit(2);
|
process.exitCode = 2;
|
||||||
}}
|
}}
|
||||||
}})();
|
}})().catch(async (e) => {{
|
||||||
|
const msg = (e && (e.stack || e.message)) || String(e);
|
||||||
|
try {{
|
||||||
|
await writeAsync(
|
||||||
|
process.stderr,
|
||||||
|
"__EVT__" + JSON.stringify({{ type: "log", level: "error", msg }}) + "\n"
|
||||||
|
);
|
||||||
|
}} catch (_) {{}}
|
||||||
|
process.exitCode = 1;
|
||||||
|
}});
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -369,6 +403,7 @@ async fn run_script_bundle(
|
|||||||
if let Some(dir) = crate::cover_python::locate_cover_scripts_dir() {
|
if let Some(dir) = crate::cover_python::locate_cover_scripts_dir() {
|
||||||
cmd.env("AICLIENT_COVER_SCRIPTS_DIR", dir);
|
cmd.env("AICLIENT_COVER_SCRIPTS_DIR", dir);
|
||||||
}
|
}
|
||||||
|
hide_console_window(&mut cmd);
|
||||||
let mut child = cmd.spawn()?;
|
let mut child = cmd.spawn()?;
|
||||||
|
|
||||||
// 把 params JSON 灌进 stdin
|
// 把 params JSON 灌进 stdin
|
||||||
@@ -456,9 +491,15 @@ async fn run_script_bundle(
|
|||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
|
||||||
let status = child.wait().await?;
|
// 与 stdout/stderr 读取并行等待,避免子进程在管道未排空时退出(Windows libuv)
|
||||||
let stderr_tail = stderr_task.await.unwrap_or_default();
|
let (status, stderr_tail, result_line) = tokio::join!(
|
||||||
let result_line = stdout_task.await.unwrap_or(None);
|
child.wait(),
|
||||||
|
stderr_task,
|
||||||
|
stdout_task,
|
||||||
|
);
|
||||||
|
let status = status?;
|
||||||
|
let stderr_tail = stderr_tail.unwrap_or_default();
|
||||||
|
let result_line = result_line.unwrap_or(None);
|
||||||
|
|
||||||
let _ = tokio::fs::remove_dir_all(&bundle_dir).await;
|
let _ = tokio::fs::remove_dir_all(&bundle_dir).await;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user