What is the best and easiest way to send a string from one instance of my program to another instance of my program? The receiving program has to execute a procedure, using the received string as a parameter.
从我的程序的一个实例发送字符串到我的程序的另一个实例的最佳和最简单的方法是什么?接收程序必须使用接收的字符串作为参数来执行过程。
I started reading about DDE but I got confused. What other options do I have, and what is the easiest way to implement this?
我开始阅读DDE,但我感到困惑。我还有什么其他选择,实现这个的最简单方法是什么?
8 个解决方案
#1
Use named Pipes, but I would recommend Russell Libby's named Pipe components. There is a TPipeClient and TPipeServer component.
使用命名管道,但我会推荐Russell Libby的命名管道组件。有一个TPipeClient和TPipeServer组件。
As of (2013-10-04) Francoise Piette and arno.garrels@gmx.de updated this source code to compile with Delphi 7 to XE5 (earlier versions may compile however untested) and put it here: http://www.overbyte.be/frame_index.html?redirTo=/blog_source_code.html
截至(2013-10-04),Francoise Piette和arno.garrels@gmx.de更新了这个源代码,用Delphi 7编译成XE5(早期版本可以编译但未经测试)并将其放在此处:http://www.overbyte .BE / frame_index.html?redirTo = / blog_source_code.html
These 2 components make using named pipes incredibly easy, and named pipes are great for inter-process communication (IPC).
这两个组件使命名管道非常容易使用,命名管道非常适合进程间通信(IPC)。
His website is here. Look for "Pipes.zip". The description from the source is: // Description : Set of client and server named pipe components for Delphi, as // well a console pipe redirection component.
他的网站在这里。寻找“Pipes.zip”。源代码的描述是://描述:Delphi的客户端和服务器命名管道组件集合,以及//控制台管道重定向组件。
Also, Russell helped me out on Experts-Exchange with using an older version of this component to work in a console app to send/receive messages over named pipes. This may help as a guide in getting you up and running with using his components. Please note, that in a VCL app or service, you don't need to write your own message loop as I did in this console app.
此外,Russell帮助我在Experts-Exchange上使用该组件的旧版本在控制台应用程序中工作,以通过命名管道发送/接收消息。这可能有助于您使用他的组件启动和运行。请注意,在VCL应用程序或服务中,您不需要像在此控制台应用程序中那样编写自己的消息循环。
program CmdClient;
{$APPTYPE CONSOLE}
uses
Windows, Messages, SysUtils, Pipes;
type
TPipeEventHandler = class(TObject)
public
procedure OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
end;
procedure TPipeEventHandler.OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
begin
WriteLn('On Pipe Sent has executed!');
end;
var
lpMsg: TMsg;
WideChars: Array [0..255] of WideChar;
myString: String;
iLength: Integer;
pcHandler: TPipeClient;
peHandler: TPipeEventHandler;
begin
// Create message queue for application
PeekMessage(lpMsg, 0, WM_USER, WM_USER, PM_NOREMOVE);
// Create client pipe handler
pcHandler:=TPipeClient.CreateUnowned;
// Resource protection
try
// Create event handler
peHandler:=TPipeEventHandler.Create;
// Resource protection
try
// Setup clien pipe
pcHandler.PipeName:='myNamedPipe';
pcHandler.ServerName:='.';
pcHandler.OnPipeSent:=peHandler.OnPipeSent;
// Resource protection
try
// Connect
if pcHandler.Connect(5000) then
begin
// Dispatch messages for pipe client
while PeekMessage(lpMsg, 0, 0, 0, PM_REMOVE) do DispatchMessage(lpMsg);
// Setup for send
myString:='the message I am sending';
iLength:=Length(myString) + 1;
StringToWideChar(myString, wideChars, iLength);
// Send pipe message
if pcHandler.Write(wideChars, iLength * 2) then
begin
// Flush the pipe buffers
pcHandler.FlushPipeBuffers;
// Get the message
if GetMessage(lpMsg, pcHandler.WindowHandle, 0, 0) then DispatchMessage(lpMsg);
end;
end
else
// Failed to connect
WriteLn('Failed to connect to ', pcHandler.PipeName);
finally
// Show complete
Write('Complete...');
// Delay
ReadLn;
end;
finally
// Disconnect event handler
pcHandler.OnPipeSent:=nil;
// Free event handler
peHandler.Free;
end;
finally
// Free pipe client
pcHandler.Free;
end;
end.
#2
I use named pipes for this, it was the easiest one I found. I'll post the code when I get home from work.
我为此使用命名管道,这是我发现的最简单的管道。我下班回家时会发布代码。
Here's an article on how to use it in delphi: http://www.delphi3000.com/articles/article_2918.asp?SK=
这是一篇关于如何在德尔福中使用它的文章:http://www.delphi3000.com/articles/article_2918.asp?SC =
There's a million solutions to this by the way, all of them seem to be annoying. Pipes is the best one I've found so far.
顺便提一下,有一百万个解决方案,所有这些解决方案似乎很烦人。管道是迄今为止我发现的最好的管道。
Here's the code, sorry about the delay. You should check out the Pipe library mentioned by Mick too. The thing I've done here was a pretty quick experiment. Please note that it was made in Delphi 2009.
这是代码,对延迟感到抱歉。您应该查看Mick提到的管道库。我在这里做的事情是一个非常快速的实验。请注意,它是在Delphi 2009中制作的。
unit PetriW.Pipes;
interface
uses
Windows,
Classes,
Forms,
SyncObjs,
SysUtils
;
type
TPBPipeServerReceivedDataEvent = procedure(AData: string) of object;
TPBPipeServer = class
private
type
TPBPipeServerThread = class(TThread)
private
FServer: TPBPipeServer;
protected
public
procedure Execute; override;
property Server: TPBPipeServer read FServer;
end;
private
FOnReceivedData: TPBPipeServerReceivedDataEvent;
FPath: string;
FPipeHandle: THandle;
FShutdownEvent: TEvent;
FThread: TPBPipeServerThread;
protected
public
constructor Create(APath: string);
destructor Destroy; override;
property Path: string read FPath;
property OnReceivedData: TPBPipeServerReceivedDataEvent read FOnReceivedData write FOnReceivedData;
end;
TPBPipeClient = class
private
FPath: string;
protected
public
constructor Create(APath: string);
destructor Destroy; override;
property Path: string read FPath;
procedure SendData(AData: string); overload;
class procedure SendData(APath, AData: string); overload;
end;
implementation
const
PIPE_MESSAGE_SIZE = $20000;
{ TPipeServer }
constructor TPBPipeServer.Create(APath: string);
begin
FPath := APath;
FShutdownEvent := TEvent.Create(nil, True, False, '');
FPipeHandle := CreateNamedPipe(
PWideChar(FPath),
PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
SizeOf(Integer),
PIPE_MESSAGE_SIZE,
NMPWAIT_USE_DEFAULT_WAIT,
nil
);
if FPipeHandle = INVALID_HANDLE_VALUE then
RaiseLastOSError;
FThread := TPBPipeServerThread.Create(true);
FThread.FreeOnTerminate := false;
FThread.FServer := self;
FThread.Resume;
end;
destructor TPBPipeServer.Destroy;
begin
FShutdownEvent.SetEvent;
FreeAndNil(FThread);
CloseHandle(FPipeHandle);
FreeAndNil(FShutdownEvent);
inherited;
end;
{ TPipeServer.TPipeServerThread }
procedure TPBPipeServer.TPBPipeServerThread.Execute;
var
ConnectEvent, ReadEvent: TEvent;
events: THandleObjectArray;
opconnect, opread: TOverlapped;
Signal: THandleObject;
buffer: TBytes;
bytesRead, error: Cardinal;
begin
inherited;
//SetThreadName('TPBPipeServer.TPBPipeServerThread');
ConnectEvent := TEvent.Create(nil, False, False, '');
try
setlength(events, 2);
events[1] := Server.FShutdownEvent;
FillMemory(@opconnect, SizeOf(TOverlapped), 0);
opconnect.hEvent := ConnectEvent.Handle;
while not Terminated do
begin
ConnectNamedPipe(Server.FPipeHandle, @opconnect);
events[0] := ConnectEvent;
THandleObject.WaitForMultiple(events, INFINITE, False, Signal);
if Signal = ConnectEvent then
try
// successful connect!
ReadEvent := TEvent.Create(nil, True, False, '');
try
FillMemory(@opread, SizeOf(TOverlapped), 0);
opread.hEvent := ReadEvent.Handle;
setlength(buffer, PIPE_MESSAGE_SIZE);
if not ReadFile(Server.FPipeHandle, buffer[0], PIPE_MESSAGE_SIZE, bytesRead, @opread) then
begin
error := GetLastError;
if error = ERROR_IO_PENDING then
begin
if not GetOverlappedResult(Server.FPipeHandle, opread, bytesRead, True) then
error := GetLastError
else
error := ERROR_SUCCESS;
end;
if error = ERROR_BROKEN_PIPE then
// ignore, but discard data
bytesRead := 0
else if error = ERROR_SUCCESS then
// ignore
else
RaiseLastOSError(error);
end;
if (bytesRead > 0) and Assigned(Server.OnReceivedData) then
Server.OnReceivedData(TEncoding.Unicode.GetString(buffer, 0, bytesRead));
// Set result to 1
PInteger(@buffer[0])^ := 1;
if not WriteFile(Server.FPipeHandle, buffer[0], SizeOf(Integer), bytesRead, @opread) then
begin
error := GetLastError;
if error = ERROR_IO_PENDING then
begin
if not GetOverlappedResult(Server.FPipeHandle, opread, bytesRead, True) then
error := GetLastError
else
error := ERROR_SUCCESS;
end;
if error = ERROR_BROKEN_PIPE then
// ignore
else if error = ERROR_SUCCESS then
// ignore
else
RaiseLastOSError(error);
end;
finally
FreeAndNil(ReadEvent);
end;
finally
DisconnectNamedPipe(Server.FPipeHandle);
end
else if Signal = Server.FShutdownEvent then
begin
// server is shutting down!
Terminate;
end;
end;
finally
FreeAndNil(ConnectEvent);
end;
end;
{ TPBPipeClient }
constructor TPBPipeClient.Create(APath: string);
begin
FPath := APath;
end;
destructor TPBPipeClient.Destroy;
begin
inherited;
end;
class procedure TPBPipeClient.SendData(APath, AData: string);
var
bytesRead: Cardinal;
success: Integer;
begin
if not CallNamedPipe(PWideChar(APath), PWideChar(AData), length(AData) * SizeOf(Char), @success, SizeOf(Integer), bytesRead, NMPWAIT_USE_DEFAULT_WAIT) then
RaiseLastOSError;
end;
procedure TPBPipeClient.SendData(AData: string);
var
bytesRead: Cardinal;
success: boolean;
begin
if not CallNamedPipe(PWideChar(FPath), PWideChar(AData), length(AData) * SizeOf(Char), @success, SizeOf(Integer), bytesRead, NMPWAIT_USE_DEFAULT_WAIT) then
RaiseLastOSError;
end;
end.
Here's how I send something:
这是我发送的东西:
TPBPipeClient.SendData('\\.\pipe\pipe server E5DE3B9655BE4885ABD5C90196EF0EC5', 'HELLO');
Here's how I read something:
这是我读的东西:
procedure TfoMain.FormCreate(Sender: TObject);
begin
PipeServer := TPBPipeServer.Create('\\.\pipe\pipe server E5DE3B9655BE4885ABD5C90196EF0EC5');
PipeServer.OnReceivedData := PipeDataReceived;
end;
procedure TfoMain.PipeDataReceived(AData: string);
begin
if AData = 'HELLO' then
// do something, but note that you're not in the main thread, you're in the pipe server thread
end;
#3
For very short messages, WM_COPYDATA is probably the easiest. Other than that, there is PetriW's suggestion of named pipes, or sockets.
对于非常短的消息,WM_COPYDATA可能是最简单的。除此之外,PetriW建议使用命名管道或插座。
#5
Get a look at ZeroMQ. If you got the thoughts behind the architecture it may dramatically change the way you think. As far as I had a walkthrough they have libraries for many programming languages, including Delphi. But I had not a chance to try it.
看看ZeroMQ。如果你了解了架构背后的想法,它可能会大大改变你的思维方式。至于我有一个演练,他们有许多编程语言的库,包括Delphi。但我没有机会尝试它。
Here is Delphi port of the library.
这是图书馆的Delphi端口。
#6
Check Cromis.IPC, internally it uses named pipes, but provides a much easier API, and it's compatible with recent Delphi versions.
检查Cromis.IPC,在内部使用命名管道,但提供了更简单的API,并且它与最近的Delphi版本兼容。
#7
I suggest TMappedFile - more efficient than named pipes.
我建议TMappedFile - 比命名管道更有效。
#8
I use InterAppComm and it's very good.
我使用InterAppComm,非常好。
It sends data between two or more applications. It can send strings, integers and other data types.
它在两个或多个应用程序之间发送数据。它可以发送字符串,整数和其他数据类型。
#1
Use named Pipes, but I would recommend Russell Libby's named Pipe components. There is a TPipeClient and TPipeServer component.
使用命名管道,但我会推荐Russell Libby的命名管道组件。有一个TPipeClient和TPipeServer组件。
As of (2013-10-04) Francoise Piette and arno.garrels@gmx.de updated this source code to compile with Delphi 7 to XE5 (earlier versions may compile however untested) and put it here: http://www.overbyte.be/frame_index.html?redirTo=/blog_source_code.html
截至(2013-10-04),Francoise Piette和arno.garrels@gmx.de更新了这个源代码,用Delphi 7编译成XE5(早期版本可以编译但未经测试)并将其放在此处:http://www.overbyte .BE / frame_index.html?redirTo = / blog_source_code.html
These 2 components make using named pipes incredibly easy, and named pipes are great for inter-process communication (IPC).
这两个组件使命名管道非常容易使用,命名管道非常适合进程间通信(IPC)。
His website is here. Look for "Pipes.zip". The description from the source is: // Description : Set of client and server named pipe components for Delphi, as // well a console pipe redirection component.
他的网站在这里。寻找“Pipes.zip”。源代码的描述是://描述:Delphi的客户端和服务器命名管道组件集合,以及//控制台管道重定向组件。
Also, Russell helped me out on Experts-Exchange with using an older version of this component to work in a console app to send/receive messages over named pipes. This may help as a guide in getting you up and running with using his components. Please note, that in a VCL app or service, you don't need to write your own message loop as I did in this console app.
此外,Russell帮助我在Experts-Exchange上使用该组件的旧版本在控制台应用程序中工作,以通过命名管道发送/接收消息。这可能有助于您使用他的组件启动和运行。请注意,在VCL应用程序或服务中,您不需要像在此控制台应用程序中那样编写自己的消息循环。
program CmdClient;
{$APPTYPE CONSOLE}
uses
Windows, Messages, SysUtils, Pipes;
type
TPipeEventHandler = class(TObject)
public
procedure OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
end;
procedure TPipeEventHandler.OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
begin
WriteLn('On Pipe Sent has executed!');
end;
var
lpMsg: TMsg;
WideChars: Array [0..255] of WideChar;
myString: String;
iLength: Integer;
pcHandler: TPipeClient;
peHandler: TPipeEventHandler;
begin
// Create message queue for application
PeekMessage(lpMsg, 0, WM_USER, WM_USER, PM_NOREMOVE);
// Create client pipe handler
pcHandler:=TPipeClient.CreateUnowned;
// Resource protection
try
// Create event handler
peHandler:=TPipeEventHandler.Create;
// Resource protection
try
// Setup clien pipe
pcHandler.PipeName:='myNamedPipe';
pcHandler.ServerName:='.';
pcHandler.OnPipeSent:=peHandler.OnPipeSent;
// Resource protection
try
// Connect
if pcHandler.Connect(5000) then
begin
// Dispatch messages for pipe client
while PeekMessage(lpMsg, 0, 0, 0, PM_REMOVE) do DispatchMessage(lpMsg);
// Setup for send
myString:='the message I am sending';
iLength:=Length(myString) + 1;
StringToWideChar(myString, wideChars, iLength);
// Send pipe message
if pcHandler.Write(wideChars, iLength * 2) then
begin
// Flush the pipe buffers
pcHandler.FlushPipeBuffers;
// Get the message
if GetMessage(lpMsg, pcHandler.WindowHandle, 0, 0) then DispatchMessage(lpMsg);
end;
end
else
// Failed to connect
WriteLn('Failed to connect to ', pcHandler.PipeName);
finally
// Show complete
Write('Complete...');
// Delay
ReadLn;
end;
finally
// Disconnect event handler
pcHandler.OnPipeSent:=nil;
// Free event handler
peHandler.Free;
end;
finally
// Free pipe client
pcHandler.Free;
end;
end.
#2
I use named pipes for this, it was the easiest one I found. I'll post the code when I get home from work.
我为此使用命名管道,这是我发现的最简单的管道。我下班回家时会发布代码。
Here's an article on how to use it in delphi: http://www.delphi3000.com/articles/article_2918.asp?SK=
这是一篇关于如何在德尔福中使用它的文章:http://www.delphi3000.com/articles/article_2918.asp?SC =
There's a million solutions to this by the way, all of them seem to be annoying. Pipes is the best one I've found so far.
顺便提一下,有一百万个解决方案,所有这些解决方案似乎很烦人。管道是迄今为止我发现的最好的管道。
Here's the code, sorry about the delay. You should check out the Pipe library mentioned by Mick too. The thing I've done here was a pretty quick experiment. Please note that it was made in Delphi 2009.
这是代码,对延迟感到抱歉。您应该查看Mick提到的管道库。我在这里做的事情是一个非常快速的实验。请注意,它是在Delphi 2009中制作的。
unit PetriW.Pipes;
interface
uses
Windows,
Classes,
Forms,
SyncObjs,
SysUtils
;
type
TPBPipeServerReceivedDataEvent = procedure(AData: string) of object;
TPBPipeServer = class
private
type
TPBPipeServerThread = class(TThread)
private
FServer: TPBPipeServer;
protected
public
procedure Execute; override;
property Server: TPBPipeServer read FServer;
end;
private
FOnReceivedData: TPBPipeServerReceivedDataEvent;
FPath: string;
FPipeHandle: THandle;
FShutdownEvent: TEvent;
FThread: TPBPipeServerThread;
protected
public
constructor Create(APath: string);
destructor Destroy; override;
property Path: string read FPath;
property OnReceivedData: TPBPipeServerReceivedDataEvent read FOnReceivedData write FOnReceivedData;
end;
TPBPipeClient = class
private
FPath: string;
protected
public
constructor Create(APath: string);
destructor Destroy; override;
property Path: string read FPath;
procedure SendData(AData: string); overload;
class procedure SendData(APath, AData: string); overload;
end;
implementation
const
PIPE_MESSAGE_SIZE = $20000;
{ TPipeServer }
constructor TPBPipeServer.Create(APath: string);
begin
FPath := APath;
FShutdownEvent := TEvent.Create(nil, True, False, '');
FPipeHandle := CreateNamedPipe(
PWideChar(FPath),
PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
SizeOf(Integer),
PIPE_MESSAGE_SIZE,
NMPWAIT_USE_DEFAULT_WAIT,
nil
);
if FPipeHandle = INVALID_HANDLE_VALUE then
RaiseLastOSError;
FThread := TPBPipeServerThread.Create(true);
FThread.FreeOnTerminate := false;
FThread.FServer := self;
FThread.Resume;
end;
destructor TPBPipeServer.Destroy;
begin
FShutdownEvent.SetEvent;
FreeAndNil(FThread);
CloseHandle(FPipeHandle);
FreeAndNil(FShutdownEvent);
inherited;
end;
{ TPipeServer.TPipeServerThread }
procedure TPBPipeServer.TPBPipeServerThread.Execute;
var
ConnectEvent, ReadEvent: TEvent;
events: THandleObjectArray;
opconnect, opread: TOverlapped;
Signal: THandleObject;
buffer: TBytes;
bytesRead, error: Cardinal;
begin
inherited;
//SetThreadName('TPBPipeServer.TPBPipeServerThread');
ConnectEvent := TEvent.Create(nil, False, False, '');
try
setlength(events, 2);
events[1] := Server.FShutdownEvent;
FillMemory(@opconnect, SizeOf(TOverlapped), 0);
opconnect.hEvent := ConnectEvent.Handle;
while not Terminated do
begin
ConnectNamedPipe(Server.FPipeHandle, @opconnect);
events[0] := ConnectEvent;
THandleObject.WaitForMultiple(events, INFINITE, False, Signal);
if Signal = ConnectEvent then
try
// successful connect!
ReadEvent := TEvent.Create(nil, True, False, '');
try
FillMemory(@opread, SizeOf(TOverlapped), 0);
opread.hEvent := ReadEvent.Handle;
setlength(buffer, PIPE_MESSAGE_SIZE);
if not ReadFile(Server.FPipeHandle, buffer[0], PIPE_MESSAGE_SIZE, bytesRead, @opread) then
begin
error := GetLastError;
if error = ERROR_IO_PENDING then
begin
if not GetOverlappedResult(Server.FPipeHandle, opread, bytesRead, True) then
error := GetLastError
else
error := ERROR_SUCCESS;
end;
if error = ERROR_BROKEN_PIPE then
// ignore, but discard data
bytesRead := 0
else if error = ERROR_SUCCESS then
// ignore
else
RaiseLastOSError(error);
end;
if (bytesRead > 0) and Assigned(Server.OnReceivedData) then
Server.OnReceivedData(TEncoding.Unicode.GetString(buffer, 0, bytesRead));
// Set result to 1
PInteger(@buffer[0])^ := 1;
if not WriteFile(Server.FPipeHandle, buffer[0], SizeOf(Integer), bytesRead, @opread) then
begin
error := GetLastError;
if error = ERROR_IO_PENDING then
begin
if not GetOverlappedResult(Server.FPipeHandle, opread, bytesRead, True) then
error := GetLastError
else
error := ERROR_SUCCESS;
end;
if error = ERROR_BROKEN_PIPE then
// ignore
else if error = ERROR_SUCCESS then
// ignore
else
RaiseLastOSError(error);
end;
finally
FreeAndNil(ReadEvent);
end;
finally
DisconnectNamedPipe(Server.FPipeHandle);
end
else if Signal = Server.FShutdownEvent then
begin
// server is shutting down!
Terminate;
end;
end;
finally
FreeAndNil(ConnectEvent);
end;
end;
{ TPBPipeClient }
constructor TPBPipeClient.Create(APath: string);
begin
FPath := APath;
end;
destructor TPBPipeClient.Destroy;
begin
inherited;
end;
class procedure TPBPipeClient.SendData(APath, AData: string);
var
bytesRead: Cardinal;
success: Integer;
begin
if not CallNamedPipe(PWideChar(APath), PWideChar(AData), length(AData) * SizeOf(Char), @success, SizeOf(Integer), bytesRead, NMPWAIT_USE_DEFAULT_WAIT) then
RaiseLastOSError;
end;
procedure TPBPipeClient.SendData(AData: string);
var
bytesRead: Cardinal;
success: boolean;
begin
if not CallNamedPipe(PWideChar(FPath), PWideChar(AData), length(AData) * SizeOf(Char), @success, SizeOf(Integer), bytesRead, NMPWAIT_USE_DEFAULT_WAIT) then
RaiseLastOSError;
end;
end.
Here's how I send something:
这是我发送的东西:
TPBPipeClient.SendData('\\.\pipe\pipe server E5DE3B9655BE4885ABD5C90196EF0EC5', 'HELLO');
Here's how I read something:
这是我读的东西:
procedure TfoMain.FormCreate(Sender: TObject);
begin
PipeServer := TPBPipeServer.Create('\\.\pipe\pipe server E5DE3B9655BE4885ABD5C90196EF0EC5');
PipeServer.OnReceivedData := PipeDataReceived;
end;
procedure TfoMain.PipeDataReceived(AData: string);
begin
if AData = 'HELLO' then
// do something, but note that you're not in the main thread, you're in the pipe server thread
end;
#3
For very short messages, WM_COPYDATA is probably the easiest. Other than that, there is PetriW's suggestion of named pipes, or sockets.
对于非常短的消息,WM_COPYDATA可能是最简单的。除此之外,PetriW建议使用命名管道或插座。
#4
See JclAppInstances in the JCL.
请参阅JCL中的JclAppInstances。
#5
Get a look at ZeroMQ. If you got the thoughts behind the architecture it may dramatically change the way you think. As far as I had a walkthrough they have libraries for many programming languages, including Delphi. But I had not a chance to try it.
看看ZeroMQ。如果你了解了架构背后的想法,它可能会大大改变你的思维方式。至于我有一个演练,他们有许多编程语言的库,包括Delphi。但我没有机会尝试它。
Here is Delphi port of the library.
这是图书馆的Delphi端口。
#6
Check Cromis.IPC, internally it uses named pipes, but provides a much easier API, and it's compatible with recent Delphi versions.
检查Cromis.IPC,在内部使用命名管道,但提供了更简单的API,并且它与最近的Delphi版本兼容。
#7
I suggest TMappedFile - more efficient than named pipes.
我建议TMappedFile - 比命名管道更有效。
#8
I use InterAppComm and it's very good.
我使用InterAppComm,非常好。
It sends data between two or more applications. It can send strings, integers and other data types.
它在两个或多个应用程序之间发送数据。它可以发送字符串,整数和其他数据类型。