【问题标题】:How to run perl script in remote machine from delphi application?如何从delphi应用程序在远程机器上运行perl脚本?
【发布时间】:2009-12-10 00:32:11
【问题描述】:

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

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

【问题讨论】:

  • 只需自动化您手动执行的操作。
  • 您在哪个部分遇到了问题?尤其是连接到远程机器、运行程序或运行 Perl 脚本

标签: delphi ssh


【解决方案1】:

本着将您已经手动完成的工作自动化的精神,您可以使用 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 选项。

【讨论】:

  • 感谢您的回复。我将在我的应用程序中实现这一点,如果我在这方面遇到一些问题,请告诉您。
【解决方案2】:

两步:

  • 使用允许您进行 SSH 的 Delphi 模块/函数
  • 运行 Perl 脚本。

【讨论】:

  • 如果您发布指向此类模块的链接会很棒
【解决方案3】:

您可以查看Capistrano - 它正是为这种自动化而设计的。你应该只需要:

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

【讨论】:

    【解决方案4】:

    如果远程机器运行的是 Windows,PsExec 可能是一个解决方案。

    PsExec 是一个轻量级的 telnet 替换,让你 在其他系统上执行进程

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

    【讨论】:

      【解决方案5】:

      远程计算机是否运行 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
      

      【讨论】:

        【解决方案6】:

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

        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;
        

        【讨论】:

        • Perl 不是一种 Web 脚本语言:“Perl 是一种高级的、通用的、解释型的动态编程语言。” (en.wikipedia.org/wiki/Perl) - 你可以用 Perl 编写 web 应用程序,但不是每个 Perl 脚本都是 web 应用程序 :)
        • 感谢您的所有回复。完成此自动化过程后,我会通知您。非常感谢。如果您有其他解决方案,请与我分享。
        猜你喜欢
        • 1970-01-01
        • 2010-11-24
        • 2012-09-18
        • 2016-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-16
        相关资源
        最近更新 更多