1. 程式人生 > 實用技巧 >參考electron-builder原始碼實現有權拉起exe並執行(nodeJs + spawn)

參考electron-builder原始碼實現有權拉起exe並執行(nodeJs + spawn)

參考https://github.com/electron-userland/electron-builder/blob/aa3625d5f6b719b6a7634c4c7ba0aad1ffe7d3d6/packages/electron-updater/src/NsisUpdater.ts

程式碼塊
/**
 * 執行Clodop.exe
 * CLodop_Setup_for_Win32NT.exe為指定在客戶端裡安裝得exe
 * elevate.exe 解決執行許可權問題,可在打包後的resources資料夾內獲取
 */
function execClodop() {
    let exeUrl = `${path.join(__dirname, '/public/lodop-print/CLodop_Setup_for_Win32NT.exe')}`
    let elevateUrl = `${path.join(__dirname, '/public/lodop-print/elevate.exe')}`
    if (isElectronDev) {
        exeUrl = `${path.join(__dirname, '/public/lodop-print/CLodop_Setup_for_Win32NT.exe')}`
    } else {
        exeUrl = `./resources/app/src/main/public/lodop-print/CLodop_Setup_for_Win32NT.exe'`
        elevateUrl = `./resources/elevate.exe`
    }

    const callUsingElevation = (args) => {
        _spawn(elevateUrl, [exeUrl].concat(args))
            .catch(e => this.dispatchError(e))
    }

    return new Promise((resolve, reject) => {
        const args = ["--updated"]
        args.push("/S")
        args.push("--force-run")
        _spawn(exeUrl, args)
            .catch((e) => {
                // https://github.com/electron-userland/electron-builder/issues/1129
                // Node 8 sends errors: https://nodejs.org/dist/latest-v8.x/docs/api/errors.html#errors_common_system_errors
                const errorCode = (e).code
                console.error(`Cannot run installer: error code: ${errorCode}, error message: "${e.message}", will be executed again using elevate if EACCES"`)
                if (errorCode === "UNKNOWN" || errorCode === "EACCES") {
                    console.log('errorCode', e)
                    callUsingElevation(args, exeUrl)
                } else {
                    console.log('e', e)
                        // this.dispatchError(e)
                }
            })
    })
}
/**
 * This handles both node 8 and node 10 way of emitting error when spawning a process
 *   - node 8: Throws the error
 *   - node 10: Emit the error(Need to listen with on)
 */
async function _spawn(exe, args) {
    return new Promise((resolve, reject) => {
        try {
            const process = spawn(exe, args, {
                detached: true,
                stdio: "ignore",
            })
            process.on("error", error => {
                reject(error)
            })
            process.unref()

            if (process.pid !== undefined) {
                resolve(true)
            }
        } catch (error) {
            reject(error)
        }
    })
}