Delphi И Cmd.exe

Cambur

Active member
20.06.2010
27
0
#1
Это рабочий примерчик
отрыть окно CMD.exe
что-то там понаписать и по выполнять
закрыть окно

что НЕ делает - не читает вывод из окна.. что не хорошо.
если кто знает, как полностью контролировать cmd.exe - присоединяйтесь


Код:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Button3: TButton;
Edit2: TEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
si: STARTUPINFO;
pi: PROCESS_INFORMATION;
res: BOOL;
r: cardinal;
Wind: hWnd;
function Find(s: string): hWnd;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


function TForm1.Find(s: string): hWnd; // искать дескриптор окна по имени
var
Wnd: hWnd;
buff: array[0..127] of Char;
begin
Result := 0;
Wnd := GetWindow(Handle, gw_HWndFirst);
while not(Wnd = 0) do
begin
if not(Wnd = Application.Handle) and IsWindowVisible(Wnd) and
(GetWindow(Wnd, gw_Owner) = 0) and not(GetWindowText(Wnd, buff, sizeof(buff)) = 0) then
begin
GetWindowText(Wnd, buff, sizeof(buff));
if pos(s, StrPas(buff)) > 0 then
begin
Result := Wnd;
Break;
end;
end;
Wnd := GetWindow(Wnd, gw_hWndNext);
end;
end;

procedure TForm1.Button1Click(Sender: TObject); // открыть окно cmd.exe
begin
with si do begin
cb := sizeof(si);
lpReserved := nil;
lpDesktop := nil;
lpTitle := PChar('Guardian');
dwFlags :=  0;
cbReserved2 := 0;
lpReserved2 := nil;
end;
res := CreateProcess(nil, PChar('cmd.exe'), nil, nil, FALSE, 0, nil, nil, si, pi);
sleep(300);
Wind := Find('Guardian');
if Wind <> 0 then Edit1.Text := 'Chevere'
else Edit1.Text := 'No furula';
Button3.Enabled := wind <> 0;
end;

procedure TForm1.Button2Click(Sender: TObject); // закрыть окно cmd.exe
begin
GetExitCodeProcess(Pi.hProcess, R);
if R = STILL_ACTIVE then begin
TerminateProcess(Pi.hProcess, R);
CloseHandle(Pi.hProcess);
Edit1.Text := 'apagado';
end else Edit1.Text := 'Not active';
end;

procedure TForm1.Button3Click(Sender: TObject); // написать чего-нибудь в окне 
var																	 
i,j  : integer;
ch	: byte;
s	 : string;
begin
if not(Wind = 0) then begin
s := '';
if Edit2.Text <> '' then begin // код символа ASCII
ch := strtoint(Edit2.Text);
SetForegroundWindow( Wind );
Keybd_Event(ch, Pi.hProcess, KEYEVENTF_EXTENDEDKEY,Pi.hProcess);
Keybd_Event(ch, Pi.hProcess, {KEYEVENTF_EXTENDEDKEY Or} KEYEVENTF_KEYUP, Pi.hProcess);
s := s + char(ch)+'<'+inttostr(ch)+'> ';
end else begin				 // или строка символов (~ использую для генерации <ENTER>)
j := length(Edit1.Text);
SetForegroundWindow( Wind );
for i := 1 to j do begin
if Edit1.Text[i] = '~' then ch := 13
else ch := ord(Edit1.Text[i]);
//	 Keybd_Event(ch, Pi.hProcess, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, Pi.hProcess);
Keybd_Event(ch, Pi.hProcess, KEYEVENTF_EXTENDEDKEY,Pi.hProcess);
Keybd_Event(ch, Pi.hProcess, {KEYEVENTF_EXTENDEDKEY Or} KEYEVENTF_KEYUP, Pi.hProcess);
s := s + char(ch)+'<'+inttostr(ch)+'> ';
end;
end;
Edit1.Text := s;
end else Edit1.Text := 'No furula';
end;



end.
 

Cambur

Active member
20.06.2010
27
0
#3
нужно было выполнять chkdsk ежедневно..
а он требует подтверждения.
в CreateProcess я пишу cmd.exe /S /K "chkdsk c: /F"
а потом ...подтверждаю эмуляцией нажатия клавиш.
то есть намного симпатичнее выглядит программка с выводом в Memo используя ReadFile
этот способ позволяет анализировать результат
но работает только для "простых" команд - ping, dir, ipconfig, ...