我有一个Delphi 7 App运行,它公开了一个类型库.TLB公开的函数之一是ProcessFile(fileName:string).当调用该函数时,我希望运行一个Windows服务(也是一个Delphi 7应用程序)来通知该事件被调用以及文件名是什么.
任何关于如何做到这一点的想法将不胜感激.我已经尝试通过使用注册表和txt文件更改回调来执行此操作,但无论哪种方式我偶尔会丢失要处理的文件,因为此ProcessFile方法可以每秒调用多次.
谢谢!
管道非常适合这项工作.您可以在服务端实现管道读取器线程,并在客户端的ProcessFile方法中通过管道发送相应的字符串数据.
一个快速,简单的无错误检查管道使用示例:
PipeServer
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;
Run Code Online (Sandbox Code Playgroud)
PipeClient
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;
Run Code Online (Sandbox Code Playgroud)
还记得管道工作为FIFO.