Как да предавате низ между 2 Delphi приложения

Възможен дубликат:
Търсете алтернатива на съобщенията на Windows, използвани в комуникацията между процесите
Inter -комуникация на процеса

Имам работещо приложение Delphi 7, което разкрива библиотека с типове. Една от функциите, които TLB излага, е ProcessFile(fileName: string). Когато се извика тази функция, бих искал работеща услуга на Windows (също приложение на Delphi 7) да получава известие, че това събитие е извикано и какво е името на файла.

Всички мисли как да направите това ще бъдат много оценени. Вече се опитах да направя това чрез променени обратни извиквания, използвайки системния регистър и txt файл, но така или иначе понякога губя файл, който трябва да бъде обработен, тъй като този метод ProcessFile може да бъде извикан много пъти в секунда.

Благодаря!


person daktmacfan    schedule 20.11.2012    source източник
comment
Кен, мисля, че той търси връзка с метода ProcessFile на TLB. Заглавието обаче предполага нещо друго.   -  person alzaimar    schedule 20.11.2012
comment
Изпратете низа по наименована тръба   -  person David Heffernan    schedule 20.11.2012
comment
@alzaimar Независимо какво търси, IPC е единственият отговор   -  person David Heffernan    schedule 20.11.2012
comment
Проверете готовата за използване библиотека за комуникация между приложения с отворен код от Iztok Kacin, наречена Cronis IPC. IIRC, базира се на наименувани канали   -  person Edwin Yip    schedule 20.11.2012


Отговори (1)


Тръбите са идеални за тази работа. Можете да внедрите нишка за четене на канали от страната на вашата услуга и да изпратите съответните низови данни през канала в метода 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;

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;

Също така не забравяйте, че pipes работи като FIFO.

person Hasan Manzak    schedule 20.11.2012
comment
Няма ли да трябва да закрепите тръбата? - person David Heffernan; 20.11.2012
comment
Това е бърз пример за просто използване на тръба. Потребителят наистина трябва да вземе мерки за сигурност. - person Hasan Manzak; 20.11.2012
comment
Здравей @The_aLiEn, разглеждам твоето предложение и мога да го следвам, но в кодовия фрагмент на сървъра ти извикваш CtreateNamedPipe('\\.\pipe\myNamedPipe', PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE или PIPE_READMODE_MESSAGE или PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BufSize, BufSize, 0, нула) ; както и ConnectNamedPipe(h, nil); Част от коя библиотека или модули на Delphi са те? Предполагам, че те са нещо от трета страна (надявам се с отворен код)? Ако е така, бихте ли предоставили линк към мястото, където мога да ги намеря, или да предоставите кода за тези процедури? Благодаря! Дейвид - person daktmacfan; 21.11.2012
comment
Те не са от модул на трета страна, те са чист WinAPI ;) И документацията е напълно безплатна, тъй като е Windows SDK, очевидно. Не можете да намерите код за прозрения на тези API, тъй като Windows не е софтуер с отворен код, но в SDK има много и много неща, които обясняват как да използвате, как да не използвате и обяснения на тези API и параметри. Ето съответна документация. - person Hasan Manzak; 21.11.2012