How to start and then kill a process

How do I start a command line (DOS) process and then kill it from Delphi? My platform is NT.

Regards,
Morten
LVL 1
mdrastedAsked:
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.

PeterLarsenCommented:
Use ShellExecute to activate the program and FindWindow to close it again.
You may search for it here.

0
LischkeCommented:
You can call CreateProcess with cmd.exe as executable and keep the returned process handle (in TProcessInformation). Whenever you think it is time to close the process then you can try sending a WM_QUIT message to the process or (if it doesn't react) call KillProcess.

Ciao, Mike
0
mdrastedAuthor Commented:
Can you please give me an example on how to use CreateProcess?

Regards;
Morten
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

PeterLarsenCommented:
Mike.
I dont think it is a good idea to remember the handle and use it to close the window again, because it may no longer exist.
-just a comment.
0
LischkeCommented:
A typical use is like:

WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);

I use this all the time and it works very well. Instead of posting all my (quite complex) code I give you another snippet created by Madshi:

unit runThread_;

interface

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

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

var Form1 : TForm1 = nil;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);   // This call does not return, unless copy is stopped
  processReady:=true;                            // Set "processReady" flag for main thread
  PostThreadMessage(waitingThread,WM_NULL,0,0);  // Wake up main thread
                                                 // If you call Application.HandleMessage (see below) in the
                                                 // main thread, the main thread is sleeping the most time in
                                                 // winAPI "waitMessage". So we send a "dummy" message in order
                                                 // to let the main thread return from Application.HandleMessage
end;

procedure TForm1.Button1Click(Sender: TObject);
var si  : TStartupInfo;
    pi  : TProcessInformation;
    dw1 : dword;
begin
  enabled:=false;
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE;
  if CreateProcess(nil,'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do         // create the thread object, but do not start it now...
      try
        processHandle:=pi.hProcess;         // tell the thread what process it has to watch
        processReady:=false;                // flag for the loop (see below)
        waitingThread:=GetCurrentThreadID;  // the current threadID for the wakeup message (see above)
        caption:='wait for copy...';
        Resume;                             // now all information is prepared; so let's start the thread
        repeat
          Application.HandleMessage;        // message loop
        until Application.Terminated or processReady;  // continue with normal program when either the
                                                       // started process has stopped or our program is closed
        caption:='copy stopped...';
      finally Free end;
    GetExitCodeProcess(pi.hProcess,dw1);
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready... (exitCode='+IntToStr(dw1)+')';
  end else caption:='could not start copy...';
  enabled:=true;
end;

end.

Ciao, Mike
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
LischkeCommented:
Peter, you don't need a window to post a message. All you need is a message queue which is automatically created when a thread calls GetMessage or PeekMessage the very first time. For these calls no window is needed but the command line program has indeed one so you can be sure that a message queue has been created.

Ciao, Mike
0
mdrastedAuthor Commented:
Thanks for your excellent help Mike!!

Regards,
Morten
0
LischkeCommented:
I'm pleased to help you and thank you for the A grading :-)

Ciao, Mike
0
PeterLarsenCommented:
Ok Mike, i understand this but it was not my point.
If you have a handle to a process and this process dont exist anymore or the handle has been recreated to another process - is it not possible that this may be a problem ??

I'm not asking just for keeping the discussion going, but because i dont know!

Regards
Peter
0
LischkeCommented:
No problem. If the process is already gone without that the application got notified of this fact (which one can prevent with the WaitFor* calls) then the APIs will just return False on return (PostThreadMessage and the like). The process ID as such is not used again, AFAIK, until the computer is rebooted.

Ciao, Mike
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.