在后台模式下从 Nodejs 执行 VBS(任务计划程序或 Windows 服务)

Execute VBS from Nodejs in background mode (Tasks Scheduler or Windows Service)

我正在尝试将 Excel 文件从 NodeJS 应用程序转换为 PDF。当我在命令行中启动 Node 时它可以工作,但是当我通过 NSSM 或直接使用 Tasks Scheduler 启动我的 app.bat 作为 Windows 服务时,它不再工作了。

使用下面的脚本,我只能看到 log.txt 中的第一行,这是程序参数。如果一切顺利,我应该会看到 0、1 和 2。遗憾的是,当 Node 在后台运行时,我没有任何数字,所以我猜问题是 CreateObject("Excel.Application") 但我不知道不知道为什么以及如何解决。

VBScript :

    Set objFSO=CreateObject("Scripting.FileSystemObject")
    outFile="C:\Users\admin\Documents\Projects\tools\log.txt"
    Set objFile = objFSO.CreateTextFile(outFile,True)
    objFile.Write Wscript.Arguments.Item(0) & " | " & WScript.Arguments.Item(1) & vbCrLf

    Dim oExcel
    Set oExcel = CreateObject("Excel.Application")
    Dim oBook

    objFile.Write "0" & vbCrLf
    Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))

    objFile.Write "1" & vbCrLf
    oBook.ExportAsFixedFormat xlTypePDF, WScript.Arguments.Item(1)

    objFile.Write "2" & vbCrLf
    oBook.Close True

NodeJS:

    const {exec} = require('child_process');
    exec('"' + Meteor.settings.directories.tools + 'convertToPDF.vbs" "' + outputServerFilePathChild + '.xlsx" "' + outputServerFilePathChild + '.pdf"', (err, stdout, stderr) => {
      if (err) {
        console.log(stderr);
        reject(new Error(stderr));
      } else {
        if (fs.existsSync(outputServerFilePathChild.replace(/ /g, "%20") + ".pdf")) {
          console.log('rename "' + outputServerFilePathChild.replace(/ /g, "%20") + '.pdf" "' + outputServerFilePathChild + '.pdf"');
          exec('rename "' + outputServerFilePathChild.replace(/ /g, "%20") + '.pdf" "' + outputServerFilePathChild + '.pdf"', (err, stdout, stderr) => {
            console.log("File generated: " + outputServerFilePathChild + ".pdf");
                    resolve(outputClientFilePathChild + ".pdf");
                  });
        } else {
          console.log("File generated: " + outputServerFilePathChild + ".pdf");
          resolve(outputClientFilePathChild + ".pdf");
        }
      }
    });

我也试过这样的事情:

    const child2 = spawn('start', [
                '"PDFConverter"',
                'cscript',
                '"C:\Users\admin\Documents\Projects\tools\convertToPDF.vbs"',
                '"C:\Users\admin\Documents\Projects\reports\admin\rebates\customer1 2019-09-30.xlsx"',
                '"C:\Users\admin\Documents\Projects\reports\admin\rebates\customer1 2019-09-30.pdf"'
            ], {
                shell: true,
                windowsHide: true,
            });

但是,它也不起作用。有人有想法吗?

编辑: 这个问题似乎无法解决。很多年前就有人问过同样的问题,至今没有答案...

我找到了答案(但这并不是真正的解决方案)。正如我猜测的那样,问题与 Excel 有关,所以它不是 VBScriptNodeJS.我用 EdgeJsC# 中做了同样的事情,我遇到了同样的问题。

您可以 edit/create 使用其库打开 XML 文件,但不能保存为 PDF 或在服务器模式下使用任何宏。

微软回答:

https://support.microsoft.com/en-us/help/257757/considerations-for-server-side-automation-of-office?wa=wsignin1.0%3Fwa%3Dwsignin1.0

If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully.

The CreateObject function and the CoCreateInstance function return one of the following run-time error messages and cannot be started for Automation... ... ... ...

我也尝试使用 winax(使用 node-ffi 的节点插件),结果相同。它在客户端模式下工作,但在服务器模式下不工作(DispInvoke: Open Microsoft Excel cannot access the file).