node.js子进程在节点webkit中不起作用 [英] node.js child process doesn't work in node webkit

查看:105
本文介绍了node.js子进程在节点webkit中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用node webkit制作了一个小应用程序.预包装,效果很好.但是在压缩它并将其添加到node-webkit.app的Contents/Resources中之后,运行该应用程序时出现错误.它可以很好地打开,但是它的任务确实涉及子进程,并且出现此错误:

未捕获的node.js错误 错误:产生ENOENT.

我猜测这可能与以下问题相关: Node- Webkit子流程执行程序

因为我的子进程正在调用pdftk(一个单独的命令行程序).最终,我希望将pdftk作为我的应用程序的一部分进行安装-我还无法弄清楚该怎么做.我尝试将其作为要与应用程序其余部分一起压缩的内容之一,但这导致该应用程序在启动后立即崩溃(它将打开具有正确标题但没有内容的窗口,该窗口将立即关闭)./p>

因此,主要问题是,如何将pdftk作为打包的node-webkit应用程序的一部分进行安装,以便可以通过双击图标而不是使用命令行来启动该应用程序?感谢您的帮助.

解决方案

我假设您有问题的代码是通过node-webkit的node-main入口点执行的: https://github.com/rogerwang/node-webkit/issues/2518

如何防止Node-Webkit立即崩溃

将代码包装在try/catches中,以防止崩溃并获取崩溃发生原因的信息.

try {

    the_child_process = child_process.spawn(pathToBin, args);

} catch (err) {

    global.console.log( "Error while trying to start child process: " + JSON.stringify(err) );
}

这是针对您正在寻找问题的真正原因的情况的一般建议.

如何在您的node-webkit应用中包含二进制文件

涉及一些事情.

  1. 包括app.nw中的二进制文件

    这应该是不言而喻的-但是有一个警告给我带来了一些麻烦: 确保通过chmod 755将二进制文件标记为可执行文件.如果您使用grunt,则可能会喜欢grunt-chmod. 现在,您的二进制文件已成为您应用程序包的一部分,您可以通过知道 absolute 路径来执行它们.

  2. 即使在打包时也要在运行时解析二进制文件的路径.以下代码段是我的解决方案,用于在您的工具为多平台的情况下为当前平台选择正确的二进制文件.此外,它还假定您的二进制文件在特定的文件夹结构中排序.或者,在构建过程中选择正确的二进制文件,并始终使用相同的路径.

    var arch = process.arch;
    var platform = process.platform;
    // this will return the root path of your app-package at runtime
    var rootDir = process.cwd(); 
    var isWin = false;
    
    var execPath = rootDir;
    
    // some base path is appended
    execPath = path.join(execPath, 'path', 'to', 'bin');
    
    // select folder for current platform
    switch (platform) {
        case 'darwin':
            execPath = path.join(execPath, 'mac');
            break;
        case 'linux':
            execPath = path.join(execPath, 'lin');
            break;
        case 'win32':
            execPath = path.join(execPath, 'win');
            isWin = true;
            break;
        default:
            global.console.log("unsupported platform: " + platform);
            return null;
    }
    
    // select folder for current processor architecture
    switch (arch) {
        case 'ia32':
            execPath = path.join(execPath, 'x86');
            break;
        case 'x64':
            execPath = path.join(execPath, 'x64');
            break;
        default:
            global.console.log("unsupported architecture: " + arch);
            return null;
    }
    
    // add executable filename
    execPath = path.join(execPath, 'node');
    
    if (isWin) {
        execPath = execPath + ".exe";
    }
    
    global.console.log("Path to your binary: " + execPath);
    
    return execPath;
    

  3. 解析最终作为参数提供给二进制文件的路径.这也有点令人困惑,因为所有路径都被视为相对于应用程序包根路径的相对路径.我的node-main文件位于我的应用程序包中的文件夹中,因此我认为我应该从那里引用相对文件,但事实并非如此.

    app package root
    |--- package.json     <- node-webkit package.json
    |
    |--- client           <- here my sources for the frontend reside
    |
    |--- server           
    |----|--- node_modules  <- server runtime dependencies
    |----|--- src           <- server source code
    |----|----|--- server.js  <- this is my node server file to execute via node
    |
    |--- node-webkit      <- node webkit code and dependencies
    |----|--- bin           <- a directory with my deployed binaries
    |----|--- node-main.js  <- this is my node main file
    

要用我的服务器文件调用节点二进制文件,以下行会导致成功:

    child_process.spawn(absPathToNodeBin, "server/src/server.js");

I made a small app with node webkit. Pre-packaging, it works fine. But after I zipped it and added it to Contents/Resources in node-webkit.app I get an error when I run the app. It opens fine, but the task it does involves child processes, and I get this error:

Uncaught node.js Error Error: spawn ENOENT.

I'm guessing it might be something related to the issue raised in this question: Node-Webkit Child Process Exec

because my child processes are calling pdftk, a separate command line program. Ultimately, I'd love to install pdftk as part of my app - I have not been able to figure out how to do this. I tried including it as one of the things to be zipped with the rest of the app, but that caused the app to crash immediately after launch (it would open a window with the correct title but no contents, which would immediately close).

So, main question is, how do I install pdftk as part of a packaged node-webkit app, so that the app can be launched simply by double clicking the icon rather than using the command line? Thanks for any help.

解决方案

I am assuming your code in question is executed via the node-main entry point of node-webkit: https://github.com/rogerwang/node-webkit/wiki/Node-main

If any exception happens (there) which is not catched in your application will crash.

Sadly at the moment the breakpad feature for getting crashdumps is not working on OSX: https://github.com/rogerwang/node-webkit/issues/2518

How to prevent Node-Webkit from crashing immediately

Wrap the code in try/catches to prevent the crash and get information why the crash occurs.

try {

    the_child_process = child_process.spawn(pathToBin, args);

} catch (err) {

    global.console.log( "Error while trying to start child process: " + JSON.stringify(err) );
}

This is a general advice for a situation like you are experiencing to track down the real cause for the issue.

How to include a binary with your node-webkit app

There are a few things involved.

  1. Including the binaries inside your app.nw

    This should be self explanatory - but there is one caveat which caused me some trouble: Make sure the binary is marked as executable via chmod 755. If you are using grunt you might like grunt-chmod. Now your binaries are part of your app's package and you can execute them by knowing the absolute path.

  2. Resolve the path to the binary at runtime even when packaged. The following piece of code is my solution for selecting the right binary for the current platform assuming your tool is multi platform. Also it assumes your binaries are ordered in a certain folder structure. Alternatively select the right binary in your build process and use always the same path.

    var arch = process.arch;
    var platform = process.platform;
    // this will return the root path of your app-package at runtime
    var rootDir = process.cwd(); 
    var isWin = false;
    
    var execPath = rootDir;
    
    // some base path is appended
    execPath = path.join(execPath, 'path', 'to', 'bin');
    
    // select folder for current platform
    switch (platform) {
        case 'darwin':
            execPath = path.join(execPath, 'mac');
            break;
        case 'linux':
            execPath = path.join(execPath, 'lin');
            break;
        case 'win32':
            execPath = path.join(execPath, 'win');
            isWin = true;
            break;
        default:
            global.console.log("unsupported platform: " + platform);
            return null;
    }
    
    // select folder for current processor architecture
    switch (arch) {
        case 'ia32':
            execPath = path.join(execPath, 'x86');
            break;
        case 'x64':
            execPath = path.join(execPath, 'x64');
            break;
        default:
            global.console.log("unsupported architecture: " + arch);
            return null;
    }
    
    // add executable filename
    execPath = path.join(execPath, 'node');
    
    if (isWin) {
        execPath = execPath + ".exe";
    }
    
    global.console.log("Path to your binary: " + execPath);
    
    return execPath;
    

  3. Resolve the paths which are fed to your binary as arguments eventually. This was also a bit confusing because all paths were treated as relative to the app's package root path. My node-main file resides in a folder in my app package so I thought I should reference files relative from there, but this was not the case.

    app package root
    |--- package.json     <- node-webkit package.json
    |
    |--- client           <- here my sources for the frontend reside
    |
    |--- server           
    |----|--- node_modules  <- server runtime dependencies
    |----|--- src           <- server source code
    |----|----|--- server.js  <- this is my node server file to execute via node
    |
    |--- node-webkit      <- node webkit code and dependencies
    |----|--- bin           <- a directory with my deployed binaries
    |----|--- node-main.js  <- this is my node main file
    

To invoke a node binary with my server file the following line led to success:

    child_process.spawn(absPathToNodeBin, "server/src/server.js");

这篇关于node.js子进程在节点webkit中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆