如何通过MATLAB命令获取由MATLAB调用的外部程序的PID?

3
我想知道在MATLAB中(Windows系统),如何获取由MATLAB调用的外部程序的PID。
例如,我通过命令!notepad.exesystem('notepad.exe')在MATLAB中调用notepad。 我想在notepad被调用后立即获取它的PID。
由于在一台计算机上可能同时打开多个notepad,因此我需要获取它们各自的PID(而不是进程名称)以跟踪它们。 我不知道如何实现...寻求帮助,谢谢!
2个回答

3

无需创建日期

您可以使用system在Matlab中调用Windows的tasklist命令,然后解析结果:

name = 'notepad.exe';
[~, s] = system(['tasklist /FI "imagename eq ' name '"']);
result = regexp(s, ['(?<=' strrep(name, '.', '\.') '\s*)\d+'], 'match');
result = str2double(result); % convert to numbers if needed
< p > system 的结果如下(打开两个记事本窗口;西班牙语 Windows 版本):

>> s
s =
    '
     Nombre de imagen               PID Nombre de sesión Núm. de ses Uso de memor
     ========================= ======== ================ =========== ============
     notepad.exe                  12576 Console                    1    13,488 KB
     notepad.exe                  13860 Console                    1    13,484 KB
    '

因此,正则表达式搜索由程序名称和可选空格前导的数字,以给出最终结果。
>> result =
          12576       13860

需要创建日期

如果您需要基于创建日期进行筛选,可以使用Windows的wmic命令:

name = 'notepad.exe';
[~, s] = system(['wmic process where name=''' name ''' get ProcessId, CreationDate']);

这会产生一个字符串,例如:
s =
    'CreationDate               ProcessId  
     20191015151243.876221+120  6656       
     20191015151246.092357+120  4004       

     '
CreationDate 是以 格式 yyyymmddHHMMSS+UUU 表示的,其中 +UUU-UUU 是距离 UTC 的分钟数。
您可以按照以下方式将 s 解析为字符串的单元数组:
result = reshape(regexp(s, '[\d+\.]+', 'match').', 2, []).'; % 2 is the number of columns

这给出
result =
  2×2 cell array
    {'20191015151243.876221+120'}    {'6656'}
    {'20191015151246.092357+120'}    {'4004'}

然后,您可以基于第一列进行过滤。

谢谢你的回答!有没有办法检索每个进程的启动时间?我需要这样做来过滤掉不需要的进程。 - ThomasIsCoding
@ThomasIsCoding 据我所知,tasklist不能实现此功能,但wmic似乎可以。请参见编辑后的答案。 - Luis Mendo

2
创建一个名为findPid.ps1的Powershell脚本,包含以下内容:
Get-Process | Where {$_.ProcessName -eq "notepad"} | Sort-Object starttime -Descending | Select 'Id'

以上脚本获取正在运行的记事本进程信息,按时间进行过滤,并提取pid。


从MATLAB执行非阻塞系统调用:

system('notepad.exe &')

调用Powershell脚本:

[~,pids] = system('powershell -file findPid.ps1');

pids 是一个包含 notepad.exe 进程(或进程)的 pid 的字符向量。

因此,要获取最近的 pid:

pid = regexp(pids,'Id\n[^-]+--\n([0-9]+)','tokens','once')

非常感谢!然而,PowerShell 在我的电脑上运行不好,我想知道是否可以通过 MS-Dos 实现相同的功能,例如包括进程启动时间的 'tasklist' 命令? - ThomasIsCoding
我在别人的Win 10电脑上尝试了您的脚本,它可以正常工作。但是当我在我的Win 7上使用它时,我不知道为什么总是需要按下'MATLAB'中的'Enter'键才能继续运行脚本,因为似乎'MATLAB'在执行'[~,pids] = system('powershell -file findPid.ps1');'之后正在等待某些操作...这很奇怪。 - ThomasIsCoding
哦,Win 10和Win 7上的MATLAB版本一样吗?在什么阶段需要按Enter键? - Paolo
是的,同样的MATLAB R2018b版本。对于***[~,pids] = system('powershell -file findPid.ps1');*** 这行代码,我需要按回车键以继续执行。 - ThomasIsCoding
不知道,我无法重现。尝试重新启动MATLAB。 - Paolo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接