如何从delphi应用程序在远程机器上运行perl脚本?

时间:2009-12-09 08:07:42

标签: delphi ssh

您好我正在使用delphi应用程序。我需要从本地机器执行一个perl脚本,该脚本位于delphi应用程序的远程机器中。我需要自动完成这个过程,没有手动交互。现在我将清楚地解释这个过程,目前要运行perl脚本,我只需打开putty窗口,连接到远程机器并执行perl脚本。 perl脚本依次调用存储过程并更新表。

现在我想通过点击按钮自动完成上面说明的过程。因此,当我单击一个按钮时,它应该调用一个连接到远程机器的函数,然后执行perl脚本。我清楚你了吗???请帮忙解决这个问题。我需要尽快在delphi中使用这段代码。

6 个答案:

答案 0 :(得分:3)

本着自动化手动操作的精神,您可以使用Putty附带的Plink实用程序。它接受各种命令行选项,包括用户名,主机,密码和要运行的命令。您也可以在已保存的Putty会话中指定大多数选项。有关详情,请参阅the Putty documentation。您可以使用CreateProcess从程序中运行命令。

var
  cmd: string;
begin
  cmd := 'plink -batch -ssh -pw secret user@host /home/user/command.pl';
  UniqueString(cmd);
  CreateProcess(nil, PChar(cmd), ...);

如果您需要运行的命令有参数,则可能需要引用整个命令。如果要运行多个命令,则应将它们放在一个文件中,然后使用Plink的-m选项。

答案 1 :(得分:2)

两个步骤:

  • 使用允许您SSH的Delphi模块/功能
  • 运行Perl脚本。

答案 2 :(得分:0)

您可以查看Capistrano - 它专为此类自动化而设计。你应该只需要:

  1. download并安装Ruby for Windows
  2. download并安装RubyGems
  3. 创建Capistrano配方以远程调用Perl脚本
  4. 从您的Delphi应用程序中调用Capistrano

答案 3 :(得分:0)

如果远程计算机正在运行Windows,则PsExec可能是一种解决方案。

  

PsExec重量轻   telnet替换,让你   在其他系统上执行进程

有类似WinExe的工具可以在Windows主机上远程执行程序

答案 4 :(得分:0)

远程计算机是否运行Windows?如果是这样,您可以随时从Delphi中调用“psexec”。或者您可以使用WMI远程执行进程(假设远程主机正在运行某个版本的Windows)

以下是Delphi中的完整示例taken from here。您需要WbemScripting_TLB单元,您可以通过使用Delphi中的“组件|导入组件|导入类型库”菜单选项安装类型库%windir%\ System32 \ wbem \ wbemdisp.tlb 来创建该单元2007。

unit Unit1;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ComCtrls;

type
  TForm1 = class(TForm)
    btnExecute: TButton;
    edtProgramToExecute: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    edtRemoteMachine: TEdit;
    edtUser: TEdit;
    edtPassword: TEdit;
    procedure btnExecuteClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses WbemScripting_TLB;

function remoteExecute(programName: string; machine: string = ''; user: string = '';
  password: string = ''): string;
var
  SWbemLocator1: TSWbemLocator;
  Service: ISWbemServices;
  InParam,
    OutParam, SObject: ISWbemObject;
  Method: ISWbemMethod;
  SProp1
    , SProp2, MyProperty
    : ISWbemProperty;
  s, methodName: string;
  PropValue: OleVariant;
begin
  methodName := 'Create';
  //  CoInitialize(nil);
  SWbemLocator1 := TSWbemLocator.Create(nil);
  if machine = '' then
    machine := '.';
  Service := SWbemLocator1.ConnectServer(machine, 'root\CIMV2', user, password, '', '',
    0, nil);
  Service.Security_.Set_ImpersonationLevel(wbemImpersonationLevelImpersonate);
  SObject := Service.Get('Win32_Process', 0, nil);

  Method := SOBject.Methods_.Item(methodName, 0);
  InParam := Method.InParameters.SpawnInstance_(0);

  MyProperty := InParam.Properties_.Add('CommandLine', wbemCimtypeString, False, 0);
  PropValue := programName;
  MyProperty.Set_Value(PropValue);

  MyProperty := InParam.Properties_.Add('CurrentDirectory', wbemCimtypeString, False, 0);
  PropValue := Null;
  MyProperty.Set_Value(PropValue);

  MyProperty := InParam.Properties_.Add('ProcessStartupInformation', wbemCimtypeObject,
    False, 0);
  PropValue := Null;
  MyProperty.Set_Value(PropValue);

  OutParam := SObject.ExecMethod_(methodName, InParam, 0, nil);
  //  OutParam:= SObject.ExecMethod_(methodName, nil, 0, nil);
  SProp1 := outParam.Properties_.Item('ReturnValue', 0);
  SProp2 := outParam.Properties_.Item('ProcessId', 0);
  case SProp1.Get_Value of
    0: s := 'Successful completion.';
    2: s := 'Access denied.';
    3: s := 'Insufficient privilege.';
    8: s := 'Unknown failure.';
    9: s := 'Path not found.';
    21: s := 'Invalid parameter.';
  else
    s := 'Unknown reply code!';
  end;
  SWbemLocator1.Free;
  service := nil;
  SObject := nil;
  OutParam := nil;
  SProp1 := nil;
  result := s + '(PID=' + inttostr(SProp2.Get_Value) + ')';
  //  CoUninitialize;
end;

procedure TForm1.btnExecuteClick(Sender: TObject);
begin
  statusbar1.simpletext := remoteExecute(edit1.text, edit2.text, edit3.text, edit4.text);
end;

end.

您也可以在VBScript中执行此操作:

Here's a VBScript snippet that demonstrates how this would work.
' This script provides a function for executing a command on a remote computer
' This uses WMI and requires that you have administrative righs on the remote machine
'

Dim strComputer, strCommandLineToRun

'change the period to an IP Address or computer name
strComputer = "."   'example: strComputer = "192.168.1.105"

'this is the path to the file on the computer whose name/IP address is stored in the strComputer variable
strCommandLineToRun = "c:\windows\system32\calc.exe"


' This calls the function to run the process on a remote computer
RemoteExecute strComputer,"","",strCommandLineToRun


Function RemoteExecute(strServer, strUser, strPassword, CmdLine)
    Const Impersonate = 3

    RemoteExecute = -1

    Set Locator = CreateObject("WbemScripting.SWbemLocator")
    Set Service = Locator.ConnectServer(strServer, "root\cimv2", strUser, strPassword)

    Service.Security_.ImpersonationLevel = Impersonate 
    Set Process = Service.Get("Win32_Process")

    result = Process.Create(CmdLine, , , ProcessId)

    If (result <> 0) Then
        WScript.Echo "Creating Remote Process Failed: " & result
        Wscript.Quit
    End If

    RemoteExecute = ProcessId
End Function

答案 5 :(得分:-1)

我不知道Perl。但如果我理解正确,它是一种类似于php的网络脚本语言。我也面临类似的情况,但用PHP。所以我最终在我的Delphi应用程序中使用Indy调用php脚本。我不知道是否可以为perl应用相同类型的逻辑。以下是逻辑的一些片段。

var
  IdHTTP: TIdHTTP;
  IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocketOpenSSL;
begin
  try
    IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
    IdHTTP := TIdHTTP.create(nil);
    idhttp.handleredirects := True;
    with IdSSLIOHandlerSocket1 do begin
      SSLOptions.Method := sslvSSLv3;
      SSLOptions.Mode :=  sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 2;
    end;
    with IdHTTP do begin
      IOHandler := IdSSLIOHandlerSocket1;
      ProxyParams.BasicAuthentication := False;
      Request.ContentType := 'text/html';
      request.connection := 'keep-alive';
      Request.Accept := 'text/html, */*';
    end;
    result := idhttp.get('http://www.mysite.com/myscript.php');
  finally
    IdHTTP.free;
    IdSSLIOHandlerSocket1.free;
  end;
end;