2016-03-16 2 views
6

У меня есть электронное приложение, которое использует child_process.exec для запуска длинных запущенных задач. Я пытаюсь управлять, когда пользователь выходит из приложения во время этих задач.Electron kill child_process.exec

Если они выходят из моего приложения или нажимают на него, детские процессы продолжают работать до тех пор, пока они не закончатся, однако окно электронного приложения уже закрыто и вышло.

Есть ли способ уведомить пользователя о том, что процесс все еще запущен, и когда они закончили, закройте окно приложения?

Все, что я в моем main.js стандартного код:

// Quit when all windows are closed. 
    app.on('window-all-closed', function() { 
    // On OS X it is common for applications and their menu bar 
    // to stay active until the user quits explicitly with Cmd + Q 
    if (process.platform != 'darwin') { 
     app.quit(); 
    } 
    }); 

Должен ли я добавлять чек где-нибудь?

Спасибо за вашу помощь

EDITED

Я не могу показаться, чтобы получить PID из child_process, пока он не закончит. Это мой код child_process

var loader = child_process.exec(cmd, function (error, stdout, stderr){ 
     console.log(loader.pid) 
     if (error) { 
     console.log(error.message); 
     } 
     console.log('Loaded: ', value) 

Должен ли я пытаться получить его по-другому?

+0

Какое желаемое поведение, чтобы автоматически убить дочерний процесс, когда приложение закрыто или фактически разрешить его продолжить до завершения, а затем автоматически закрыть? – mscdex

+0

@mscdex было бы здорово убить все дочерние процессы, а затем выйти из приложения. Возможно ли это? – tjmgis

+0

Кроме того, вы должны получать pids, когда вы вызываете «дочерние процессы» и убиваете его через это. – shriek

ответ

2

ChildProcess испускает exit событие, когда процесс завершен - если вы следить за текущими процессами в массиве, и у них удалить себя после exit пожаров событий, вы должны быть в состоянии только foreach над оставшимися работает ChildProcess.kill() при выходе из приложения.

Это не может быть 100% -ный рабочий код/​​не лучший способ делать что-то, поскольку я не могу проверить его прямо сейчас, но этого должно быть достаточно, чтобы установить вас по правильному пути.

var processes = []; 

// Adding a process 
var newProcess = child_process.exec("mycommand"); 
processes.push(newProcess); 
newProcess.on("exit", function() { 
    processes.splice(processes.indexOf(newProcess), 1); 
}); 

// App close handler 
app.on('window-all-closed', function() { 
    if (process.platform != 'darwin') { 
    processes.forEach(function(proc) { 
     proc.kill(); 
    }); 

    app.quit(); 
    } 
}); 

EDIT: Как shreik упоминалось в комментарии, вы также можете просто хранить ИДП в массиве вместо из ChildProcess объектов, а затем использовать process.kill(pid), чтобы убить их. Может быть, немного более эффективно!

+0

Я продолжал получать сообщение об ошибке proc.kill(); не была функцией – tjmgis

9

Итак, после всяких замечательных комментариев я смог обновить свой код с помощью ряда дополнений, чтобы заставить его работать, поэтому публикую свои обновления для всех остальных.

1) Переход от child_process.exec к child_process.spawn

var loader = child_process.spawn('program', options, { detached: true })

2) Используйте Electron ipcRenderer сообщение от моего модуля к сценарию main.js. Это позволяет мне отправить ИДП в main.js

ipcRenderer.send('pid-message', loader.pid);

ipcMain.on('pid-message', function(event, arg) { 
    console.log('Main:', arg); 
    pids.push(arg); 
}); 

3) Добавить этот ИДП в массив

4) В моем main.js я добавил следующий код, чтобы убить ИДП которые существуют в массиве перед выходом из приложения.

// App close handler 
app.on('before-quit', function() { 
    pids.forEach(function(pid) { 
    // A simple pid lookup 
    ps.kill(pid, function(err) { 
     if (err) { 
      throw new Error(err); 
     } 
     else { 
      console.log('Process %s has been killed!', pid); 
     } 
    }); 
    }); 
}); 

Спасибо за помощь всем.

0

Другое решение. Если вы хотите продолжать использовать exec()

Чтобы убить дочерний процесс, выполняемый exec(), взгляните на модуль ps-tree. Они преувеличивают то, что происходит.

в UNIX, процесс может прекратить с помощью вызова выхода, и это родительский процесс может ожидать этого события с помощью системного ожидания вызова. системный вызов wait возвращает идентификатор процесса завершенного дочернего элемента , так что родительский вопрос указывает, какое из, возможно, многих детей, прекращено. Однако, если родительский континент заканчивается, все его дети имеют , назначенные в качестве нового родителя процессом init. Таким образом, у детей все еще есть родитель, чтобы собирать их статистику состояния и выполнения. (от «операционной системы понятий»)

РЕШЕНИЕ: использование ps-tree получить все процессы, что child_process могли запуститься, так что они

exec() на самом деле работает так:

function exec (cmd, cb) { 
    spawn('sh', ['-c', cmd]); 
    ... 
} 

Итак, проверьте пример и приложите его под свои нужды

var cp = require('child_process'), 
psTree = require('ps-tree'); 

var child = cp.exec("node -e 'while (true);'", function() { /*...*/ }); 

psTree(child.pid, function (err, children) { 
    cp.spawn('kill', ['-9'].concat(children.map(function (p) { return p.PID }))); 
}); 
Смежные вопросы