Folgendermaßen starte ich ein Stapelverarbeitungsprogramm, OHNE das das DOS-
Fenster erscheint:
ShellExecute(Handle,'open',PChar(WinPath+'\Temp\Uninst.bat'),nil,nil,sw_hide
);
Dies funktioniert ganz gut, bis auf die Tatsache, daß nach Abarbeitung der
Batch-datei das DOS- Fenster (unsichtbar) im Arbeitsspeicher verbleibt.
Hat jemand eine Idee, wie ich es schaffen kann, das das DOS- Fenster nach
Beendigung der Batch-datei automatisch geschlossen wird ?
Übrigends beinhaltet die Batch-datei lediglich eine Zeile (z.B.
C:\Windows\blabla.exe), die ein anderes Programm startet.
Direkt in "ShellExecute" kann ich das leider aus best. Gründen nicht
eintragen, mir bleibt nur der Umweg über die kleine Batch.
Any Ideas ?
Grüße,
Stefan
Stefan Maierbacher schrieb:
>
> Hi,
>
> Folgendermaßen starte ich ein Stapelverarbeitungsprogramm, OHNE das das DOS-
> Fenster erscheint:
>
> ShellExecute(Handle,'open',PChar(WinPath+'\Temp\Uninst.bat'),nil,nil,sw_hide
> );
>
> Dies funktioniert ganz gut, bis auf die Tatsache, daß nach Abarbeitung der
> Batch-datei das DOS- Fenster (unsichtbar) im Arbeitsspeicher verbleibt.
Hatte die Woche ähnliche Probleme. Eine mögliche Lösung von vielen ist diese:
function WinExecAndWait32(FileName:String; Visibility :integer):integer;
var
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)
then
Result := -1
{ pointer to PROCESS_INF }
else begin
WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess,Result);
CloseHandle( ProcessInfo.hProcess );
CloseHandle( ProcessInfo.hThread );
end;
end;
Ansonsten schau dir mal den Thread "Batchaufruf aus einer Anwendung" in
dieser NG an. (Ja, die Lösung kann so nah sein :-)
Für Weitergehendes empfehle ich dir eine Deja-News-Suche nach
"CreateProcess", "WinExecAndWait32" oder "EnumThreadWindows".
Du wirst von der Masse erschlagen :-)
> Hat jemand eine Idee, wie ich es schaffen kann, das das DOS- Fenster nach
> Beendigung der Batch-datei automatisch geschlossen wird ?
> Übrigends beinhaltet die Batch-datei lediglich eine Zeile (z.B.
> C:\Windows\blabla.exe), die ein anderes Programm startet.
> Direkt in "ShellExecute" kann ich das leider aus best. Gründen nicht
> eintragen, mir bleibt nur der Umweg über die kleine Batch.
Vielleicht hilft dir auch hier "CreateProcess" oder "ShellExecuteEx"?
Cu, Marco
Hi Stefan,
>Hat jemand eine Idee, wie ich es schaffen kann, das das DOS- Fenster nach
>Beendigung der Batch-datei automatisch geschlossen wird ?
Explorer / *.BAT-Datei / Eigenschaften der Batchdatei / Reiter
Programm / "Beim beenden schliessen" aktivieren.
Gruss
Markus
----------------------------------------------------
home: zwy...@ibm.net
office: markus....@basler.ch
----------------------------------------------------
Es müßte auch gehen, wenn der Befehl nicht einfach der "xxx.BAT"
Aufruf ist sondern "COMMAND.COM /Cxxx.BAT". (aber erschlag
mich nicht, wenn das jetzt auch nicht funktioniert)
Gottfried.
Hi Gottfried
>Es müßte auch gehen, wenn der Befehl nicht einfach der "xxx.BAT"
>Aufruf ist sondern "COMMAND.COM /Cxxx.BAT".
Was willst du damit sagen?
>(aber erschlag mich nicht, wenn das jetzt auch nicht funktioniert)
*Huch*, wen hab ich denn kürzlich gehau'n ??
>Direkt in "ShellExecute" kann ich das leider aus best. Gründen nicht
>eintragen, mir bleibt nur der Umweg über die kleine Batch.
Darf man fragen, warum?
>Any Ideas?
Keine guten:
Den Batch nach einer bestimmten Zeit wieder töten.
Das System so einstellen, daß DOS-Fenster, deren Programm beendet ist,
sich wieder automatisch schließen.
Ciao, MM
Darf man -:)
Ich schreibe grad an einem Programm, welches ein anderes Delphiprogramm, das
mit InstallShieldExpress installiert wurde wieder deinstalliert, ohne das
man sich durch die Systemsteuerung quälen muß.
Hierzu lese ich den Deinstallationsschlüssel aus der Registry aus:
z.B.
C:\WINDOWS\unin0407.exe -f"C:\Programme\Testprogramm\DeIsL1.isu" -c"C:\Prog
ramme\Testprogramm\_ISREG32.DLL"
"Shellexecute" startet diesen Pfad leider nicht, wenn ich ihn als
Programmnamen angebe. Deshalb dachte ich mir, ich lege eine Batch an, in der
dieser Pfad drinsteht und starte anschließend die Batch mit "ShellExecute".
Das funktioniert auch, bis auf die Tatsache, daß das DOS- Fenster danach
nicht automatisch geschlossen wird (Es hilft auch nix, unter "Eigenschaften"
der Batch-datei "automatsch beenden" zu wählen, da die Batch ja nicht vom
User, sondern vom Prog angelegt wird.).
Bye,
Stefan
>>Aufruf ist sondern "COMMAND.COM /Cxxx.BAT".
>
>Was willst du damit sagen?
COMMAND.COM /C <Kommando> startet eine Shell, die genau den einen
Befehl abarbeitet und sich dann beendet. Ohne den Parameter bleibt die
Shell danach defaultmäßig offen und wartet auf immer mehr Kommandos
bis man sie mit Exit verlässt. COMMAND.COM /P öffnet eine, die man
nicht mit Exit verlassen kann.
All' das ist unter Windows aber verkompliziert, hängt von einer
Milliarde anderen Einstellungen ab und ist allgemein unzuverlässig.
Ciao, MM
Hi Stefan,
>"Shellexecute" startet diesen Pfad leider nicht, wenn ich ihn als
>Programmnamen angebe. Deshalb dachte ich mir, ich lege eine Batch an, in der
Klar, wenn du den ganzen String als Programmnamen angibst, dann geht
es nicht.
>C:\WINDOWS\unin0407.exe -f"C:\Programme\Testprogramm\DeIsL1.isu" -c"C:\Prog
>ramme\Testprogramm\_ISREG32.DLL"
ApplName := 'C:\WINDOWS\unin0407.exe';
ApplParam := '-f"C:\Programme\Testprogramm\DeIsL1.isu" -c"C:\Prog
ramme\Testprogramm\_ISREG32.DLL"';
ApplDir := 'c:\windows\temp'; //oder so ...
ShellExecute(0, Nil, pChar(ApplName), pChar(ApplParam),
pChar(ApplDir), SW_SHOW); //SW_SHOW oder was du willst.
Hab ich so bei mir ausprobiert und hat funktioniert.
Gruss
Markus
>Hierzu lese ich den Deinstallationsschlüssel aus der Registry aus:
>"Shellexecute" startet diesen Pfad leider nicht, wenn ich ihn als
>Programmnamen angebe.
Zerschneide ihn in Programm und Parameter und verfüttere die getrennt
an ShellExecute, dann geht's vielleicht. Wahrscheinlich kommst Du in
allen realen Fällen mit einer Suche nach einem Space aus. Wenn nicht,
insbesondere wenn Pfade mit Spaces vorkommen, müsstest Du das um die
Behandlung von '"' ergänzen:
> procedure SplitExeParams(CmdLine:string;var EXE,Params:string);
> var p:integer;
> begin
> p:=pos(' ',CmdLine);
> if p=0
> then begin EXE:=CmdLine; Params:='' end
> else begin EXE:=copy(CmdLine,1,p-1); Params:=copy(CmdLine,p+1,Length(CmdLine));
> end;
Jedenfalls ist es kein Grund einen Batch zu schreiben: Beteiligt sind
nur echte Windows-Programme, die sollte man klaglos starten können.
Ciao, MM