Autor Beitrag
kraz
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mi 29.10.03 22:10 
Hallo, ich spiele gerade ein bischen mit dem edonkey-server herum.

Ich habe eine kleine oberfläche gemacht, mit der man die ini vom server anpassen kann.

Den Server starte ich so:
ausblenden Delphi-Quelltext
1:
ShellExecute(0'open', PChar(RootDir+'dserver.exe'), PChar(''), nil, SW_HIDE);					

wenn man den server in der eingabeaufforderung startet ist man in dem server-modus und kann dort z.b. mit der eingabe des buchstaben "g" den status abfagen ...

ich kann schon aufs fenster zugreifen ... aber wie komme ich an die ausgabe ?

unter postmessage und getmessage finde ich hier nichts womit ich was anfangen kann und mit der hilfe komme ich sowieso nie zurecht ...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button3Click(Sender: TObject);
var
  h: hwnd;
  begin

  try
    h := FindWindowByTitle(RootDir+'dserver.exe');
    if h <> 0 then
  /////// hier muss dss jetzt hin oder ? - nur was ?
    except
 end;
end;

wenn ich es so nicht hinbekomme muss ich auf die logdatei zugreifen ...
denke aber nicht das das ne saubere lösung ist ...

Danke im Vorraus !! :D

Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.

_________________
Man muss schnell laufen, um dort zu bleiben wo man ist ...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 30.10.03 09:33 
Also, zunächst mal: Ich hab so was auch schon gebraucht, da hab ich das auch benutzt:

Der folgende Quelltext ist von Martin Strohal:
(Delphi-Source.de)
www.delphi-treff.de/...m-programm-anzeigen/

Im folgenden steht eine Funktion, die eine Kommandozeile aufruft und die Ausgabe, sowie Fehler in eine Stringliste schreibt.

Danach folgt noch ein Beispiel für die Benutzung der Funktion.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
function GetConsoleOutput(const Command: Stringvar Output, Errors: TStringList): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  PipeOutputRead: THandle;
  PipeOutputWrite: THandle;
  PipeErrorsRead: THandle;
  PipeErrorsWrite: THandle;
  Succeed: Boolean;
  Buffer: array [0..255of Char;
  NumberOfBytesRead: DWORD;
  Stream: TMemoryStream;
begin
  //Initialisierung ProcessInfo
  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);

  //Initialisierung SecurityAttr
  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
  SecurityAttr.nLength := SizeOf(SecurityAttr);
  SecurityAttr.bInheritHandle := true;
  SecurityAttr.lpSecurityDescriptor := nil;

  //Pipes erzeugen
  CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
  CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);

  //Initialisierung StartupInfo
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb:=SizeOf(StartupInfo);
  StartupInfo.hStdInput := 0;
  StartupInfo.hStdOutput := PipeOutputWrite;
  StartupInfo.hStdError := PipeErrorsWrite;
  StartupInfo.wShowWindow := sw_Hide;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

  if  CreateProcess(nil, PChar(command), nilnil, true,
  CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nilnil,
  StartupInfo, ProcessInfo) then begin
    result:=true;
    //Write-Pipes schließen
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsWrite);

    //Ausgabe Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
      while true do begin
        succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
        if not succeed then break;
        Stream.Write(Buffer, NumberOfBytesRead);
      end;
      Stream.Position := 0;
      Output.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;
    CloseHandle(PipeOutputRead);

    //Fehler Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
      while true do begin
        succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
        if not succeed then break;
        Stream.Write(Buffer, NumberOfBytesRead);
      end;
      Stream.Position := 0;
      Errors.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;
    CloseHandle(PipeErrorsRead);

    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    CloseHandle(ProcessInfo.hProcess);
  end
  else begin
    result:=false;
    CloseHandle(PipeOutputRead);
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsRead);
    CloseHandle(PipeErrorsWrite);
  end;
end;


Zitat:
Aufrufbeispiel:
Für die Ausgabe und die Fehler wird zunächst eine Stringliste erzeugt. Anschließend wird obige Funktion aufgerufen. Ist sie erfolgreich ausgeführt wurden (Rückgabewert ist true), wird die Output-Stringliste in einem Memo angezeigt.
Um Kommandozeilenbefehle ausführen zu können, die keine eigenständigen Anwendungen sind (wie der DOS-Befehl "dir" im folgenden Beispiel) muss der Name des Kommandozeileninterpreters davor stehen. "cmd.exe" ist das unter Windows NT/2000/XP und "command.com" unter Windows 9x. Der Parameter /c sorgt dafür, dass der Kommandozeilenbefehl ausgeführt und die Kommandozeile anschließend wieder geschlossen wird.


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button1Click(Sender: TObject);
var output, errors: TStringList;
begin
  output:=TStringList.Create;
  try
    errors:=TStringList.Create;
    if GetConsoleOutput('cmd /c dir c:\', output, errors) then
      Memo1.Lines.AddStrings(output);
  finally
    output.free;
    errors.free;
  end;
end;


Grüße, S.J.
// EDIT: Link aktualisiert


Zuletzt bearbeitet von jaenicke am Mo 05.07.10 22:36, insgesamt 2-mal bearbeitet
kraz Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Fr 31.10.03 09:28 
Titel: danke !
Hallo

Ich habe das obrige mal getestet und funktioniert wunderbar mit dir ...
aber bei der dserver.exe bekomme ich nichts in memo rein.

ich denke das ist, weil die funktion keinen true wert liefert bis der server wieder geschlossen wird.

Nach dem start von dserver befindet man sich in einem eingabemodus:
Der Befehl "g" liefert z.b. die userzahl und anzahl der files ...

Außerdem gelangt man damit ja nicht an den laufenden Prozess ...
Der server würde nochmal gestartet und ich erhielte natürlich dann die werte des 2. - neuen servers : user=0 files=0

irgendwie muss ich doch an den laufenden prozess kommen ...
also einem laufenden fenster nen befehl zusenden und ausgabe auslesen.

Ich hoffe da gibts noch ne andere möglichkeit ...

_________________
Man muss schnell laufen, um dort zu bleiben wo man ist ...
kraz Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Fr 31.10.03 09:35 
kann ich das hier irgendwie für meine zwecke verwenden ?

hab ich unter "netsend nachricht abfangen" gefunden ...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.Button1Click(Sender: TObject);  
var  
  hWnd, hLabel: Cardinal;  
  buffer: array[0..255of Char;  
begin  
  hWnd := FindWindow(nil'Nachrichtendienst ');  
  hLabel := GetDlgItem(hWnd, $0000FFFF);  
  SendMessage(hLabel, WM_GETTEXT, sizeof(buffer), Integer(@buffer));  
  ShowMessage(string(buffer));  
end;


Moderiert von user profile iconTino: Delphi-Tags hinzugefügt.

_________________
Man muss schnell laufen, um dort zu bleiben wo man ist ...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 15.11.03 14:54 
Titel: Ich hab da was...
Hallo!

Ich hab durch Zufall hier im Forum als ich selbst was gesucht habe genau das gefunden, das das macht!

Das funktioniert im Grunde so wie der Quelltext, den ich gepostet hatte!
Die folgende Komponente stammt von maxk!

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:

TConsoleSession by maxk 

If think, all properties are known. So I needn't present it here. 
PLEASE NOTE: TConsoleSession isn't able to run 16-Bit applications 
under systems higher than Windows NT. 
If you have any questions and/or ideas please mail me: delphi_max@lycos.de 
}
 

unit ConsoleSession; 

interface 

uses 
  Windows, Messages, SysUtils, Classes, ExtCtrls; 

type 
  TGotBytesEvent=procedure(Sender:TObject;Buffer:stringof object
  TConsoleSession = class(TComponent) 
   constructor Create(AOwner:TComponent); override
   destructor Destroy; override
   procedure Write(Buffer:string); 
   procedure WriteLn(Buffer:string); 
   function Running:boolean; 
   procedure ReadFromPipe; 
   procedure Execute; 
   procedure Terminate(ExitCode:Cardinal=0); 
   procedure WaitFor(TimeOut:Cardinal=0); 
   function GetProcess:Cardinal; 
  private 
    FCommandLine:string
    FReadBufferSize:Cardinal; 
    FWriteBufferSize:Cardinal; 
    FReadInterval:integer; 
    FOnGotBytes:TGotBytesEvent; 
    Timer:TTimer; 
    hIReadPipe,hIWritePipe,hOReadPipe,hOWritePipe:THandle; 
    ProcessInfo:TProcessInformation; 
    procedure FReadFromPipe(Sender:TObject); 
    procedure SetReadInterval(NewInterval:integer); 
    procedure CleanUp; 
  protected 
    { Protected-Deklarationen } 
  public 
    { Public-Deklarationen } 
  published 
    property CommandLine:string read FCommandLine write FCommandLine; 
    property ReadBufferSize:Cardinal read FReadBufferSize write FReadBufferSize; 
    property WriteBufferSize:Cardinal read FWriteBufferSize 
     write FWriteBufferSize; 
    property ReadInterval:integer read FReadInterval write SetReadInterval; 
    property OnGotBytes:TGotBytesEvent read FOnGotBytes write FOnGotBytes; 
  end

procedure Register

implementation 

constructor TConsoleSession.Create(AOwner:TComponent); 
begin 
 inherited Create(AOwner); 

 if csDesigning   in ComponentState then begin 
  MessageBox(0,'Please note that TConsoleSession isn''t able to run 16-Bit '
   'applications under systems higher than Windows NT.'+#13+'When you have any'
   ' ideas so mail me: delphi_max@lycos.de - Thanks'+#13+'This message only '
   'appears in design time.','Warning',MB_ICONEXCLAMATION); 
 end

 FCommandLine:='cmd.exe'
 FReadBufferSize:=256
 FWriteBufferSize:=65535
 Timer:=TTimer.Create(nil); 
 Timer.OnTimer:=FReadFromPipe; 
 SetReadInterval(100); 
end

destructor TConsoleSession.Destroy; 
begin 
 Timer.Free; 
 if Running then TerminateProcess(ProcessInfo.hProcess,0); 
 CleanUp; 
 inherited Destroy; 
end

procedure TConsoleSession.Write(Buffer:string); 
var BytesToWrite,BytesWritten:Cardinal; 
begin 
 if not Running then 
  raise Exception.Create(Name+': Command not running'); 
 while length(Buffer)>0 do begin 
  BytesToWrite:=length(Buffer); 
  if BytesToWrite>FWriteBufferSize then BytesToWrite:=FWriteBufferSize; 
  WriteFile(hIWritePipe,Buffer[1],BytesToWrite,BytesWritten,nil); 
  Delete(Buffer,1,BytesWritten); 
 end
end

procedure TConsoleSession.WriteLn(Buffer:string); 
begin 
 Write(Buffer+#13#10); 
end

function TConsoleSession.Running:boolean; 
begin 
 Result:=WaitForSingleObject(ProcessInfo.hProcess,0)=WAIT_TIMEOUT; 
end

procedure TConsoleSession.ReadFromPipe; 
begin 
 if not Running then 
  raise Exception.Create(Name+': Command not running'); 
 FReadFromPipe(nil); 
end

procedure TConsoleSession.Execute; 
var SecAttr:TSecurityAttributes; 
    StartupInfo:TStartUpInfo; 
begin 
 if not Running then CleanUp else 
  raise Exception.Create(Name+': Already running'); 

 with SecAttr do begin 
  nLength:=SizeOf(TSecurityAttributes); 
  bInheritHandle:=true; 
  lpSecurityDescriptor:=nil
 end

 if not CreatePipe(hIReadPipe,hIWritePipe,@SecAttr,0then 
  raise Exception.Create(Name+': Unable to create write pipe'); 
 if not Createpipe(hOReadPipe,hOWritePipe,@SecAttr,0then 
  raise Exception.Create(Name+': Unable to create read pipe'); 

 FillChar(StartupInfo,Sizeof(StartupInfo),#0); 
 with StartupInfo do begin 
  cb:=SizeOf(StartupInfo); 
  hStdOutput:=hOWritePipe; 
  hStdInput:=hIReadPipe; 
  dwFlags:=STARTF_USESTDHANDLES+STARTF_USESHOWWINDOW; 
  wShowWindow:=SW_HIDE; 
 end

 if not CreateProcess(nil,PChar(FCommandLine),@SecAttr,@SecAttr,True, 
  NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo,ProcessInfo) then 
   raise Exception.Create(Name+': Unable to start command.'+#13+'Error: '
   IntToStr(GetLastError)); 
end

procedure TConsoleSession.Terminate(ExitCode:Cardinal=0); 
begin 
 if not Running then 
  raise Exception.Create(Name+': Command not running'); 
 TerminateProcess(ProcessInfo.hProcess,ExitCode); 
 CleanUp; 
end

procedure TConsoleSession.WaitFor(TimeOut:Cardinal=0); 
var Tick:Cardinal; 
begin 
 Tick:=GetTickCount; 
 while (Tick+TimeOut>GetTickCount) and (Running) and (TimeOut=0do begin 
  Sleep(1); 
 end
end

function TConsoleSession.GetProcess:Cardinal; 
begin 
 if not Running then 
  raise Exception.Create(Name+': Command not running'); 
 Result:=ProcessInfo.hProcess; 
end

procedure TConsoleSession.FReadFromPipe(Sender:TObject); 

 function BytesInPipe:Cardinal; 
 begin 
  if not PeekNamedPipe(hOReadPipe,nil,0,nil,@Result,nilthen Result:=0
 end

var BytesRead:DWord; 
    Buffer:string
begin 
 if (not Running) or (BytesInPipe=0then exit; 
 try 
  Timer.Enabled:=False; 
  repeat 
   BytesRead:=0
   SetLength(Buffer,FReadBufferSize); 
   ReadFile(hOReadPipe,Buffer[1],length(Buffer),BytesRead,nil); 
   SetLength(Buffer,BytesRead); // Remove trash from other reads 
   OemToAnsi(@Buffer[1],@Buffer[1]); 
   if Assigned(FOnGotBytes) then FOnGotBytes(Self,Buffer); 
  until BytesInPipe=0
 finally 
  Timer.Enabled:=True; 
 end
end

procedure TConsoleSession.SetReadInterval(NewInterval:integer); 
begin 
 Timer.Interval:=NewInterval; 
 FReadInterval:=Timer.Interval; 
end

procedure TConsoleSession.CleanUp; 
begin 
 if ProcessInfo.hProcess<>0 then CloseHandle(ProcessInfo.hProcess); 
 if ProcessInfo.hThread<>0 then CloseHandle(ProcessInfo.hThread); 
 if hOReadPipe<>0 then CloseHandle(hOReadPipe); 
 if hOWritePipe<>0 then CloseHandle(hOWritePipe); 
 if hIReadPipe<>0 then CloseHandle(hIReadPipe); 
 if hIWritePipe<>0 then CloseHandle(hIWritePipe); 

 ProcessInfo.hProcess:=0
 ProcessInfo.hThread:=0
 hOReadPipe:=0
 hOWritePipe:=0
 hIWritePipe:=0
 hOWritePipe:=0
end

procedure Register
begin 
  RegisterComponents('maxk', [TConsoleSession]); 
end

end.


Damit kannst Du Daten während der Ausführung eines DOS-Programms in die Konsole schreiben und lesen!

Viel Erfolg,
S.J.
oOXTCOo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 141

Windows XP Prof. 3
Delphi 7
BeitragVerfasst: Sa 15.01.11 08:40 
ich würde genau sowas brauchen...
ich möchte laufend von einem dos programm, den inhalt auslesen (in einem intervall), ich muss nichts zum fenster senden, einfach nur im intervall lesen.

wie kann ich mit hilfe dieser komponente einfach den kompletten fenster hinhalt in einem intervall im memo anzeigen oder in einem string schreiben?

mit dieser komponente wird mir zwar der inhalt angezeigt, aber nur nach einiger wartezeit und in zwei teilen...

gibt es nicht eine einfachere möglichkeit einfach per fenster handle den inhalt aus einem dos fenster zu lese wie bei einem windows handle?


danke!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 15.01.11 10:45 
Was das Programm dann macht ist vermutlich den Ausgabecursor zu positionieren. Damit habe ich mich noch nie weiter beschäftigt das auszulesen.
Vorstellen kann ich mir mehrere Möglichkeiten, z.B. die entsprechende API zu hooken und das so mitzubekommen.

Ich habe das bei einem Programm, das auf diese Weise einen prozentualen Fortschritt ausgegeben hat, einfach per Logik entsprechend interpretiert. Weil da klar war welche Ausgabe wann kommt. Da ging es mir auch nicht um die Anzeige des Ergebnisses, sondern um dessen Aufbereitung.

user profile iconoOXTCOo hat folgendes geschrieben Zum zitierten Posting springen:
gibt es nicht eine einfachere möglichkeit einfach per fenster handle den inhalt aus einem dos fenster zu lese wie bei einem windows handle?
Nicht dass ich wüsste. :nixweiss:
oOXTCOo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 141

Windows XP Prof. 3
Delphi 7
BeitragVerfasst: Sa 15.01.11 23:04 
ich habe mir die sources genauer angesehen und das problem schein daran zu liegen das mein ziel dos programm auch nur den fortschritt anzeigt um dem es mir genau geht und den ich gerne in meinem programm anzeigen würde.

es funktioniert perfekt mit konsolen programmen die immer eine neue zeile erstellen, aber mein ziel konsolen programm positioniert den cursor immer neu und zeigt den neuen status immer in der selben zeile an, darum verute ich mal, wird das ergebnis immer nur dann angezeigt wenn der buffer voll ist oder das programm abgeschlossen hat.

kannst du mir einen tip geben wie das über die api direkt funktioniert?

oder was wäre wenn ich den buffer kleiner mache so das immer nur die grösse des letzten ergebnisses rein passt?
dann müsste ich doch erzwingen können, das immer der buffer ausgegeben wird.

ich kanns leider im moment nicht testen, bin gerade nicht bei meinem computer, aber ich könnte mir vorstellen das es funktioniert.

die letze idee die ich hätte wäre die konsolen anwendung zu patchen damit sie mir immer eine neue zeile ausgiebt.
aber das wollte ich vermeiden, da diese anwendung nicht von mir ist und ich die nicht verändern dürfte.
oOXTCOo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 141

Windows XP Prof. 3
Delphi 7
BeitragVerfasst: So 16.01.11 05:32 
problem über die win api gelöst! ;)

wer selbiges problem hat: entwickler-forum.de/...ht=ReadConsoleOutput (funktioniert bestens!)
hjl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22
Erhaltene Danke: 2

Windows 10 Enterprise (64 Bit)
Delphi 7, Delphi XE2, Delphi Berlin (10.1), Delphi Tokyo (10.2)
BeitragVerfasst: Do 27.10.16 13:11 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Also, zunächst mal: Ich hab so was auch schon gebraucht, da hab ich das auch benutzt:

Der folgende Quelltext ist von Martin Strohal:
(Delphi-Source.de)
www.delphi-treff.de/...m-programm-anzeigen/

Im folgenden steht eine Funktion, die eine Kommandozeile aufruft und die Ausgabe, sowie Fehler in eine Stringliste schreibt.

Danach folgt noch ein Beispiel für die Benutzung der Funktion.
...


Von diesem Quelltext von Martin Strohal habe ich auch abgeschaut.

Es geht mir aber nur um die Ausführung eines bestimmten Programmes ohne Benutzeroberfläche (es kann auch mit Benutzeroberfläche laufen und hat für den Lauf ohne Benutzeroberfläche eine eigenen Eingabeparameter).
Dieses Programm macht auf die Konsole laufend Textausgaben - je nach Anwendungsfall auch stundenlang.
Auf der Basis dieses Quelltextes ist mir das auch gelungen, die Ausgaben in einem Memo-Fenster anzeigen zu lassen.
Das Programm läuft sonst völlig im Hintergrund.
Nur habe ich die lokalen Funktionsvariablen global deklariert und die eigentliche Funktion durch einen Button-Click ausführen lassen.

Nun soll dieses Programm aber auch vorzeitig beendet werden können, zu einem beliebigen Zeitpunkt, wenn auch erst nach 1 oder ein paar Stunden.
Unter dem programm-eigenen DOS-Fenster schafft man das mit den Tastatureingaben 'e' mit Abspeichern der Ergebnisse, 'n' ohne Abspeichern der Ergebnisse,
anschließend ist das Programm mit der Enter-Taste zu schließen, wobei dann das eigene programmeigene DOS-Fenster auch geschlossen wird.
Das Programm verwendet im Lauf ohne Benutzeroberfläche dazu die Tastaturabfragen wie z.B. GetasyncKeyState(69) <> 0.

Meine Versuche, mit Eingaben in der Anwendung darauf Einfluß zu nehmen, sind bisher fehlgeschlagen.
Gern würde ich dies mit 2 Buttons machen, also Beenden mit und ohne Abspeichern.
Kann man nicht mit StartupInfo.hStdInput die Eingabeschnittstelle PipeInputWrite festlegen und mit
WriteFile(PipeInputWrite, cbuf, 1, NumberOfBytesWrite, nil);
darauf eingeben?

Weitere Angaben: Delphi 7, Windows 7 Prof. 64 Bit, 4-Prozessorkern-Rechner
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 27.10.16 15:32 
Ich habe danach (siehe oben) ja noch eine Variante für lesen und schreiben gepostet:
www.entwickler-ecke.....php?p=109159#109159

Ich hatte danach noch eine deutlich bessere Variante weiterentwickelt (TDOSCommand, das Original lief nicht unter neueren Delphiversionen), aber die finde ich grad nicht... das Original müsste bei dir aber mit Delphi 7 laufen.

Vielleicht hilft dir auch diese aktuellere Komponente weiter:
github.com/TurboPack/DOSCommand

Für diesen Beitrag haben gedankt: hjl