如何在2个Delphi应用程序之间传递字符串[重复]

Posted

技术标签:

【中文标题】如何在2个Delphi应用程序之间传递字符串[重复]【英文标题】:How to pass string between 2 Delphi applications [duplicate] 【发布时间】:2012-11-20 01:41:48 【问题描述】:

可能重复:Looking for an alternative to windows messages used in inter-process communicationInter-process communication

我有一个正在运行的 Delphi 7 应用程序,它公开了一个类型库。 TLB 公开的函数之一是 ProcessFile(fileName: string)。当调用该函数时,我希望正在运行的 Windows 服务(也是 Delphi 7 应用程序)得到通知该事件已被调用以及文件名是什么。

任何关于如何做到这一点的想法将不胜感激。我已经尝试通过使用注册表和 txt 文件更改回调来做到这一点,但无论哪种方式,我偶尔都会丢失要处理的文件,因为此 ProcessFile 方法可以每秒调用多次。

谢谢!

【问题讨论】:

Ken,我认为他正在寻找 TLB 的 ProcessFile 方法的挂钩。标题暗示了别的东西。 将字符串发送到命名管道 @alzaimar 无论他在寻找什么,IPC 都是唯一的答案 检查由 Iztok Kacin 开发的开源、即用型应用间通信库,名为 Cronis IPC。 IIRC,它基于命名管道 【参考方案1】:

管道非常适合这项工作。您可以在服务端实现一个管道读取器线程,并在客户端的 ProcessFile 方法中通过管道发送相应的字符串数据。

一个快速、简单的无错误检查管道使用示例:

管道服务器

var
  Form1: TForm1;
  t: TReadpipe;

  h: THandle;
  msg: string;

const BufSize=512;

implementation

$R *.dfm

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  chandle: THandle;
begin
  t.Terminate;

  chandle := CreateFile('\\.\pipe\myNamedPipe', GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, 0);
  CloseHandle(chandle);

  t.WaitFor;
  t.Free;
  CloseHandle(h);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  t := Treadpipe.Create(false);
end;

 TReadPipe 

procedure TReadPipe.Execute;
var
  buf: array [0 .. BufSize-1] of char;
  read: cardinal;
begin
  while not Terminated do
  begin
    h := CreateNamedPipe('\\.\pipe\myNamedPipe', PIPE_ACCESS_DUPLEX,
      PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,
      PIPE_UNLIMITED_INSTANCES, BufSize, BufSize, 0, nil);

    ConnectNamedPipe(h, nil);

    if Terminated then
      break;

    msg := '';

    repeat
      FillChar(buf, BufSize, #0);
      ReadFile(h, buf[0], BufSize, read, nil);

      msg := msg + Copy(buf, 0, read);
    until GetLastError <> ERROR_MORE_DATA;

    if msg <> '' then
      Synchronize(
        procedure
        begin
          form1.Memo1.Lines.Add(msg)
        end);
  end;

  DisconnectNamedPipe(h);
end;

管道客户端

var
  Form1: TForm1;
  i: Integer = 0;
  pipe: THandle;

const
  BufSize = 512;

implementation

$R *.dfm

procedure TForm1.Button1Click(Sender: TObject);
var
  buf: array [0 .. BufSize - 1] of char;
  written: Cardinal;
  str: pchar;
begin
  pipe := CreateFile('\\.\pipe\myNamedPipe', GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, 0);

  if pipe = INVALID_HANDLE_VALUE then
    Halt;

  inc(i);
  str := pchar('someStr' + inttostr(i));
  fillchar(buf, BufSize, #0);
  move(str[0], buf[0], Length(str) * Sizeof(char));
  WriteFile(pipe, buf[0], Length(str) * Sizeof(char), written, nil);

  CloseHandle(pipe);
end;

还要记住管道作为 FIFO 工作。

【讨论】:

您不需要固定管道吗? 这是一个简单的管道使用示例。用户确实应该采取安全措施。 嗨@The_aLiEn 我看你的建议,可以按照它,但在你的服务器代码 sn-p 你调用 CtreateNamedPipe('\\.\pipe\myNamedPipe', PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE 或 PIPE_READMODE_MESSAGE 或 PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,BufSize,BufSize,0,无);以及 ConnectNamedPipe(h, nil);这些是哪些库或 Delphi 单元的一部分?我的猜测是它们是第 3 方的东西(希望是开源的)?如果是这样,您能否提供一个链接到我可以在哪里获得它们或提供这些程序的代码?谢谢!大卫 它们不是来自第 3 方单位,它们是纯 WinAPI ;) 而且文档是完全免费的,因为它是 Windows SDK,显然。您无法找到这些 API 的任何洞察代码,因为 Windows 不是开源软件,但在 SDK 中有很多东西解释了如何使用、如何不使用以及对这些 API 和参数的解释。 Here 是相应的文档。

以上是关于如何在2个Delphi应用程序之间传递字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在DELPHI中窗体之间 如何传递数据?

在 Delphi 2007 DLL 和 XE6 EXE 之间传递 PChar

Delphi;传递const字符串与传递var字符串的性能

在 2 个 php 脚本之间传递 $_SESSION 中的对象 [重复]

Delphi - 获取非本地时区的 TTimeZone 并在时区之间转换 [重复]

砍字符串(用户传递的参数)[重复]