如何在Delphi中自动化perl脚本?

时间:2009-11-12 07:12:59

标签: perl delphi

目前,我正在使用delphi应用程序。我需要从delphi应用程序运行perl脚本。为了更清楚,我们手动在unix窗口中执行perl脚本。现在我需要从应用程序自动执行该perl脚本。

我尝试使用ShellExecute:

ShellExecute(Handle, 'open', PChar('C:\loaderperl.bat'), nil, nil, SW_SHOW);

窗口闪烁一秒钟并关闭。我不知道脚本是否被执行。

嗨,谢谢你的所有答案,对不起我迟到的回复。我仍然在努力应对这种自动化。现在我将清楚地解释这个过程,目前我打开putty窗口,连接到远程机器并执行perl脚本。 perl脚本依次调用存储过程并更新表。现在,我想通过单击按钮自动执行上面说明的过程。因此,当我单击一个按钮时,它应该调用一个连接到远程机器的函数,然后执行perl脚本。我清楚你了吗???请帮忙解决这个问题。我需要在delphi中使用此代码

4 个答案:

答案 0 :(得分:1)

(编辑回应下面的评论。)

这有几个步骤:首先,实际运行脚本;第二,检查它是否成功运行(它设法启动一个新进程并且该进程成功。)

第1部分,运行脚本:

要从Delphi应用程序运行脚本,请使用ShellExecuteEx并使用“open”动词(下面标志中的更多详细信息。)如果脚本与Perl关联,则可以执行脚本本身可执行文件,或者使用脚本作为命令行参数运行Perl exe。

This article看起来是使用此API及其简单表兄ShellExecute的良好起点。

ShellExecute[Ex]函数通常希望您的应用程序在之后运行消息循环。您的应用程序不太可能不会,只要用户单击按钮启动此操作后您的应用程序就会处于空闲状态,但如果由于某种原因不能使用,则应传递SEE_MASK_NOASYNC标志。 MSDN有很多信息。

第2部分,检查它是否成功执行并成功完成任务:

要查看脚本是否已执行,您应该获得已启动进程的进程句柄,如果有新进程,请检查该进程的退出代码。如果任务失败,您应该修改脚本以返回非零代码。 (我不熟悉Perl,所以我不能具体告诉你如何,但一般来说它是来自“main”函数或其他第一个/启动函数的返回值。)你可以这样做:

  • SEE_MASK_NOCLOSEPROCESS标记传递给ShellExecuteEx。如果成功启动一个进程,那将填充您传入的结构的hProcess成员(如果没有,请检查GetLastError以找出原因。)如果这就是您需要的全部内容知道(如果它开始,没有关于它是否有效)那么你已经完成了。
  • 可选:使用WaitForSingleObject(YourParamStruct.hProcess, INFINITE)等待进程结束(当然,如果您有一个有效的hProcess)
  • 致电GetExitCodeProcess以查找退出代码。 (检查它是否返回STILL_ACTIVE,如果它仍在运行,请等待并再试一次。)通常,它应该以{{1​​}}退出以表示成功。您应该修改脚本,以便在出现错误时返回非零值。您可以根据需要使代码变得简单或复杂 - 例如,对任何错误返回0,或者根据错误类型分解一些代码。 (避免使用1,因为这是259的值 - 这样做可能会导致Delphi代码进入无限循环,这取决于它的编码方式,认为它仍然在等待获取退出代码,因为Perl脚本当它不存在时仍在运行。)

然后,您的Delphi应用程序可以检查此代码以查看Perl脚本是否有效,如果失败则执行某些操作 - 记录消息,告诉用户等等。

另一件事 - 你说你只是想知道脚本是否被执行以及上面应该提供的那样。鉴于它是一个Perl脚本并在命令行上运行,您可能想要做的另一件事是获取其输出,如果您不返回错误代码则扫描错误,或者记录或显示用户。您可以通过CreateProcesscapturing the output运行此操作。根据你的说法,这对你所追求的东西来说可能有点过分了!

答案 1 :(得分:0)

使用shellexecute使用相关参数(perl解释器+脚本位置+名称)启动rsh或任何你的unix窗口?

答案 2 :(得分:0)

你需要调用外部程序(perl解释器在本地机器上执行,ssh或smth这样在远程机器上执行)。这是调用外部程序并等待它结束的过程(如果你不需要等到它结束,删除WaitForSingleObject或只是像其他人建议的那样调用ShellExecute)。

更新:要查看脚本输出,请尝试使用this article

中的解决方案
function ExecAndWait(const FileName, Params: ShortString; const WinState: Word): boolean; export; 
var 
  StartInfo: TStartupInfo; 
  ProcInfo: TProcessInformation; 
  CmdLine: ShortString; 
begin 
  { Put the name of file between quotes, due to spaces in names of files in system Win9x } 
  CmdLine := '"' + Filename + '" ' + Params; 
  FillChar(StartInfo, SizeOf(StartInfo), #0); 
  with StartInfo do 
  begin 
    cb := SizeOf(SUInfo); 
    dwFlags := STARTF_USESHOWWINDOW; 
    wShowWindow := WinState; 
  end; 
  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false, 
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, 
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);
  { Wait the finish of program } 
  if Result then 
  begin 
    WaitForSingleObject(ProcInfo.hProcess, INFINITE); 
    { Free the Handles } 
    CloseHandle(ProcInfo.hProcess); 
    CloseHandle(ProcInfo.hThread); 
  end; 
end; 

答案 3 :(得分:0)

如果您想要ShellExecute()批处理文件,则需要执行cmd.exe并将脚本作为参数传递,如下所示:

ShellExecute(Handle, 'open', 'cmd.exe', '/C C:\loaderperl.bat', nil, SW_SHOW);

您可以使用输出重定向来捕获文件中的脚本输出。如果您想查看脚本是否已成功执行,您可以(出于测试目的)将pause添加到其末尾。