Jak wyświetlić wynik działania aplikacji konsolowej
jas_dream
Artykuł odpowiada na pytanie jak w Delphi uruchomić dany program w trybie konsolowym i wyświetlić jego wynik (np. raport) w komponencie TMemo (oczywiście wynik można odrazu zapisywać, albo np. przedstawić w innym komponencie - wystarczy tylko drobna zmiana kodu)
{ główna funkcja }
function TForm1.RunCaptured(const _dirName, _exeName, _cmdLine, nazwa_pliku: string, tworz_raport: Boolean): Boolean;
var
start: TStartupInfo;
procInfo: TProcessInformation;
tmpName: string;
tmp: Windows.THandle;
tmpSec: TSecurityAttributes;
res: TStringList;
return: Cardinal;
begin
Result := False;
try
{ tmpName to plik w którym zostaną zapisane dane z aplikacji konsolowej }
{ jeżeli wartosc tworz_raport będzie prawdą, jest to także plik tymczasowy }
tmpName := nazwa_pliku;
FillChar(tmpSec, SizeOf(tmpSec), #0);
tmpSec.nLength := SizeOf(tmpSec);
tmpSec.bInheritHandle := True;
tmp := Windows.CreateFile(PChar(tmpName),
Generic_Write, File_Share_Write,
@tmpSec, Create_Always, File_Attribute_Normal, 0);
try
FillChar(start, SizeOf(start), #0);
start.cb := SizeOf(start);
start.hStdOutput := tmp;
start.dwFlags := StartF_UseStdHandles or StartF_UseShowWindow;
start.wShowWindow := SW_Minimize;
{ Start programu konsolowego }
if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,
0, nil, PChar(_dirName), start, procInfo) then
begin
SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
WaitForSingleObject(procInfo.hProcess, Infinite);
GetExitCodeProcess(procInfo.hProcess, return);
Result := (return = 0);
CloseHandle(procInfo.hThread);
CloseHandle(procInfo.hProcess);
Windows.CloseHandle(tmp);
{ Dodawanie wyniku aplikacji do komoponntu TMemo }
res := TStringList.Create;
try
res.LoadFromFile(tmpName);
Memo1.Lines.AddStrings(res);
finally
res.Free;
end;
{ jeżeli plik tymczasowy nie potrzebny to go usuń }
if tworz_raport = false then
Windows.DeleteFile(PChar(tmpName));
end
else
begin
{ w razie problemów wyswietl komunikat }
Application.MessageBox(PChar(SysErrorMessage(GetLastError())),
'Błąd uruchomienia aplikacji konsolowej!', MB_OK);
end;
except
Windows.CloseHandle(tmp);
{ jeżeli plik tymczasowy nie potrzebny to go usuń }
if tworz_raport = false then
Windows.DeleteFile(PChar(tmpName));
raise;
end;
finally
end;
end;
{ przykład }
// C: - lokalizacja programu konsolowego w tym przypadku dysk C:
// cmd.exe - nazwa programu w tym przypadku cmd.exe
// /c dir - parametr dla danego programu
// raport.txt - nazwa pliku raportującego
// true - po zakończeniu nie usuwaj plik raportujący
RunCaptured('C:', 'cmd.exe', '/c dir', 'raport.txt', true);
Info:
http://www.swissdelphicenter.ch/de/showcode.php?id=990
A co zrobi, żeby to polecenie wykonało się w bierzącej ścierzce, tj.
aby wykonywały się polecenia w typie cd .. itp...
? ?? ? ? ?? ??? ? ?? ?
wro dnia: thx stary właśnie tego potrzebowałem!
Patryk -> a co jeśli program będzie chodził przez 5 sekund? Co się do memo wczyta? :->
byś chociaż napisał kto jest autorem kodu :>
Czasami można prościej:
ShellExecute(Handle, 'open', 'cmd.exe', '/c dir c: > raport.txt', 'C:', SW_HIDE);
Memo1.Lines.LoadFromFile('C:\raport.txt');
jeszcze jest jeden kod: http://www.elists.org/pipermail/delphi/2003-November/024712.html ale niezbyt mi chce chodzic,
jak coś odsyłam, jakbyście mieli jakiekolwiek problemy
dużo łatwiejszym sposobem jest skorzystanie z TDosCommand,
Ale to juz jest w FAQ
linki:
http://www.codeproject.com/win32/runsilent.asp
http://www.torry.net/quicksearchd.php?SID=bc34bec387023809f4dd9bfcead20390&String=console&Title=Yes
http://4programmers.net/Forum/195239#195239
http://4programmers.net/Forum/viewtopic.php?id=66953
to by było na tyle
wporzo!