简体   繁体   English

如何完全停止使用 System.Diagnostic.Process.Start 启动的 .bat 文件(和子进程)

[英]How to fully stop a .bat file (and child processes) started with System.Diagnostic.Process.Start

Context语境

I'm using a.Net System.Diagnostic.Process object from Matlab to run, without any popping-up console window, some external processing for which I redirect, in real time, stdout/stderr to the matlab console (or any matlab progress-gui in the future). I'm using a.Net System.Diagnostic.Process object from Matlab to run, without any popping-up console window, some external processing for which I redirect, in real time, stdout/stderr to the matlab console (or any matlab progress -gui 将来)。

The program to run is a .bat file, that itself runs a python script (preprocessing.py) that finally internally calls an executable (processing.exe).要运行的程序是一个.bat文件,它本身运行一个 python 脚本 (preprocessing.py),最终在内部调用一个可执行文件 (processing.exe)。

So far everything works great including redirection of stdout/stderr, except that when trying to stop execution on matlab side (with ctrl+c ), I can see from the task manager that the call to Process.Kill() does not stop nor the python engine (python.exe) and nor the executable call by the python script (processing.exe).到目前为止,一切正常,包括 stdout/stderr 的重定向,除了尝试在 matlab 端(使用ctrl+c )停止执行时,我可以从任务管理器中看到对Process.Kill()的调用不会停止,也不会停止python 引擎 (python.exe) 和 python 脚本 (processing.exe) 的可执行调用。 My matlab script is then blocked in Process.WaitForExit() until I manually kill python.exe or processing.exe from the task manager.然后,我的 matlab 脚本在Process.WaitForExit()中被阻止,直到我从任务管理器中手动杀死 python.exe 或 processing.exe。

Why the Kill() method on the initial System.Diagnostic.Process ran on.bat file does not kill the other child processes and makes me locked in WaitForExit?为什么初始 System.Diagnostic.Process 上的 Kill() 方法运行 on.bat 文件不会杀死其他子进程并使我锁定在 WaitForExit 中? ... I can force-kill processing.exe but it's dirty (I'm not supposed to know anything about possible child processes started). ...我可以强制杀死 processing.exe 但它很脏(我不应该知道任何可能启动的子进程)。

The matlab code matlab代码

Basically my matlab code looks like this:基本上我的 matlab 代码如下所示:

function [] = main(guicallbacks)
%[
    % Init process
    process = System.Diagnostic.Process();
    process.StartInfo.Filename = 'Processing.bat';
    process.StartInfo.CreateNoWindow = true;
    process.UseShellExecute = false;
    process.RedirectStandardOutput = true;
    process.RedirectStandardError = true;

    % Attach to process events
    l = event.listener(process, 'OutputDataReceived', @onStdOut); l.Recursive = true;
    l = event.listener(process, 'ErrorDataReceived', @onStdErr); l.Recursive = true;

    % Start process
    Start(process);
    cuo = onCleanup(@()stopProcess(process));
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    % Wait for process
    canceled = false;
    while (~double(process.HasExited))
    
        % Check for cancellation (progress gui, etc...)
        canceled = guicallbacks.IsCancelPending();
        if (canceled), break; end

        % Wait
        pause(1.0);

    end

    % Check stop reason
    if (canceled), error('System:OperationCanceledException', 'User cancelation'); end
    if (double(process.ExitCode) ~= 0), error('Process failed (ExitCode = %i)', double(process.ExitCode)); end
%]
end
function [] = onStopProcess(process)
%[
    if (double(process.HasExited())), return; end

    process.Kill();
    process.WaitForExit();
%]
end
function [] = onStdOut(varargin)
%[
    cprintf('blue', char(varargin{2}.Data));
%]
end
function [] = onStdErr(varargin)
%[
    cprintf('red', char(varargin{2}.Data));
%]

The.bat file .bat 文件

Basically, execept for setting a few environment variables the .bat file to call looks like this:基本上,除了设置一些环境变量之外,要调用的.bat文件如下所示:

python.exe -u preprocessing.py

The python script python 脚本

The python script call final processing.exe executable this way: python 脚本调用 final processing.exe 可执行文件如下:

subprocess.call("processsing.exe");

Here below is adaptation in matlab for the solution pointed out by @rahnema1 to fully kill the process and its children (recursively):下面是 matlab 中针对@rahnema1 指出的解决方案的改编,以完全杀死进程及其子进程(递归):

function [] = onStopProcess(process)
%[
    if (double(process.HasExited())), return; end

    killProcessTree(process.Id);
    process.WaitForExit();
%]
end

function [] = killProcessTree(processId)
%[
    % https://stackoverflow.com/a/10402906/684399
    NET.addAssembly('System.Management');
    mos = System.Management.ManagementObjectSearcher(sprintf('Select * From Win32_Process Where ParentProcessID=%i', processId));
    mos = mos.Get();
    mos = mos.GetEnumerator();
    while(mos.MoveNext())
        pd = mos.Current.Properties.Item('ProcessID');
        killProcessTree(double(pd.Value));
    end
    try
        endOfLeafProcess = System.Diagnostics.Process.GetProcessById(processId);
        endOfLeafProcess.Kill();
    catch
    end    
%]
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从主进程使用KeyboardInterrupt停止子进程? - How to use KeyboardInterrupt from the main process to stop child processes? Python 3:我如何启动2个进程,从先完成的那个返回答案,并尽早停止另一个进程 - Python 3: How do i start 2 processes return the answer from whichever finishes first, and stop the other process early 如何使用 Process(target=)、start()、join()、alive() 和 terminate() 使子进程超时 - How to timeout child processes using Process(target=), start(), join(), alive() and terminate() 监督者停止/启动所有进程,但不包括X和Y进程 - supervisord stop/start all process but exclude X and Y processes Python中如何分别启动和停止多处理进程? - How to separately start and stop multiprocessing processes in Python? 如何从 python 杀死进程和子进程? - how to kill process and child processes from python? 在父进程中,如何查看子进程管理的子变量? - In a parent process, how to see child variables that are managed by child processes? 如何阻止多个进程创建另一个进程的多个实例? - How to stop multiple processes from creating multiple instances of another process? 在 Simpy 中,如何同步两个进程以启动第三个进程? - In Simpy, how do I sync two processes to start a third process? 如何与子进程共享父进程的 numpy 随机状态? - How to share numpy random state of a parent process with child processes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM