• Delphi


    毫无疑问,几乎对所有Delphi程序员来说,不用说如何在Windows下如何执行外部程序了!目前Delphi,真的已经很棒了,Delphi有一套和VCL并驾齐驱的图形界面库,叫做"FireMonkey",如果你仅仅想编写Windows程序,而且要调用Windows平台的API,那么肯定VCL是首选,没有其它!但是,如果你想下定决心,跟随Delphi的脚步,进入更广阔的开发天地,那么你也没有第二种选择,只有选择Multi-Device Applications,它支持的平台:

         PC:Windows、OSX、Linux

    Mobile:Android、IOS

    FireMokey跨平台开发英文版PDF格式图书下载 此图书为Embarcadero 2017年度MVP写的图书!

    Multi-Device Applications的控制台程序,支持上述所有平台!!Multi-Device Applications的图形界面库只有一种,就是FireMonkey!!!开发Multi-Device Applications时候,Delphi的RTL库几乎全部都可以使用,大多数在system单元中!!

    更多实际编程,需要自己去摸索了,我今天就是要说如何在Delphi中,执行Windows、OSX、Linux的外部程序?在Windows中通常都是shellExecute,在OSX和linux中,应该是有两种方式执行外部程序:

    方式一:下面代码我在windows下测试完毕,由于最近比较忙,所以OSX和linux没有测试,但是应该没有什么问题,只要把程序前面的条件编译修改成对应操作系统,而且对应操作系统安装了PAServer,在Delphi里面配置好了,选择编译平台,编译运行就可以了!

    program Project1;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    //通过此条件编译指令,分别执行哪个操作系统代码
    {$DEFINE MSWINDOWS}
    
    uses
      System.SysUtils,
    {$IF DEFINED (LINUX) or DEFINED (MACOS)}
      POSIX.Stdlib,
    {$ENDIF}
    {$IFDEF MSWINDOWS}
      Windows,
      ShellApi;
    {$ENDIF}
    
    {
      运行程序方法
      prog:要运行程序全路径名称
    }
    
    procedure RunProg(prog: string);
    begin
    
      // windows条件编译
    {$IFDEF MSWINDOWS}
      ShellExecute(0, 'open', Pchar(prog), nil, nil, SW_SHOWNORMAL);
    {$ENDIF}
      // OSX条件编译
    {$IFDEF MACOS}
      _system(PAnsiChar('open ' + AnsiString(prog)));
    {$ENDIF}
      // linux条件编译
    {$IFDEF LINUX}
      _system(MarshaledAString(UTF8String(prog)));
    {$ENDIF}
    end;
    
    var
      runExe: string; // 要执行程序变量
    
    begin
      try
        // 提示信息
        writeln('请输入要执行程序全路径名称:');
    
        // 读取要执行程序全路径名称
        readln(runExe);
    
        // 运行输入的程序
        RunProg(runExe);
    
      except
        on E: Exception do
          writeln(E.ClassName, ': ', E.Message);
      end;
    
    end.

    方式二:

    program myls;
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      System.SysUtils,
      Posix.Base,
      Posix.Fcntl;
    
    type
      TStreamHandle = pointer;
    
    ///  <summary>
    ///    Man Page: http://man7.org/linux/man-pages/man3/popen.3.html
    ///  </summary>
    function popen(const command: MarshaledAString; const _type: MarshaledAString): TStreamHandle; cdecl; external libc name _PU + 'popen';
    
    ///  <summary>
    ///    Man Page: http://man7.org/linux/man-pages/man3/pclose.3p.html
    ///  </summary>
    function pclose(filehandle: TStreamHandle): int32; cdecl; external libc name _PU + 'pclose';
    
    ///  <summary>
    ///    Man Page: http://man7.org/linux/man-pages/man3/fgets.3p.html
    ///  </summary>
    function fgets(buffer: pointer; size: int32; Stream: TStreamHAndle): pointer; cdecl; external libc name _PU + 'fgets';
    
    ///  <summary>
    ///    Utility function to return a buffer of ASCII-Z data as a string.
    ///  </summary>
    function BufferToString( Buffer: pointer; MaxSize: uint32 ): string;
    var
      cursor: ^uint8;
      EndOfBuffer: nativeuint;
    begin
      Result := '';
      if not assigned(Buffer) then begin
        exit;
      end;
      cursor := Buffer;
      EndOfBuffer := NativeUint(cursor) + MaxSize;
      while (NativeUint(cursor)<EndOfBuffer) and (cursor^<>0) do begin
        Result := Result + chr(cursor^);
        cursor := pointer( succ(NativeUInt(cursor)) );
      end;
    end;
    
    var
      Handle: TStreamHandle;
      Data: array[0..511] of uint8;
    
    begin
      try
        Handle := popen('/bin/ls -lart','r');
        try
          while fgets(@data[0],Sizeof(Data),Handle)<>nil do begin
            Write(BufferToString(@Data[0],sizeof(Data)));
          end;
        finally
          pclose(Handle);
        end;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

    方式二我还没有测试,但是应该是没有问题的,这个国外一个程序员写的代码,在他录制的视频中,就是这段代码,可以在linux下正常执行!方式二和方式一比较,一个不同点是能够获取到程序运行返回的信息!

    完整工程源码:https://download.csdn.net/download/sunylat/10746054

    参考:

    https://www.youtube.com/watch?v=4gDPqq8H-xw

    https://chapmanworld.com/2017/04/06/calling-linux-commands-from-delphi/

  • 相关阅读:
    RedHat 7 安装PostgreSQL 10.5
    百万级数据库优化方案
    所有文章的测试Demo
    PostGreSql安装
    windows server 2016部署服务
    Spring MVC Hello World 404
    Unity攻略
    Unity判断用户联网状态,WiFi/移动网络/无网络
    Unity UGUI Layout自动排版组件用法介绍
    Unity中对系统类进行扩展的方法
  • 原文地址:https://www.cnblogs.com/sunylat/p/9855842.html
Copyright © 2020-2023  润新知