0

I'm trying to watch a process in a background job, but i think i don't understand background processing in powershell correctly. I'm assuming that because my script doesn't want to work.

$target = "firefox"
$Watch = {
    while (1) {
    sleep -Milliseconds 100
        if(!((get-process $target -ErrorAction SilentlyContinue).Responding -eq $true)) 
        {
            Get-Job -name $target | Stop-Job
            break
        }
    }
}

Start-Job -Name $target -ScriptBlock $Watch

In my opinion, this script should control the "responding" property of my "firefox" process each 100 milliseconds and if firefox hangs or gets closed it should stop the background job.

if I execute this script and then close my firefox process, the Job is still running. It seems like it doesn't care about my Stop-Job command.

if i execute this scipt without any jobs like this, it works like a charm.

$target = "firefox"
while (1) {
    sleep -Milliseconds 100
        if(!((get-process $target -ErrorAction SilentlyContinue).Responding -eq $true)) 
        {
            Write-Host "Hello"
            break
        }
}

if i run this script with jobs, and do the get-job -name $target | stop-job part in the console, it also works. so it just doesn't want to execute my if () {scriptblock} while running as a background job.

is it impossible to run a loop in a Background-Job?

1 Answer 1

1

You are trying to Stop the job from inside the job... which is not possible

PowerShell jobs using different process id and are totally separated, even when you receive the data from the job, the data is "Deserialized" which means it's not the real object just a copy of it.

So, if your purpose is to stop the job when the firefox process is not responding, you can create a simple job like this:

while the process is responding and while not...

$Job = Start-Job {

## Monitor the job and wait until it stop responding...
while ((Get-Process firefox).Responding) {sleep -Milliseconds 100}

## do whatever you want, when it stopped responding...
if (!(Get-Process firefox).Responding) {
    Stop-Process firefox
    Start-Process firefox
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

the purpose of the script is to restart the process, read server data and take a screenshot when the process is not responding. since i want to watch more than one process, i thought it would be the best to do this with a background job for each process that is watched. I also choose a background job because I want to create either a windows Form or a Notify Icon to visualize that the script is running. When I don't do the processing in a background job, my windows form does not respond to anything. If I do my Read,Screenshot and Restart part within the Background job, it also doesn't work.
no, not exactly. if I execute the job like this while (!(Get-Process firefox).Responding) {#do stuff} it completes the job right after starting, because it doesn't monitor the job. while (1) of my code does this monitoring. your job only checks the property one time and if the Process is not responding, it executes the script block until the process is started again. problem of while (1) is, that it doesn't give you any information if the scriptblock is executed or not. that's why i tried to do the stop-job inside the loop, so i can do something whenn the job state is "stopped"
nope, it checks for the responding property which is true, so it will sleep for 100 milliseconds, then it will check if the property is not true, doesn't execute the script block because the property is true, and completes the job. so i guess while (1) is necessary. i tried to break or return out of the while loop, but it was not successfull.
the first while will continue to sleep until the process will not respond, which mean the job will remain running... for the test you can start notepad and run this: $Job = start-job {while ((Get-Process notepad).Responding) {sleep 1}} then do get-job $job.name you will see the job remain running
if i try this exact code in powershell ISE, it completes the job right after starting it. EDIT: ok, i was wrong. it works. it didn't work for me because i didn't assign it to a variable. so thank you very much for your effort!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.