![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите оптимизировать код (выполнения в консоли)!
Pavel © (2008-11-29 14:49:00)Пытался сделать свою программу для её использования вместо bat-файла. Всё работает, но каждый раз приходится запускать цикл:
procedure TForm1.Button1Click(Sender: TObject);
var
P:TProcessProcParam;
begin
P.ApplicationName := nil;
P.CommandLine := 'cmd.exe';
P.DataProc := AddToFormMemo;
GoProcess(P);
end;
И как ( при необходимости) выполнить последовательность команд, чтобы они не выполнялись все сразу?!
Код такой:
type
TProcessProcParam =
record
ApplicationName: PChar;
CommandLine: PChar;
DataProc: procedure (Str:PChar);
end;
PProcessProcParam = ^TProcessProcParam;
function ProcessProc(P:PProcessProcParam):DWord; stdcall;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
SecurityAttributes: TSecurityAttributes;
StdOutPipeRead, StdOutPipeWrite: THandle;
CreateResult: Boolean;
Chars: PChar;
BytesReadFromFile: Cardinal;
BytesReadFromPipe: Cardinal;
WaitResult: Cardinal;
begin
with SecurityAttributes do
begin
nLength := SizeOf(SecurityAttributes);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreateResult := CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecurityAttributes, 0);
if not CreateResult then
begin
P^.DataProc(nil);
if assigned(P^.ApplicationName) then FreeMem(P^.ApplicationName);
if assigned(P^.CommandLine) then FreeMem(P^.CommandLine);
Dispose(P);
Result := 1;
Exit;
end;
with StartupInfo do
begin
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
cb := SizeOf(StartupInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := 0;//StdOutPipeRead2;//GetStdHandle(STD_INPUT_HANDLE);
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
ZeroMemory(@ProcessInfo, SizeOf(@ProcessInfo));
CreateResult := CreateProcess(P^.ApplicationName, P^.CommandLine, nil, nil,
True, 0, nil, nil, StartupInfo, ProcessInfo);
if not CreateResult then
begin
P^.DataProc(nil);
CloseHandle(StdOutPipeRead);
CloseHandle(StdOutPipeWrite);
if assigned(P^.ApplicationName) then FreeMem(P^.ApplicationName);
if assigned(P^.CommandLine) then FreeMem(P^.CommandLine);
Dispose(P);
Result := 2;
Exit;
end;
repeat
WaitResult := WaitForSingleObject(ProcessInfo.hProcess, 100);
PeekNamedPipe(StdOutPipeRead, nil, 0, nil, @BytesReadFromPipe, nil);
if BytesReadFromPipe > 0 then
begin
getMem(Chars, BytesReadFromPipe + 2);
ZeroMemory(Chars, BytesReadFromPipe + 2);
ReadFile(StdOutPipeRead, Chars^, BytesReadFromPipe, BytesReadFromFile, nil);
OemToAnsi(Chars, Chars);
P^.DataProc(Chars);
FreeMem(Chars);
end;
until (WaitResult <> WAIT_TIMEOUT) and (BytesReadFromPipe = 0);
P^.DataProc(nil);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(StdOutPipeRead);
CloseHandle(StdOutPipeWrite);
if assigned(P^.ApplicationName) then FreeMem(P^.ApplicationName);
if assigned(P^.CommandLine) then FreeMem(P^.CommandLine);
Dispose(P);
Result := 0;
end;
procedure GoProcess(P:TProcessProcParam);
var
PP:PProcessProcParam;
C:DWord;
begin
New(PP);
if assigned(P.ApplicationName) then
begin
GetMem(PP^.ApplicationName, Length(P.ApplicationName));
StrCopy(PP^.ApplicationName, P.ApplicationName);
end
else
begin
PP^.ApplicationName := nil;
end;
if assigned(P.CommandLine) then
begin
GetMem(PP^.CommandLine, Length(P.CommandLine));
StrCopy(PP^.CommandLine, P.CommandLine);
end
else
begin
PP^.CommandLine := nil;
end;
PP^.DataProc := P.DataProc;
CreateThread(nil, 0, @ProcessProc, PP, 0, C);
end;
procedure AddToFormMemo(Str:PChar);
begin
if assigned(Str)
then Form1.Memo1.Lines.Add(Str)
else Form1.Memo1.Lines.Add('выполнено');
end;
Slym (2008-11-29 15:51:00) [21]Pavel (29.11.08 14:49)
1. какое обилие Диспозов/Фримемов Нюсов и гетмемов... не запутался?
2. DataProc вызывается в другом потоке и Form1.Memo1.Lines.Add(Str) вызовет ерор..
3. Пайпа нужно два... без hStdInput никуда...
4. ReadFile - не процедура, а функция возвращающая колво прочитанного
5. getMem(Chars, BytesReadFromPipe + 2); - что за магическая двойка?
6. И вообще код в топку...
7. Leonid Troyanovsky © (29.11.08 15:16) [1] +1
Leonid Troyanovsky (2008-11-29 15:16:00) [22]
> Pavel (29.11.08 14:49)
> Пытался сделать свою программу для её использования вместо
> bat-файла.
Вот отсюда - по-медленней.
Огласи все ТЗ.
--
Regards, LVT.