目前,我正在使用delphi应用程序。我需要从delphi应用程序运行perl脚本。为了更清楚,我们手动在unix窗口中执行perl脚本。现在我需要从应用程序自动执行该perl脚本。
我尝试使用ShellExecute:
ShellExecute(Handle, 'open', PChar('C:\loaderperl.bat'), nil, nil, SW_SHOW);
窗口闪烁一秒钟并关闭。我不知道脚本是否被执行。
嗨,谢谢你的所有答案,对不起我迟到的回复。我仍然在努力应对这种自动化。现在我将清楚地解释这个过程,目前我打开putty窗口,连接到远程机器并执行perl脚本。 perl脚本依次调用存储过程并更新表。现在,我想通过单击按钮自动执行上面说明的过程。因此,当我单击一个按钮时,它应该调用一个连接到远程机器的函数,然后执行perl脚本。我清楚你了吗???请帮忙解决这个问题。我需要在delphi中使用此代码
答案 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脚本并在命令行上运行,您可能想要做的另一件事是获取其输出,如果您不返回错误代码则扫描错误,或者记录或显示用户。您可以通过CreateProcess
和capturing 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
添加到其末尾。