从nodejs app运行MSI包

时间:2016-02-12 14:42:59

标签: node.js windows-installer

我想从nodeJS应用程序运行mongoDB MSI包。我尝试按照this问题的答案,但它给了我以下错误:

internal/child_process.js:298
throw errnoException(err, 'spawn');
^
Error: spawn UNKNOWN
    at exports._errnoException (util.js:837:11)
    at ChildProcess.spawn (internal/child_process.js:298:11)
    at exports.spawn (child_process.js:339:9)
    at exports.execFile (child_process.js:141:15)
    at C:\_PROJECTs\nodejs\automation\mongoDB-setup\auto-setup.js:34:5
    at C:\_PROJECTs\nodejs\automation\mongoDB-setup\lib\file.js:31:5
    at C:\_PROJECTs\nodejs\automation\mongoDB-setup\lib\file.js:20:5
    at FSReqWrap.oncomplete (fs.js:82:15)

尝试使用简单的EXE文件(例如puttygen.exe)时,它可以正常工作。

以下是我所拥有的代码的相关部分:

'use strict'
const os = require('os'),
      path = require('path'),
      setup = require('child_process').execFile;

const fileName = 'mongodb.msi';
//const fileName = 'puttygen.exe';
const dest = path.join(os.homedir(), fileName);

// run the installation
setup(dest, function(err, data) {  
  console.log(err);                      
});

我不确定execFile是否也是MSI包的正确方法。

4 个答案:

答案 0 :(得分:1)

const dest = "cmd /c " + path.join(os.homedir(), fileName);

答案 1 :(得分:1)

我建议在这种情况下使用spawn。 (有关更多说明,请参阅node js文档)。在win64上我认为你需要使用参数生成命令行,否则child_process.js将为你做(对于unix也一样)。

以下是您的案例(非ES6):

var os = require('os'),
  path = require('path'),
  setup = require('child_process').spawn;

//1)uncomment following if you want to redirect standard output and error from the process to files
/*
var fs = require('fs');
var out = fs.openSync('./out.log', 'a');
var err = fs.openSync('./out.log', 'a');
*/
var fileName = 'mongodb.msi';

//spawn command line (cmd as first param to spawn)
var child = spawn('cmd', ["/S /C " + fileName], { // /S strips quotes and /C executes the runnable file (node way)
  detached: true, //see node docs to see what it does
  cwd: os.homedir(), //current working directory where the command line is going to be spawned and the file is also located
  env: process.env
  //1) uncomment following if you want to "redirect" standard output and error from the process to files
  //stdio: ['ignore', out, err]
});

//2) uncomment following if you want to "react" somehow to standard output and error from the process
/*
child.stdout.on('data', function(data) {
  console.log("stdout: " + data);
});

child.stderr.on('data', function(data) {
  console.log("stdout: " + data);
});
*/

//here you can "react" when the spawned process ends
child.on('close', function(code) {
  console.log("Child process exited with code " + code);
});

// THIS IS TAKEN FROM NODE JS DOCS
// By default, the parent will wait for the detached child to exit.
// To prevent the parent from waiting for a given child, use the child.unref() method,
// and the parent's event loop will not include the child in its reference count.
child.unref();

希望有帮助:) 如果您想要win32或UNIX版本,它会看起来有点不同,请再次查看文档,或发布另一个请求。 另请参阅child_process.js的源代码。

答案 2 :(得分:0)

运行.msi文件的最佳方法是使用Windows随附的命令行工具,称为msiexec。 因此,以下代码将被剪掉

import * as os from 'os';
import { spawn } from 'child_process';

// /quiet does installing in background process. Use docs to find more. 
export const runMSI = (msiName: string, args?: string[]) => {
    const childProcess = spawn('msiexec', [`/i ${msiName} /quiet`], {
        detached: false,
        cwd: os.homedir(),
    });

    childProcess.stdout.on('data', (data) => {
        console.log('STDOUT: ', data.toString());
    });

    childProcess.stderr.on('data', (data) => {
        console.log('STDERR: ', data.toString());
    });


    childProcess.on('close', (code: number) => {
        console.log('Child exited with code ' + code);
    });
};

答案 3 :(得分:0)

我来自未来>> 2020年7月29日。 nodejs文档建议改为使用execexecFile函数。

为方便起见,child_process模块​​为child_process.spawn()和child_process.spawnSync()提供了一些同步和异步替代方案。这些选择中的每一个都在child_process.spawn()或child_process.spawnSync()之上实现。 https://nodejs.org/api/child_process.html#child_process_spawning_bat_and_cmd_files_on_windows