如何在Eletron中打开window的powershell

482 阅读1分钟
const { spawn } = require("child_process");
const { app, shell, dialog } = require("electron");
let server;
let powershellProcess;
let isExiting = false;
function startPowerShell() {
  try {
    const command = [
      "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8",
      "[Console]::InputEncoding = [System.Text.Encoding]::UTF8",
      '[Console]::WriteLine("==================== 应用状态 ====================")',
      '[Console]::WriteLine("本地服务器已启动:http://localhost:3000")',
      '[Console]::WriteLine("提示:关闭此窗口将终止应用程序")',
      '[Console]::WriteLine("===================================================")',
      '[Console]::WriteLine("按任意键关闭应用...")',
      '$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null',
      "exit",
    ].join("; ");

    // 使用更简单直接的方式启动PowerShell
    powershellProcess = spawn(
      "powershell.exe",
      ["-NoProfile", "-Command", command],
      {
        stdio: "inherit",
        detached: false,
        windowsHide: false,
      }
    );
    // 处理PowerShell进程退出
    powershellProcess.on("exit", (code) => {
      if (!isExiting) {
        // 用户主动关闭了PowerShell窗口
        app.quit();
      }
    });

    // 处理启动错误
    powershellProcess.on("error", (err) => {
      console.error("启动PowerShell失败:", err);
      dialog.showErrorBox(
        "启动失败",
        `无法启动PowerShell:${err.message}\n请确认系统已安装PowerShell`
      );
      cleanupResources();
      app.quit();
    });
  } catch (err) {
    dialog.showErrorBox("启动异常", err.message);
    cleanupResources();
    app.quit();
  }
}

function cleanupResources() {
  if (isExiting) return;
  isExiting = true;

  if (server) {
    server.close();
  }

  if (powershellProcess && !powershellProcess.killed) {
    powershellProcess.kill();
  }
}
app.whenReady().then(() => {
  startPowerShell();
  startLocalServer();
});

为什么打开window的powershell无法显示任何文字,这是在electron的主进程启动的。。

//electron主进程内容
const { app, shell, dialog } = require("electron");
const http = require("http");
const https = require("https");
const fs = require("fs").promises;
const fsSync = require("fs");
const path = require("path");
const url = require("url");
const { spawn } = require("node:child_process");
const os = require("os");
let server;
let powershellProcess = null;
let isExiting = false;
// MIME类型映射
const mimeTypes = {
  ".html": "text/html",
  ".js": "text/javascript",
  ".css": "text/css",
  ".json": "application/json",
  ".png": "image/png",
  ".jpg": "image/jpeg",
  ".gif": "image/gif",
  ".svg": "image/svg+xml",
  ".ico": "image/x-icon",
};



// 清理资源
function cleanupResources() {
  if (isExiting) return;
  isExiting = true;

  if (server) {
    server.close();
  }

  if (powershellProcess && !powershellProcess.killed) {
    powershellProcess.kill();
  }
}

// 启动PowerShell窗口
function startPowerShell() {
  try {
    const powershellPath =
      "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
    const command = [
      "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8",
      "[Console]::InputEncoding = [System.Text.Encoding]::UTF8",
      '[Console]::WriteLine("==================== 应用状态 ====================")',
      '[Console]::WriteLine("本地服务器已启动:http://localhost:3000")',
      '[Console]::WriteLine("提示:关闭此窗口将终止应用程序")',
      '[Console]::WriteLine("===================================================")',
      '[Console]::WriteLine("按任意键关闭应用...")',
      '$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null',
      "exit",
    ].join("; ");

    // 使用更简单直接的方式启动PowerShell
    powershellProcess = spawn(
      powershellPath,
      ["-NoProfile", "-NoExit", "-Command", command],
      {
        stdio: "inherit",
        detached: false,
        windowsHide: false,
        creationFlags: 0x00000010,
      }
    );

    // 处理PowerShell进程退出
    powershellProcess.on("exit", (code) => {
      if (!isExiting) {
        // 用户主动关闭了PowerShell窗口
        app.quit();
      }
    });

    // 处理启动错误
    powershellProcess.on("error", (err) => {
      console.error("启动PowerShell失败:", err);
      dialog.showErrorBox(
        "启动失败",
        `无法启动PowerShell:${err.message}\n请确认系统已安装PowerShell`
      );
      cleanupResources();
      app.quit();
    });
  } catch (err) {
    dialog.showErrorBox("启动异常", err.message);
    cleanupResources();
    app.quit();
  }
}

function startLocalServer() {
  const port = 3000;
  const host = "localhost";

  server = http.createServer(handleRequest).listen(port, host, () => {
    const localUrl = `http://${host}:${port}`;
    shell.openExternal(localUrl).catch((err) => {
      dialog.showMessageBox({
        type: "error",
        title: "打开浏览器失败",
        message: `请手动访问:${localUrl}`,
        buttons: ["确定"],
      });
    });
  });

  server.on("error", (err) => {
    dialog.showErrorBox(
      "服务器启动失败",
      `端口${port}已被占用:${err.message}`
    );
    cleanupResources();
    app.quit();
  });
}

// 应用生命周期
app.whenReady().then(() => {
  startPowerShell();
  startLocalServer();
});

// 处理应用退出
app.on("before-quit", (event) => {
  if (!isExiting) {
    event.preventDefault();
    cleanupResources();
    setTimeout(() => app.quit(), 100);
  }
});

app.on("will-quit", () => {
  cleanupResources();
});

app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    cleanupResources();
    app.quit();
  }
});

// 处理异常退出
process.on("uncaughtException", (error) => {
  console.error("未捕获异常:", error);
  cleanupResources();
  app.quit();
});

process.on("SIGINT", () => {
  console.log("收到SIGINT信号");
  cleanupResources();
  app.quit();
});