0

I have a powershell script that will automatically print all .pdf files in a folder with Foxit. I have it set to wait until Foxit has exited until the script continues. Every once in a while, the script will pause and wait even though Foxit has already exited. Is there a way to make it time out after a certain amount of time?

Here is the code I have:

Start-Process $foxit -ArgumentList $argument -Wait
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry

I've tried the recommendations here and they don't seem to work. For example if I do:

$proc = Start-Process $foxit -ArgumentList $argument
$proc.WaitForExit()
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry

I get:

You cannot call a method on a null-valued expression.

Any help would be greatly appreciated.

Community
  • 1
  • 1
Alex McKenzie
  • 892
  • 2
  • 10
  • 20

4 Answers4

1

I think I figured it out. If I start it with Invoke-WmiMethod I can get the process ID and wait for it, then ask it to time out.

$proc = Invoke-WmiMethod -Class win32_process -Name create -ArgumentList "$foxit $argument"
Wait-Process -Id $proc.ProcessId -Timeout 120
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry

This seems to work pretty consistantly.

Alex McKenzie
  • 892
  • 2
  • 10
  • 20
0

One way to implement a timeout is to use a background job:

$Job = start-job -ScriptBlock { write-output 'start';Start-Sleep -Seconds 15 }

$timeout = New-TimeSpan -Seconds 10
$timer = [diagnostics.stopwatch]::StartNew()

  While ($timer.Elapsed -le $timeout)
   {
    if ($Job.State -eq 'Completed' )
     {
      Receive-Job $Job
      Remove-Job  $Job
      Return
     } 
     Start-Sleep -Seconds 1
    } 
      write-warning 'Job timed out.  Stopping job'
      Stop-Job $Job
      Receive-Job $Job
      Remove-Job  $Job
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • Using the backgroud job wasn't working for me. I'm not exacty sure why but I think it has to do with the variables not passing on to the job. – Alex McKenzie Nov 19 '13 at 17:39
0

I ran into this same problem and found a slightly simpler solution that also captures the output of the child process. The -PassThru argument is key as it returns a process object for each process that the cmdlet starts.

$proc = Start-Process $foxit -ArgumentList $argument -PassThru
Wait-Process -Id $proc.Id -Timeout 120
Move-Item $filePath $printed[$location]
Add-Content "$printLogDir\$logFileName" $logEntry
Community
  • 1
  • 1
0

I prefer this style to have better control what to do during the runtime of the external process:

$waitTime = 60
$dism = Start-Process "$env:windir\system32\dism.exe" -ArgumentList "/Online /Cleanup-Image /ScanHealth" -PassThru -WindowStyle Hidden
while (!$dism.HasExited -or $waitTime -gt 0) {sleep -Seconds 1; $waitTime--}
"done."

By cheking the HasExited-attribute I can continue with my code with any other tasks in parallel.

Carsten
  • 1,612
  • 14
  • 21