【问题标题】:How to do something if a job has finished如果工作完成了怎么办
【发布时间】:2016-12-19 02:54:52
【问题描述】:

我正在尝试为我的 PowerShell 脚本实现一个 GUI,以便为其他用户简化某个过程。我有以下 PowerShell 脚本:

if ($checkBox1.Checked)    { 
    Try{
    Start-Job { & K:\sample\adp.cmd }
    $listBox1.Items.Add("ADP-Job started...")
    }catch [System.Exception]{
    $listBox1.Items.Add("ADP --> .cmd File not found!")}
    }

    if ($checkBox2.Checked)    { 
    Try{ 
    Start-Job { & K:\sample\kdp.cmd }
    $listBox1.Items.Add("KDP-Job started...")
    }catch [System.Exception]{
    $listBox1.Items.Add("KDP --> .cmd File not found!")}
    }

有没有办法持续检查所有正在运行的作业并为每个已完成的作业做一些事情?例如在我的列表框中打印出这样的内容:ADP-Files have been uploaded

由于每个 Job 大约需要 5 分钟 - 4 个小时,所以我想到了一个 while 循环,它每 5 分钟检查一次 Job 是否完成,但我不知道如何区分每个 Job 以执行特定的操作。

【问题讨论】:

    标签: powershell jobs


    【解决方案1】:

    这里有多种可能的方式:

    $Var = Start-Job { & K:\sample\kdp.cmd }
    

    然后检查

    $Var.State
    

    或者给工作起个名字

    Start-Job { & K:\sample\kdp.cmd } -Name MyJob
    

    然后检查

    Get-Job MyJob
    

    【讨论】:

      【解决方案2】:

      您可以使用-Name 参数为作业指定名称:

      Start-Job { Write-Host "hello"} -Name "HelloWriter"
      

      并使用Get-Job cmdlet 接收作业状态:

      Get-Job -Name HelloWriter
      

      输出:

      Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
      --     ----            -------------   -----         -----------     --------             -------                  
      3      HelloWriter     BackgroundJob   Completed     True            localhost             Write-Host "hello"
      

      或者您将Start-Job cmdlet 分配给一个变量并使用它来检索作业:

      $worldJob = Start-Job { Write-Host "world"}
      

      所以你可以写$woldJob然后接收:

      Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
      --     ----            -------------   -----         -----------     --------             -------                  
      7      Job7            BackgroundJob   Completed     True            localhost             Write-Host "world" 
      

      您也不必轮询 Job 状态。而是使用Register-ObjectEvent cmdlet 在作业完成时收到通知:

      $job = Start-Job { Sleep 3; } -Name "HelloJob"
      
      $jobEvent = Register-ObjectEvent $job StateChanged -Action {
          Write-Host ('Job #{0} ({1}) complete.' -f $sender.Id, $sender.Name)
          $jobEvent | Unregister-Event
      }
      

      【讨论】:

      • 感谢您的快速答复。因此,如果我给我的 Jobs 单独命名,然后使用 Get-Job -Name cmdlet,我可以创建一条自定义消息,以便在 Job 完成后打印出来,即使这需要几个小时?或者我是否必须制作一个循环,如果它完成了,它每 5 分钟连续检查一次?
      • 你也可以让job完成后自己输出消息
      • 那将是完美的解决方案,但我该怎么做呢?我尝试通过在我的 .cmd 文件后面放置一条写入主机消息来尝试它,但它只是立即打印了该消息,即使作业尚未完成。
      • 我找到了更好的解决方案,请参阅我编辑的答案。我认为这是最好的方法
      • 非常感谢!这太棒了,正是我搜索的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      相关资源
      最近更新 更多