PowerShell:通过调度程序执行时,SendKeys无法正常工作

时间:2020-10-31 16:14:13

标签: powershell scheduler

更新: 问题的背景:我是飞行模拟器爱好者小组的成员。为了一起训练,我们运行一个P3D多人服务器。由于我们在白天和晚上都进行训练,因此我创建了一个powershell脚本,该脚本每天在白天和晚上模式之间变化。手动执行此操作是不可能的,因为这意味着每天都要重新启动P3D两次! P3D进程允许使用给定的飞行文件以多人游戏模式自动启动。唯一的问题是P3D在启动后仍然保持停止状态。要使其停止,必须在键盘上键入字符“ p”。多人服务器是一台Windows 10 PC,可在无人看管的服务器机房环境中运行。安全性与多人服务器的运行无关。

如果手动启动,PowerShell脚本可以正常运行。由于PS脚本需要管理员权限,因此我将通过具有以下内容的cmd脚本启动它:

SET ScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ScriptsDirectory%StartP3DProcess.ps1
PowerShell -WindowStyle Hidden -NoProfile -ExecutionPolicy Unrestricted -Command "& {Start-Process PowerShell -ArgumentList '-WindowStyle Hidden -NoProfile -ExecutionPolicy Unrestricted -File ""%PowerShellScriptPath%""' -Verb RunAs}";

PowerShell脚本编辑3个文件(2x XML,1x flat),然后启动一个进程,并在一段时间延迟后将字符“ p”发送给该进程。

# Setup date and time in flight file
$result = SetDateTimeInFlightFile -eveningOffsetHour $eveningOffsetHour -flightFileSpec $flightFileSpec
    
# Setup required TacPack state
$result = SetTacPackState -tacPackState $controlData[$controlTacPackState] -tacPackFileSpec $tacPackFileSpec

# Update session state description in multiplayer configuration file
$result = SetSessionStatus -mpCfgFileSpec $startCfgSpec

# Start P3D Server
Start-Process -FilePath $P3DFileSpec -ArgumentList $P3DArgs

# Set the started P3D process operational
Start-Sleep -s 60 # wait until process is started up

# Send 'p' to P3D server
$result = SendCommandToProcess -processName $P3DFileExe -command 'p'

由于PS脚本应该每天运行两次(分别在7h00和19h00),所以我设置了一个调度程序任务来运行cmd脚本。通过sheduler启动的PS脚本只需执行一次即可正常工作:字符'p'的发送不起作用。将字符发送到指定进程的函数如下所示($ processId包含正确的进程ID,$ command'p'):

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::AppActivate($processId)
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait($command)

工作环境是一台运行Windows 10 Pro的“服务器”,系统上没有任何普通用户(出于管理目的,只有一个用户帐户“ admin”)。使用集成的日志文件编写,我已经验证了这两种情况(计划程序和手动运行):

  • PS脚本在正确的用户下运行并具有管理员权限
  • $ processId指向正确的进程(通过任务管理器检查了PID)
  • 进程开始与发送“ p”之间的60秒延迟已足够
  • PowerShell不产生错误输出

什么在骗我?感谢您的提示和帮助 汉尼斯

1 个答案:

答案 0 :(得分:1)

如果这样做的目的是简单地恢复已暂停的过程,则可以使用PsSuspendPoshInternals模块,该模块提供了暂停/恢复过程的功能。