Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите оптимизировать код (выполнения в консоли)!


Страницы:   1 2

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.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо