简体   繁体   中英

open a file with default program in node-webkit

I want to give the user any option he want to edit a file, how can I open a file with the default program of the specific file type? I need it to work with Windows and Linux but Mac option would be great too.

as PSkocik said, first detect the platform and get the command line :

function getCommandLine() {
   switch (process.platform) { 
      case 'darwin' : return 'open';
      case 'win32' : return 'start';
      case 'win64' : return 'start';
      default : return 'xdg-open';
   }
}

second , execute the command line followed by the path

var exec = require('child_process').exec;

exec(getCommandLine() + ' ' + filePath);

You can use the open module:

npm install --save open

and then call it in your Node.js file:

const open = require('open');
open('my-file.txt');

This module already contains the logic to detect the operating system and it runs the default program that is associated to this file type by your system.

For file on a disk:

var nwGui = require('nw.gui');
nwGui.Shell.openItem("/path/to/my/file");

For remote files (eg web page):

var nwGui = require('nw.gui');
nwGui.Shell.openExternal("http://google.com/");

Detect the platform and use:

  • 'start' on Windows
  • 'open' on Macs
  • 'xdg-open' on Linux

I am not sure if start used to work as is on earlier windows versions, however on windows 10 it doesn't work as indicated in the answer. It's first argument is the title of the window.

Furthermore the behavior between windows and linux is different. Windows "start" will exec and exit, under linux, xdg-open will wait.

This was the function that eventually worked for me on both platforms in a similar manner:

  function getCommandLine() {
     switch(process.platform) {
       case 'darwin' :
         return 'open';
       default:
         return 'xdg-open';
     }
  }

  function openFileWithDefaultApp(file) {
       /^win/.test(process.platform) ? 
           require("child_process").exec('start "" "' + file + '"') :
           require("child_process").spawn(getCommandLine(), [file],
                {detached: true, stdio: 'ignore'}).unref(); 
  }

If you aim to script some kind of prompt with a default editor or simply chain files opening, you will have to wait until the program ends or fail.

Inspired from PSkocik and Khalid answers.

const {exec} = require('child_process');

let openFile=function(filePath,mute){

    let command=(function() {
        switch (process.platform) { 
            case 'darwin' : return 'open '+filePath+' && lsof -p $! +r 1 &>/dev/null';
            case 'win32' : 
            case 'win64' : return 'start /wait '+filePath;
            default : return 'xdg-open '+filePath+' && tail --pid=$! -f /dev/null';
        }
    })();

    
    if(!mute)console.log(command);
    let child=exec(command);
    if(!mute)child.stdout.pipe(process.stdout);
    
    return new function(){
        this.on=function(type,callback){
            if(type==='data')child.stdout.on('data',callback);
            else if(type==='error')child.stderr.on('data',callback);
            else child.on('exit',callback);
            return this;
        };
        this.toPromise=function(){
            return new Promise((then,fail)=>{
                let out=[];
                this.on('data',d=>out.push(d))
                .on('error',err=>fail(err))
                .on('exit',()=>then(out));
            });
        };
    }();
};

use :

openFile('path/to/some_text.txt')
.on('data',data=>{
    console.log('output :'+data);
})
.on('error',err=>{
    console.log('error :'+err);
})
.on('exit',()=>{
    console.log('done');
});

or :

openFile('path/to/some_text.txt').toPromise()
.then(output=>{
    console.log('done output :'+output.join('\n'));
}).catch(err=>{
    console.log('error :'+err);
});

PS : Let me know if it waits for other sytems than winXX ( Inspired from Rauno Palosaari post but not tested yet ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM