计划的 powershell 替换批处理文件结束得太早或永远不会结束

计划的 powershell 替换批处理文件结束得太早或永远不会结束

首先我将解释一下背景,因为我可能没有以正确的方式进行解释。

我们有一个使用 Oracle Forms 6i(是的,确实很旧)开发的 ERP。它有表单和报告。报告的查询非常复杂,以至于在运行充足的日期时,输出要一小时或更长时间后才可用,因此这些报告是在任务管理器中安排的。任务调用 .bat,.bat 调用 Forms Runtime(.exe),Forms Runtime 运行表单,该表单运行报告。我不会详细解释这一切的原因。重点是这些任务是在 Windows XP 中安排的,我想将它们移动到我们的一台服务器(我正尝试在 Server 2012R2 中使其工作)。

经过一些尝试和研究,我决定从 .bat 脚本转移到 powershell。我已经运行了 ps1,但遇到了一些我不知道如何解决的问题:1- 调用 PS1 脚本的计划任务运行一秒钟,并在表单/报告结束执行后结束。2- 计划任务在表单/报告结束后仍处于“正在运行”状态。

我的 PS1 脚本如下:

param (
    [Parameter(Mandatory=$true)]
    [alias ("form")]
    [string]$formulario = $(throw "-form parametro obligatorio.") 
)

try
{
  BEHAVIOUR 1
    Start-Process -FilePath "C:\orant\BIN\ifrun60.EXE" -WorkingDirectory <SOMEPATH> -ArgumentList "$formulario <oracle_conn_credentials>"
  BEHAVIOUR 2
    Start-Process -FilePath "C:\orant\BIN\ifrun60.EXE" -WorkingDirectory <SOMEPATH> -ArgumentList "$formulario <oracle_conn_credentials>" -Wait


} 
catch
{
    LogWrite "ERROR."
    LogWrite $Error[0]
}

在哪里:

  • $formulario 是输入参数,如 \blah\blah\blah\.fmx
  • LogWrite 是我用来记录执行情况的函数,在本例中不需要,因为该函数已经过全面测试
  • 带有“行为 1”的行是导致计划任务过早结束的行。我想这是因为我使用了 Start-Process,这会启动一个新的独立线程。这让我想到了下一点:
  • 带有“行为 2”的行是使计划任务永不结束的行。它类似于上一行,但添加了“-Wait”,因此 powershell 脚本会等待进程结束。

在这两种情况下,我还发现尽管报告已正确生成,但 Reports Runtime 进程却从未结束。这可能是脚本未结束的原因,但脚本正在运行 Forms Runtime,而 Forms Runtime 是调用 Reports Runtime 的进程。当所有报告都结束时,Forms Runtime 完成,但 Reports Runtime 和 Powershell 进程均未结束。

我希望我已经解释得足够清楚了。如果没有解决方案,任何解决方法都将不胜感激。

编辑:好的,我发现了几件事……首先,我找到了让 powershell 或多或少按照我想要的方式运行的方法。这是使用 实现的Start-Process -PassThru。它将是这样的:

$proceso = Start-Process -FilePath "C:\orant\BIN\ifrun60.EXE" -WorkingDirectory <SOMEPATH> -ArgumentList "$formName <oracle_conn_credentials>" -PassThru
$handle = $proceso.Handle
$proceso.WaitForExit();

阅读该问题的第三个答案后,我得到了这个解决方案: https://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait 好的,现在我的进程结束了,所以计划任务也结束了。但是,子进程仍然会永远运行。Reports Runtime 会打开一个控制台,让您知道报告是否正在运行,并显示已执行报告的日志。通常,退出报告时会忽略此控制台并关闭其窗口(手动操作,单击右上角的 X)。但由于报告是从没有用户界面的计划任务生成的(在任务管理器中,您可以看到它以 session_id = 0 运行,这意味着没有人机界面),所以无法手动关闭此控制台,并且进程会一直保留,直到您将其终止。所以现在的问题变了:有没有办法识别这个子进程?记住:任务计划程序运行 powershell 脚本,ps 运行 oracle 表单,oracle 表单运行 oracle 报告。我需要识别这个 oracle 报告进程。请记住,我计划使用多个表单/报告运行它,并且可以同时使用同一个用户运行 2 个实例。

答案1

好吧,经过一天的努力寻找如何解决这个问题之后,我想我已经找到了运行所有这些并完成而不让孤立进程发生的方法。

$process = Start-Process -FilePath "C:\orant\BIN\ifrun60.EXE" -WorkingDirectory <SOMEPATH> -ArgumentList "$formName <oracle_conn_credentials>" -PassThru
$idProcess = $process.Id
$handle = $process.Handle
A ==> $process.WaitForExit();
B ==> $process | Wait-Process
$child = Get-WmiObject win32_process | where {$_.ParentProcessId -eq $idProcess}
Stop-Process -Id $child.ProcessId
Write-Output "Process finished with exit code "  $process.ExitCode

当我通过做这些事情来学习 Powershell 时,我不确定标记为“A”的行和标记为“B”的行之间到底有什么区别,但两者似乎都有效。

相关内容