![]() |
Programm extern ausführen
Hallo erstmal :hi:
ich hoff ich bin in der richtigen Kategorie gelandet.. Ich möchte gern mit Delphi ein Programm ausführen und die Befehle angeben, nach stundenlangem Ggoglen hab ich herausgefunden, dass ShellExecute, WinExecute und TProcess geeignet wären, wobei glaube ich nur letztere Funktion auch Befehle ausführt - oder? Dabei hab ich jetzt folgendes Problem: Muss ja eingeben uses SysUtils, Classes, Process; Dann spuckt Delphi mir aus "File not found: 'Process.dcu'" - ich verzweifelt nach dieser Datei gesucht aber ich find die nicht... Wo bekomm ich die denn jetzt her? Sorry, kenne mich kaum mit Delphi aus und probiere jetzt schon ziemlich lange, das zum Laufen zu kriegen. Wäre nett, wenn mir jemand hilft! Liebe Grüße, Ariane |
Re: Programm extern ausführen
Hallo und willkomen in der Dp!
Möglichkeiten zum starten von Programmen gibt es viele. ShellExecute, WinExec oder CreateProcess und sicher noch einige mehr. Aber für Dich sich die beiden ersten interessant. bei Shellexecute musst Du die ShellApi einbinden, bei Winexec, Windows oder SysUtils. Bin mit jetzt nicht sicher. |
Re: Programm extern ausführen
Delphi-Quellcode:
function WinExecAndWait_32(FileName: string; Visibility: Integer; bWait: Boolean = False): Longword;
var { by Pat Ritchey } zAppName: array[0..512] of Char; zCurDir: array[0..255] of Char; WorkDir: string; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; begin StrPCopy(zAppName, FileName); GetDir(0, WorkDir); StrPCopy(zCurDir, WorkDir); FillChar(StartupInfo, SizeOf(StartupInfo), #0); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := Visibility; if not CreateProcess(nil, zAppName, // pointer to command line string nil, // pointer to process security attributes nil, // pointer to thread security attributes False, // handle inheritance flag CREATE_NEW_CONSOLE or // creation flags NORMAL_PRIORITY_CLASS, nil, //pointer to new environment block nil, // pointer to current directory name StartupInfo, // pointer to STARTUPINFO ProcessInfo) // pointer to PROCESS_INF then Result := WAIT_FAILED else begin if bWait then WaitForSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, Result); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); end; end; { WinExecAndWait32 } das ist die funktion die ich immer verwende, und die ist auch kompatibel mit späteren windows versionen!!! um sie zu verwenden musst du unter uses windows einbinden aufrufen kannst du die function so: WinExecAndWait_32('c:\sin.exe +set game 2015', 1, False); wäre eine version mit parameter WinExecAndWait_32('c:\sin.exe', 1, False); und diese wäre ohne parameter!! die 1 steht für die sichtbarkeit des gestarten programms und true/false steht bei der function für das warten auf das gestartete programm |
Re: Programm extern ausführen
Erstmal danke für die Hilfe!!
Kann mit beiden Varianten das gewünschte Programm starten - aber wie lasse ich Delphi die Befehle in das Programm eingeben? Möchte, dass das Programm, sobald es gestartet wurde, immer das Selbe tut - also auch immer die selben Befehle bekommt. edit: Mir ist auch nicht so klar, was der Parameter auslöst.. edit2: ach doch, zumindest hab ich herausgefunden, dass der Parameter sich auf die Konfigurationen bezieht (wie lbccaleb ja auch mit "set" geschrieben hat, sorry..) |
Re: Programm extern ausführen
...mal andersrum gefragt: Was soll am Ende dabei rauskommen wenn "Delphi Befehle in Dein Programm eingegeben" hat?
|
Re: Programm extern ausführen
also den bsp mit dem parameter hab ich nur mal mit gepostet damit auch klar wird wie ein programm mit parametern über diese function gestartet wird, das brauchst du bei dir nicht mit eingeben wenn du keine parameter hast, desweiteren musst du natürlich die sin.exe durch dein programm austauschen, wie meinst du das mit von delphi eingeben lassen und es soll immer das selbe tun??
|
Re: Programm extern ausführen
Ok, konkretes Beispiel:
Programm: ampl.exe Befehle, die ich eingeben möchte: model test.mod; (noch weitere Befehle) quit; Es wäre doch bestimmt möglich, dass Delphi diese Befehle direkt an das Programm weiter gibt, oder? Am Ende soll Folgendes herauskommen: Beispiel: Ich möchte ein Problem mit einem Programm (SCIP) lösen. Die Informationen dazu lese ich aus Edit-Fenstern ein und speichere sie in einer externen Datei (das hab ich schon irgendwie hinbekommen, funktioniert soweit). Dann möchte ich das Lösungsprogramm starten. Dem Programm sollen die Befehle zum Lösen des Problems gegeben werden (das Programm nutzt, um die Lösung zu ermitteln, die externe Datei). Am Ende spuckt mir das Programm eine Lösung aus, die ich dann (aber erst später, erstmal sollte ich das Ausführen hinbekommen xD) wieder *äh* "einlesen" möchte, sodass sie in den Labels meines Programms erscheinen.. |
Re: Programm extern ausführen
Also Du hat (D)eine Anwendung wo du Infos in Edits hast. Jetzt soll beim Speichern gleich ein anderes programm gestarted werden, (SCIP.exe) wobei "model test.mod" an SCIP.exe übergeben wird. Richtig!?
|
Re: Programm extern ausführen
Ja genau. Ich möchte *nachzähl* 3 Befehle an scip.exe übergeben.
|
Re: Programm extern ausführen
Delphi-Quellcode:
sFileName := 'c:\path\bla.exe'
shellexecute(Handle, ExtractFileName(sFileName), 'model testy.mod', ÊxtractfilePtah(sFileName), SW_SHOW); |
Re: Programm extern ausführen
ja das wären dann in dem fall wie ich oben beschrieben hab die parameter was ich meinte....
das wäre mit der funktion dann so:
Delphi-Quellcode:
WinExecAndWait_32('c:\path\bla.exe model testy.mod', 1, False);
|
Re: Programm extern ausführen
Hmm er spuckt mir "Undeclared Identifier: sFileName" aus...Soll ich das noch irgendwo in die Variablen reinschreiben?
Sorry, wie gesagt, kenn mich da nicht so wirklich aus.. Was dies hier angeht
Delphi-Quellcode:
wird das Programmfenster sofort geschlossen. hab mal mit nem Screenshot versucht herauszufinden, was das Programm ausgibt, ich meine, dass es die Worte einzeln betrachtet oder so..
WinExecAndWait_32('c:\path\bla.exe model testy.mod', 1, False);
"invalid parameter: ..." |
Re: Programm extern ausführen
sFileName ist ein Sring den Du noch deklarieren musst.
|
Re: Programm extern ausführen
Merkwürdig, habe jetzt:
Delphi-Quellcode:
und dann wird gemeldet: "Missing operator or semicolon" und "Incompatible types: 'String' and 'PAnsiChar'".
procedure TForm1.BitBtn3Click(Sender: TObject);
var sFileName: String; begin sFileName := 'scip.exe' shellexecute(Handle, ExtractFileName(sFileName), 'model test.mod', ExtractfilePath(sFileName), SW_SHOW); end; |
Re: Programm extern ausführen
Zitat:
Delphi-Quellcode:
sFileName := 'scip.exe';
shellexecute(Handle, pchar(ExtractFileName(sFileName)), pchar('model test.mod'), pchar(ExtractfilePath(sFileName)), SW_SHOW); |
Re: Programm extern ausführen
Delphi-Quellcode:
würde auch gehn.
var sFileName: Char;
|
Re: Programm extern ausführen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
sorry muss dir leider sagen nee würds nicht, denn wenn man die var als char deklariert, kann man danach ihr keinen string zuweisen, das sind inkompatible komponenten! ausserdem würde in der prozedure shellexecute dadurch gleich 2 fehler entstehen, zumeinen weil der string 'model test.mod' weiterhinn besteht und zum anderen würde es glaub ich auch noch ne meldung geben das char und pchar inkompatibel sind (da will ich mich aber nicht drauf festlegen, müsst ich selber probieren erst) habs dir mal gemacht stellst dir das ungefähr so vor?? |
Re: Programm extern ausführen
Upps Ich meinte PChar.
Aber ich muss korigieren. Du hast. Hab es eben probiert. |
Re: Programm extern ausführen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo nochmal, tut mir leid, dass ich erst jetzt wieder reinschau...
also, an und für cih funktioniert die Ausführung des Programms jetzt. Da sich das Fenster immer selbst schließt, hab ich mal probeweise das Programm mit cmd ausgeführt. Es funktioniert, wenn ich nur "scip.exe" eingebe und dann erst die Befehle eingebe. Gebe ich aber "scip.exe model xy.mod" ein, wird angezeigt "Invalid Parameter". Ist es möglich, dass Delphi dann erst das Programm scip.exe ausführt und dann die Befehle weiter gibt? Blödes Programm :( edit: Im Anhang ist jetzt ein Bild von dem, was dann angezeigt wird... |
Re: Programm extern ausführen
Check mal mal scip.exe "model test.mod"
Wo ist das der Parameter "model" (im Screen)?? |
Re: Programm extern ausführen
ja ich wusste ja bisher nicht genau was du vorhast, jetzt wo du den screener gepostet hast kann ich dir schon mal sagen das "model" in dieser art dadrinne schon mal blödsinn ist, denn das prog erkennt diesen parameter so nicht, versuchs einfach mal ohne also so:
Delphi-Quellcode:
dann kannst ja noch mal schreiben..
"scip.exe xy.mod"
|
Re: Programm extern ausführen
Liste der Anhänge anzeigen (Anzahl: 1)
Funktioniert leider auch nicht. Habe außerdem leider auch die Befehle von AMPL und SCIP durchnander gebracht :oops: Kann die ja zum Glück leicht ändern..im Anhang jetzt der Versuch mit
scip.exe "read prog.zpl" Also mit diesen Eingaben funktionierts leider nicht. Gebe ich aber zuerst scip.exe ein, lande ich im "SCIP>" und dann funktioniert "read prog.zpl"... Ohne das "read" bzw. "model"/wie auch immer wird auch wieder angezeigt "invalid parameter <prog.zpl>" |
Re: Programm extern ausführen
Ist klar weil das programm nur die angegeben Parameter unterstützt, Die wären etwa -c -b -l
weder "read" noch "model" wird das Programm nie erkennen. |
Re: Programm extern ausführen
Oh mist :angel2:
Mit
Delphi-Quellcode:
funktionierts jetzt...
WinExecAndWait_32('scip.exe -c "read sudoku.zpl opt disp sol"', 1, False);
Vielen Dank an euch beide!! Hab mich ja selten doof angestellt xD Jetzt bleibt nur noch aus, wie ich die Zeilen, die das Programm ausgibt (die Lösungen) in Delphi einlese..soll ich dazu einen extra Thread erstellen? Könntet ihr mir da bitte auch noch helfen? |
Re: Programm extern ausführen
TDosCommand, CaptureCmd
|
Re: Programm extern ausführen
Hab jetzt versucht, TDoscommand.pas zu installieren, da wird aber dann angezeigt
"Could not create '(mein Verzeichnispfad von Delphi)\projects\bpl\dclusr70.bpl'" Wobei meine bpl Dateien glaub ich alle in (Delphi-Pfad)\Bin liegen.. Daraufhin hab ich ein neues Package erstellt und absolutes Chaos angerichtet.. Hab immerhin gute zwei Stunden gebraucht, um den angerichteten Schaden wieder zu reparieren bzw. herauszufinden wie ich auch wieder Dateien kompilieren kann :? Kann mir jemand bitte helfen? Ich krieg das nicht auf die Reihe :-/ |
Re: Programm extern ausführen
Morgen
Ich glaub Du hast Dein Delphi leicht verbogen. Versuch mal reparieren von Setup.
Delphi-Quellcode:
Edit1.Text -> Ist Dein Command! 'Cmd /k' musst du lassen. das sich die Console sonst nicht wiederbeendet. Schau in die Hilfe wegen dem Command (Cmd /?)
function GetConsoleOutput(const Command: String; var Output, Errors: TStringList): Boolean;
var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecurityAttr: TSecurityAttributes; PipeOutputRead: THandle; PipeOutputWrite: THandle; PipeErrorsRead: THandle; PipeErrorsWrite: THandle; Succeed: Boolean; Buffer: array [0..255] of 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), nil, nil, true, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, 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; procedure TForm1.Button1Click(Sender: TObject); var output, errors: TStringList; begin output:=TStringList.Create; try errors:=TStringList.Create; if GetConsoleOutput('cmd /K '+Edit1.Text, output, errors) then Memo1.Lines.AddStrings(output); finally output.free; errors.free; end; end; |
Re: Programm extern ausführen
Danke für die Antwort!!
Mittlerweile scheint Delphi wieder zu funktionieren, hab einfach mal reparieren lassen und meine "environment" paths zurückgesetzt, immerhin hab ich jetzt keinen fehler mit "can't find system.pas" mehr. Delphi startet das Programm ohne Fehlermeldungen. Führe ich aber den Prozess aus (klicke also auf den Button), läuft das Programm - spuckt aber nichts aus und stürzt ab (habs auch mal mehrere Minuten laufen lassen, hat nichts gebracht). Ist es außerdem möglich, statt in ein Memo-Feld eine Zeile bzw. einen Teil einer Zeile in ein Label einzulesen? An dem Programm kann es eigentlich auch nicht liegen, hab ein paar Befehle gekürzt, damit das SCIP-Fenster nicht zu viele Zeilen hat, bewirkte aber auch nichts. Woran kann das jetzt liegen? edit: hab die anderen Ausführ-Befehle wie WinExecute und so gelöscht und Edit1.Text durch 'scip.exe "r prog.zpl opt disp sol"', also meine Befehle ersetzt - richtig? Hab auch WinExecute nochmal vorher ausführen lassen aber dasselbe Ergebnis. |
Re: Programm extern ausführen
du könntest so eine zeile aus einem memo in ein label einlesen:
Delphi-Quellcode:
wobei die 4 die zeile im memo ist, die du auslesen möchtest...
label1.Caption := memo1.Lines.Strings[4];
|
Re: Programm extern ausführen
Oh man...mein Fehler war, dass ich für SCIP nicht den Befehl "quit" eingegeben habe -.-
Hmm jetzt verbleibt zuletzt (dann hör ich auch auf zu nerven ;) ), dass ich nur einen Teil der Zeile einlese, da meine Zeilen so aussehen: x#1#1#5 und ich will nur die 5 einlesen lassen und in das label bringen. Geht das? |
Re: Programm extern ausführen
versuchs mal damit:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var output, errors: TStringList; begin output := TStringList.Create; try errors:=TStringList.Create; if GetConsoleOutput('cmd /K '+Edit1.Text, output, errors) then label1.caption := output.ValueFromIndex[5]; finally output.free; errors.free; end; end; |
Re: Programm extern ausführen
Vielen vielen Dank, es funktioniert jetzt!! :bounce1:
Danke danke und nochmals danke :balloon: |
Re: Programm extern ausführen
Delphi-Quellcode:
Zwecks eventueller Fehler, ne :wink:
if GetConsoleOutput('cmd /K '+Edit1.Text, output, errors) then
label1.caption := output.ValueFromIndex[5] else label1.caption := errors.text; |
Re: Programm extern ausführen
Och mist...heut ist mir ein Fehler aufgefallen:
hatte RunCaptured('e:', 'scip.exe', '-c "read prog.zpl"') benutzt und wie erwartet funktionierte die ganze Geschichte auf einem anderen Computer wieder nicht.. Übrigens läuft das ganze über meinen USB-Stick, dachte also daran, einfach per c:\windows\explorer (müsste der arbeitsplatz sein..eigentlich o.O) meinen USB-Stick "anzusprechen" - aber der wird auch bei jedem PC anders benannt, G, Q, F, wie auch immer. Dann hab ich nach Befehlen gesucht, die einfach auf das Verzeichnis verweisen, in dem mein Delphi-Programm selbst sich befindet, also das aktuelle Verzeichnis. "chdir" und "cd" hab ich ausprobiert aber das ging auch nicht (geht nur in cmd?) Zuletzt wollte ich das durch eine Eingabe des Verzeichnisses in ein Edit-Fenster laufen lassen, aber dort wird angezeigt, dass der Verzeichnisname ungültig sei. Könntet ihr mir bitte noch einmal helfen? edit: also RunCaptured scheint nur das Laufwerk zu brauchen, nicht mal den kompletten Pfad.. edit2: achja, hier der link zu runcaptured selbst.. ![]() |
Re: Programm extern ausführen
Wenn du die Ausgabe nicht abfangen musst, hilft auch
![]() ![]() |
Re: Programm extern ausführen
Mit Ausgabe abfangen meinst du, dass Delphi Zeilen aus dem ausgeführten Programm ausliest? Brauche das Einlesen/Abfangen leider nach wie vor..
|
Re: Programm extern ausführen
Habs jetzt rausgefunden :) muss dafür nur
RunCaptured('.\', 'scip.exe', '-c "read prog.zpl quit"') Nochmal danke :hi: |
Re: Programm extern ausführen
Ich bedanke mich ebenfalls. Habe beim Lesen einiges kapiert und gelernt.
Danke an alle beteiligten. Dschingis |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz