【问题标题】:Restarting a PowerShell script after the last process is closed在最后一个进程关闭后重新启动 PowerShell 脚本
【发布时间】:2022-10-15 17:44:19
【问题描述】:

我写了一个脚本,它打开了 7 个程序大约 10 次(是的,它是一个恶作剧脚本)。

我的问题是,有没有办法观察最后一个进程是否已关闭,如果是,则再次重新启动整个脚本?

while ($start -le 10){
  Start-Process mspaint.exe
  Start-Process notepad.exe
  Start-Process write.exe
  Start-Process cmd.exe
  Start-Process explorer.exe
  Start-Process control.exe
  Start-Process calc.exe
  $start =+ 1
}

我的脚本现在如下所示:

$start; $process

PowerShell.exe -windowstyle hidden { script.ps1 }

while ($start -le 10){
    Start-Process mspaint.exe
    Start-Process notepad.exe
    Start-Process write.exe
    Start-Process cmd.exe
    Start-Process explorer.exe
    Start-Process control.exe
    Start-Process calc.exe
    $start =+ 1
}

$process = Get-Process mspaint.exe

if ($process = $false){
    Start-Process -FilePath c:/script.ps1
}

我确实对此进行了测试,但它又重新开始了...我认为我使用 Get-Process 错误...

是否有其他方法可以观察该过程是否已关闭?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    如果在同一个无限期运行的脚本中处理重新启动是可以接受的:

    # Note: This runs indefinitely.
    # If run in the foreground, you can use Ctrl-C to stop.
    while ($true) {
      1..10 | ForEach-Object {
        # Launch all processes and pass information 
        # about them through (-PassThru)
        'mspaint.exe',
        'notepad.exe',
        'write.exe',
        'cmd.exe',
        'explorer.exe',
        'control.exe',
        'calc.exe' | ForEach-Object {
            Start-Process -PassThru $_
          }
      } | Wait-Process # Wait for all processes to terminate.
      # Continue the loop, which launches the programs again.
    }
    

    然后,您可以通过Start-Process 在后台不可见地启动脚本;例如。:

    Start-Process -WindowStyle Hidden powershell.exe '-File c:script.ps1'
    

    警告:要停止操作,您必须找到隐藏的 PowerShell 进程并终止它。如果添加-PassThru,您将获得一个代表隐藏进程的进程信息对象。


    如果您希望能够正常调用脚本本身,并让它产生一个隐藏的后台进程来监视启动的进程然后重新调用脚本(不可见),则需要做更多的工作:

    # Launch all processes 10 times and
    # collect the new processes' IDs (PIDs)
    $allPids = (
      1..10 | ForEach-Object {
        'mspaint.exe',
        'notepad.exe',
        'write.exe',
        'cmd.exe',
        'explorer.exe',
        'control.exe',
        'calc.exe' | ForEach-Object {
            Start-Process -PassThru $_
        }
      }
    ).Id
    
    # Launch a hidden PowerShell instance
    # in the background that waits for all launched processes
    # to terminate and then invisibly reinvokes this script:
    Start-Process -WindowStyle Hidden powershell.exe @"
    -Command Wait-Process -Id $($allPids -join ',');
    Start-Process -WindowStyle Hidden powershell.exe '-File "$PSCommandPath"'
    "@
    

    警告:要停止操作,您必须找到隐藏的 PowerShell 进程并终止它。

    【讨论】:

    • 它有效,我希望它是怎样的!这正是我需要的,非常感谢!
    • 很高兴听到它,@ItsJustHaga;我的荣幸。
    【解决方案2】:

    在没有看到您的实际脚本的情况下,您可以使用类似的东西

    $validate  = Get-Process -Name pwsh 
    
    if ($validate){
    Start-Process -FilePath c:/script.ps1
    }
    

    【讨论】:

    • 我添加了我的脚本。谢谢提醒,忘记加了>.<
    • $validate = Get-Process -Name Calculator if ($validate){ Start-Process -FilePath c:/script.ps1 }
    • 我测试了你的代码,但遗憾的是脚本会重复自己,即使进程没有关闭......
    • 好吧,您的 while 循环没有一个好的停止,因为它说 while($true)$true 始终是 $true 它永远不会退出 while 循环。这意味着它将继续运行您放入其中的任何内容。你应该尝试在你的 while 循环中加入一些会改变的东西。或使用倒计时使其退出。然后,如果需要,使用我给您的检查返回 while 循环。这是一些可能有帮助的文档。 learn.microsoft.com/en-us/powershell/module/…
    • 我试过如下:Powershell $process = Get-Process mspaint.exe if ($process = $false){ Start-Process -Filepath c:/script.ps1 }
    猜你喜欢
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多