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
dhertzfeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

intheCommented:
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
0
intheCommented:
whoops i might have "jumped the gun" a bit here.
0
MadshiCommented:
What is the problem, Chad? Do you think that the CloseHandle calls will *terminate/close* notepad? No no, that only closes the handles, nothing more. If you want to terminate notepad after the time is out, you will have to do something more.

E.g. try this:

PostThreadMessage(pi.dwThreadID, WM_QUIT, 0, 0);

Or this:

TerminateProcess(pi.hProcess, 0);

Or you could look for notepad's main window and post a WM_CLOSE message to it:

PostMessage(notepadsMainWnd, WM_CLOSE, 0, 0);

Regards, Madshi.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dhertzfeAuthor Commented:
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
0
dhertzfeAuthor Commented:
DUH!!!!!    Madshi.....Your PostThread does work....I just had it after the CloseHandle call.

Thanks for the both of you.
Chad
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.