簡體   English   中英

Windows cmd 或 powershell 腳本啟動程序實例,獲取其 PID 並在一段時間后停止它

[英]Windows cmd or powershell script to start an instance of a program, get its PID and stop it after a time period

我正在嘗試使用 windows 中的命令行腳本來實現以下目標:

  1. 啟動啟動 GUI 的程序 (.exe) 實例(還將一些參數傳遞給命令)
  2. 等待程序執行的特定時間(例如 X 秒)
  3. 終止其執行

可能是程序的多個實例可以並行運行,所以我正在搜索的是一種能夠終止先前由“啟動”命令啟動的程序的特定實例的方法。 我假設的一種可能方式是能夠並獲得它的 PID,但我不確定在使用簡單的命令行腳本時是否可以做到這一點。

我嘗試過的是以下內容:

A)程序實例“A”的命令行腳本

Start "" "C:\Program Files (x86)\XXXX\YYYY.exe" /USER=myUser /PASSWORDD=myPass  /CMDLINEID=winTsk_IntSO_A
timeout 180
taskkill /F /T /IM YYYY.exe /FI "USERNAME eq domain\username"
timeout 30
exit

B)程序實例“B”的命令行腳本

Start "" "C:\Program Files (x86)\XXXX\YYYY.exe" /USER=myUser /PASSWORDD=myPass  /CMDLINEID=winTsk_IntSO_B
timeout 180
taskkill /F /T /IM YYYY.exe /FI "USERNAME eq domain\username"
timeout 30
exit

但顯然,如果我並行運行這兩個腳本,首先執行的 taskkill 命令會終止兩個實例(我將它們作為 windows 計划任務在特定用戶帳戶下運行)。 唯一標識每個實例的參數是 /CMDLINEID但我懷疑我是否可以根據該參數過濾正在運行的任務。

在@filimonic 建議之后,我使用以下 powershell 腳本來實現目標:

A) Powershell 腳本,例如“A”

$process = [System.Diagnostics.Process]::Start(
    'C:\Program Files (x86)\XXXX\YYYY.exe', 
    '/USER=myUser /PASSWORDD=myPass /CMDLINEID=winTsk_IntSO_A')

Write-Host $process.Id
Start-Sleep -Seconds 10

if (-not $process.HasExited) {
    $process.Kill()
}

A) Powershell 腳本,例如“B”

$process = [System.Diagnostics.Process]::Start(
'C:\Program Files (x86)\XXXX\YYYY.exe', 
'/USER=myUser /PASSWORDD=myPass /CMDLINEID=winTsk_IntSO_B')

Write-Host $process.Id
Start-Sleep -Seconds 120

if (-not $process.HasExited) {
    //Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $ppid } | ForEach-Object { Kill-Tree $_.ProcessId }
    //Stop-Process -Id $ppid
    $process.Kill()
}

這是有效的,但是我有以下問題:

  • YYYY.exe 是一個 GUI 應用程序,它的“加載”時間約為 60 秒
  • 第一個具有“10秒”等待期的腳本正常執行,我可以在任務管理器中看到相應的“任務”也終止了
  • 具有“120 秒”等待期的第二個腳本正常執行,但在執行后,任務管理器(相同 PID)中的“任務”仍然運行

在此處輸入圖像描述

關於如何更有效地終止 YYYY.exe 運行實例的任何想法?

從一個腳本:

$process = [System.Diagnostics.Process]::Start('cmd.exe')
$process.Id #PID here
# ... Wait something #
$process.Kill()

從第二個腳本: ($storedProcessId 以某種方式存儲在腳本之間) 您可能需要管理員權限

$process = [System.Diagnostics.Process]::GetProcessById($storedProcessId)
$process.Kill()

當然,您可以使用更多的 powershell-native 方式:

$process = Start-Process -PassThrough -FileName 'cmd.exe'

當然,兩種方式都有帶有命令行 arguments 的變體。 請參閱Process.StartStart-Process 的文檔


所以你的腳本會是這樣的

$process = [System.Diagnostics.Process]::Start(
    'C:\Program Files (x86)\XXXX\YYYY.exe', 
    '/USER=myUser /PASSWORDD=myPass  /CMDLINEID=winTsk_IntSO_A')

Start-Sleep -Seconds 180

if (-not $process.HasExited) {
    $process.Kill()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM