AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Mit Delphi ein anderes Delphiprogramm ansprechen

Mit Delphi ein anderes Delphiprogramm ansprechen

Ein Thema von Back2Code · begonnen am 16. Jan 2014 · letzter Beitrag vom 16. Jan 2014
Antwort Antwort
Seite 2 von 2     12
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.536 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Mit Delphi ein anderes Delphiprogramm ansprechen

  Alt 16. Jan 2014, 15:07
http://de.wikipedia.org/wiki/Standard-Datenstr%C3%B6me
ErrOut = stderr
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.108 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: Mit Delphi ein anderes Delphiprogramm ansprechen

  Alt 16. Jan 2014, 15:08
Gibts hier im Board bzw im Netz eine gute Erklärung zu den Begriffen "Pipe & stdOut? Höre ich jetzt zum ersten Mal
Das MSDN-Tutorial hier ist eigentlich genau das, was wir wollen. Ich habe es in Kürze einmal versucht, nachzubauen, hat auch halbwegs funktioniert. In meiner VCL-Memo konnte ich sehen, was der (unsichtbare) Kindprozess einfach mittels WriteLn() rausgeworfen hat. Das hat auf die Schnelle auch geklappt, nur müsste ich noch eine Lösung finden, nicht bis in alle Unendlichkeit zu warten, bis jemand etwas in die Pipe schreibt.

Ich werfe es hier einfach mal hinein:

Delphi-Quellcode:
unit Unit13;

interface

uses
   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
   System.Classes, Vcl.Graphics,
   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
   TMainForm = class(TForm)
      gridpanel: TGridPanel;
      startButton: TButton;
      stopButton: TButton;
      stdOutMemo: TMemo;
      Timer1: TTimer;

      procedure Timer1Timer(Sender: TObject);
      procedure startButtonClick(Sender: TObject);
      procedure stopButtonClick(Sender: TObject);

      private const
         // relativer Pfad ausgehend vom Arbeitsverzeichnis
         childProcessApplicationName: String = '.\..\ChildProcess\Win32\Debug\ChildProcessProject.exe';


      private var
         myProcess: TProcessorNumber;

         readHandle: THandle;
         writeHandle: THandle;

      private
         procedure startProcess();
         procedure stopProcess();

         procedure tryStartProcess();
         procedure tryStopProcess();

         procedure createMeAPipe(
            var readHandle: THandle;
            var writeHandle: THandle
         );

         /// <exception cref="EFileNotFoundException" />
         procedure checkChildPossible();

         procedure tryReadFromPipe();
         function isValidReadHandle(): Boolean;

   end;

var
   MainForm: TMainForm;

implementation

{$R *.dfm}

{ TMainForm }

procedure TMainForm.startButtonClick(Sender: TObject);
begin
   startProcess();
end;

procedure TMainForm.startProcess();
begin
   startButton.Enabled := False;
   try
      tryStartProcess();
      stopButton.Enabled := True;
   except
      startButton.Enabled := True; raise;
    end;
end;

procedure TMainForm.stopButtonClick(Sender: TObject);
begin
   stopProcess();
end;

procedure TMainForm.stopProcess();
begin
   stopButton.Enabled := False;
   try
      tryStopProcess();
      startButton.Enabled := True;
   except
      stopButton.Enabled := True; raise;
   end;


end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin
   if isValidReadHandle() then
      tryReadFromPipe();
end;

procedure TMainForm.tryReadFromPipe();
const
   readBufferLength = 2400;
var
   buffer: Array[0..readBufferLength] of AnsiChar;
   bytesRead: DWORD;
begin

   ReadFile(readHandle, buffer, readBufferLength, bytesRead, nil);
   buffer[bytesRead] := #0;

   stdOutMemo.Lines.Append(buffer);

end;

function TMainForm.isValidReadHandle(): Boolean;
begin
   Result :=
      not (readHandle = 0)
   and
      not (readHandle = INVALID_HANDLE_VALUE)
   ;

end;

procedure TMainForm.tryStartProcess();
var
   startInfo: TStartupInfo;
   processInfo: TProcessInformation;

   errorCode: Cardinal;
   errorMsg: String;

   dwCreationFlags: DWORD;
   cmdLine: String;

   applicationName: String;
begin

   checkChildPossible();
   createMeAPipe(readHandle, writeHandle);

   startInfo := Default(TStartupInfo);
   startInfo.cb := SizeOf(startInfo);

   startInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
   startInfo.wShowWindow := SW_SHOW;

   // Wegen STARTF_USESTDHANDLES in den dwFlags explizit alle drei Handles setzen
   startInfo.hStdOutput := writeHandle;
   startInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
   startInfo.hStdError := GetStdHandle(STD_ERROR_HANDLE);

   processInfo := Default(TProcessInformation);

   applicationName :=
      GetCurrentDir()+PathDelim+
      childProcessApplicationName;

   if not CreateProcess(
      PWideChar(applicationName),
      nil,
      nil,    // Standard-Sicherheit, Handle wird nicht vererbt
      nil,    // Standard-Sicherheit, Handle wird nicht vererbt
      True,    // Handles (Schreibepipe!) vererben
      0,    // Keine besonderen dwCreationFlags
      nil,
      nil,
      startInfo,
      processInfo
   ) then raise Exception.Create(
      'TMainForm.tryStartProcess: Errorcode '+
      GetLastError().ToString()+
      ' bei CreateProcess'
      )
   ;


end;

procedure TMainForm.checkChildPossible();
begin
   if not FileExists(
      GetCurrentDir()+childProcessApplicationName
   ) then raise EFileNotFoundException.Create(
      'TMainForm.checkChildPossible: '
      +'Datei '
      +childProcessApplicationName.QuotedString()
      +' nicht gefunden. Aktuelles Arbeitsverzeichnis ist '
      +GetCurrentDir().QuotedString()
   );
end;


procedure TMainForm.createMeAPipe(
   var readHandle: THandle;
   var writeHandle: THandle
);
var
   saSecurity: TSecurityAttributes;
begin

   saSecurity.nLength := SizeOf(TSecurityAttributes);
   saSecurity.bInheritHandle := True;
   saSecurity.lpSecurityDescriptor := nil;

   if not CreatePipe(readHandle, writeHandle, @saSecurity, 0) then
      raise Exception.Create('TMainForm.createMeAPipe: Konnte keine Pipe erstellen');


end;

procedure TMainForm.tryStopProcess;
begin
   raise EProgrammerNotFound.Create('derp');
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.100 Beiträge
 
Delphi 12 Athens
 
#13

AW: Mit Delphi ein anderes Delphiprogramm ansprechen

  Alt 16. Jan 2014, 15:28
Das hatte ich zuerst und dachte mir dann "nee, sieht komisch aus, machst'e es doch andersrum"
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.753 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: Mit Delphi ein anderes Delphiprogramm ansprechen

  Alt 16. Jan 2014, 18:15
.. hast Du die source-codes von dem consolen Programm nicht.
Wenn ja würde ich eher die zur Hand nehmen und in das GUI-Pogramm einbinden.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz