Link to home
Start Free TrialLog in
Avatar of dhertzfe
dhertzfe

asked on

Trouble Killing a Process

Hey All,

I used some of the information here to use CreateProcess. Everything works great except killing the process if it times out. The command I'm issuing for a test to time out is "Notepad.exe xxx.txt". I know Notepad will open and stay open so the GetExitCodeProcess should never get anything but STILL_ACTIVE.  Here is my code. When I check the Task Manager on NT, Notepad is still running even after the CloseHandle commands.

 FillChar(si, SizeOf(si), #0);
 with si do
   begin
      cb := SizeOf(si);
      lpReserved := nil;
      lpDesktop := nil;
      dwFlags := STARTF_USESHOWWINDOW;
      wShowWindow := hideFlg;
      cbReserved2 := 0;
      lpReserved2 := nil;
   end;

   if (CreateProcess(nil, PChar(cmdLine), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, si, pi)) then
   begin
     dwRet := STILL_ACTIVE;
     t1 := Now;
     while (dwRet = STILL_ACTIVE) do
     begin
        GetExitCodeProcess(pi.hProcess, dwRet);
        Application.ProcessMessages;
        t2 := Now;
        t3 := t2 - t1;
        DecodeTime(t3,Hour,Min,Sec,MSec);
        If Sec >= timeOut then begin
           sMesg := FormatDateTime('mm"/"dd"/"yyyy " " hh:mm:ss AM/PM "Timeout"',Now);
           Memo1.Lines.Add(sMesg);
           sMesg := '   File = ' + processFile;
           Memo1.Lines.Add(sMesg);
           sMesg := '   Command = ' + cmdLine;
           Memo1.Lines.Add(sMesg);
           CloseHandle(pi.hProcess);
           CloseHandle(pi.hThread);
           timeoutFlg := True;
           break;
        end;
     end;
   end else begin
     sMesg := FormatDateTime('mm"/"dd"/"yyyy " " hh:mm:ss AM/PM "Error"',Now);
     Memo1.Lines.Add(sMesg);
     sMesg := '   File = ' + processFile;
     Memo1.Lines.Add(sMesg);
     sMesg := '   Command = ' + cmdLine;
     Memo1.Lines.Add(sMesg);
   end;


Thanks in advance,
Chad
Avatar of inthe
inthe

some code i had from another question that may help as mit seems to work ol for closing the program:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
   
implementation

{$R *.DFM}
function CreateProcessSimple(sExecutableFilePath : string ): string;
  var
   pi: TProcessInformation;
   si: TStartupInfo;
   wnd : hwnd;
   i : integer;
  begin
   FillMemory( @si, sizeof( si ), 0 );
   si.cb := sizeof( si );
    CreateProcess(Nil, PChar( sExecutableFilePath ),
                  Nil, Nil, False, NORMAL_PRIORITY_CLASS,
                  Nil, Nil, si, pi );

      WaitForSingleObject(pi.hProcess,1000);
   wnd:= FindWindow(nil, PChar('Untitled - Notepad'));
   setwindowpos(wnd,HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE+SWP_NOMOVE+SWP_NOSIZE);
   CloseHandle( pi.hProcess );
   CloseHandle( pi.hThread );
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CreateProcessSimple('notepad.exe');
end;


procedure TForm1.Button2Click(Sender: TObject);
var h: THandle;
begin
  h:= FindWindow(nil, PChar('Untitled - Notepad'));
  SendMessage(h, WM_CLOSE, 0, 0);
end;


end.


Regards Barry
whoops i might have "jumped the gun" a bit here.
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dhertzfe

ASKER

Barry & Madshi  Thanks for your replies.

I tried PostThreadMessage(pi.dwThreadID, WM_QUIT, 0, 0);
and TerminateProcess(pi.hProcess, 0);  but the notepad processes(my test scenario) still are listed in the Task Manager of NT.  So I assume they are still there and were not terminated.  Do I need to do something additionally?

To use PostMessage(notepadsMainWnd, WM_CLOSE, 0, 0);, how would I get the window handle?  I don't know the caption of the window to use  h:= FindWindow(nil, PChar('win caption')); since I am passed the commands from another program. If I provide the class with GetClass, wouldn't I get the handle from the main program?

Need further assistance.  :(

Thanks,
Chad
DUH!!!!!    Madshi.....Your PostThread does work....I just had it after the CloseHandle call.

Thanks for the both of you.
Chad