PowerShell Spawn фоновый процесс для поддержания активности - PullRequest
3 голосов
/ 07 марта 2020

У меня есть простая функция поддержания активности, которая будет нажимать ScrollLock каждые 60 секунд, чтобы не дать моему рабочему ноутбуку перейти в спящий режим (изменение настроек управления питанием здесь не вариант, так как эти настройки ограничены для меня в этой рабочей системе) , но этот скрипт зависит от консоли, которая всегда запускает функцию. Может кто-нибудь посоветовать, как заставить эту функцию:

• породить полностью независимый процесс (т.е. не дочерний процесс), который будет продолжать существовать даже после закрытия консоли, выполняющей функцию?

• Сделать этот новый процесс полностью бесшумным, то есть невидимым запуститься как фоновый процесс, который я вижу только при запуске Get-Process?

Возможность создавать независимые (не дочерние) процессы таким способом была бы полезна для многих я думаю, что в других ситуациях такая возможность создания независимого процесса, который не закрывается с вызывающей консолью, была бы действительно полезной.

function KeepAlive {
    $wsh = New-Object -ComObject WScript.Shell
    while($true) {
        $wsh.SendKeys('{SCROLLLOCK}')
        Start-Sleep 60
    }
}

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Я подтвердил, что Start-Process, кажется, начинает совершенно новый процесс. Я думаю, что это может быть правильным подходом. Я предполагаю, что каким-то образом мне нужно запустить новое окно powershell, а затем заставить этот процесс запустить мой код? Немного смущен лучшим подходом здесь: я должен взять код кода Keypress и перенаправить его в файл временного сценария, а затем вызвать этот сценарий из нового Start-Process или есть более эффективный подход к Вы думаете, это?

1 голос
/ 07 марта 2020

Самый простой способ - использовать фоновое задание:

Start-Job {
    $wsh = New-Object -ComObject WScript.Shell
    while($true) {
        $wsh.SendKeys('{SCROLLLOCK}')
        Start-Sleep 60
    }
}

Фоновые задания (прозрачно для вас) приведут к выполнению кода в отдельном дочернем процессе.

Если вы хотите запустить свой код в фоновом режиме в рамках одного и того же процесса, вам нужно назначить свой код для запуска в отдельном пространстве выполнения - пространство выполнения в некоторой степени аналогично " thread "в низкоуровневых языках программирования:

# Create (and open) a new runspace
$rs = [runspacefactory]::CreateRunspace([initialsessionstate]::CreateDefault2())
$rs.Open()

# Create a [powershell] object to bind our script to the above runspaces
$ps = [powershell]::Create().AddScript({
    $wsh = New-Object -ComObject WScript.Shell
    while($true) {
        $wsh.SendKeys('{SCROLLLOCK}')
        Start-Sleep 60
    }
})

# Tell powershell to run the code in the runspace we created
$ps.Runspace = $rs

# Invoke the code asynchronously
$handle = $ps.BeginInvoke()

Функция BeginInvoke() немедленно вернется, и код начнет выполняться в нашем фоновом пространстве выполнения - то есть он не блокирует пространство выполнения по умолчанию, так что вы можно продолжить использование оболочки в то же время.

Чтобы снова завершить / остановить выполнение:

$ps.Stop()
...