Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I use named pipes for this, it was the easiest one I found. I'll post the code when I get home from work.</p> <p>Here's an article on how to use it in delphi: <a href="http://www.delphi3000.com/articles/article_2918.asp?SK=" rel="noreferrer">http://www.delphi3000.com/articles/article_2918.asp?SK=</a></p> <p>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.</p> <p>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.</p> <pre><code>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 &gt; 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. </code></pre> <p>Here's how I send something:</p> <pre><code>TPBPipeClient.SendData('\\.\pipe\pipe server E5DE3B9655BE4885ABD5C90196EF0EC5', 'HELLO'); </code></pre> <p>Here's how I read something:</p> <pre><code>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; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload