[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 628
  • Last Modified:

How to programmatically end process (notepad.exe) in W2000 & XP

Hi To ALL,
This little tool scans CD-DVD and close Apps as soon as user press eject button on drive.
Problem with this code is that doesnt recognise Player as Window title because new song is new title.  
"WPPlay" works fine.

What I would like to do is instead FindWindow Title to find Process "Player.exe".
How is that possible?
Thx
Best Regards
Prozor7

procedure TForm1.Timer1Timer(Sender: TObject);
 var
  h: HWND;
  title, title2 : string;
 begin
  title := 'Player';
  title2 := 'WPPlay';
    with DiskEject1 do
      begin
        if DiskEject.Ejected = True then
          h := FindWindow(nil,PChar(title));
           Application.ProcessMessages;
            PostMessage(h, WM_CLOSE, 0, 0);
        if DiskEject.Ejected = True then
          h := FindWindow(nil,PChar(title2));
           Application.ProcessMessages;
            PostMessage(h, WM_CLOSE, 0, 0);
    end;
 end;
end.

How to programmatically end process (notepad.exe) in W2000 & XP
0
prozor7
Asked:
prozor7
  • 8
  • 7
1 Solution
 
TvigepCommented:
The code below will give you the list of processes running as the Taskmanager does. It assumes a TStringList on a form called Plist, if you want to execute this directly. Once you've got the process name, you can use
BOOL TerminateProcess(
      HANDLE  hProcess, // handle to the process
      UINT  uExitCode // exit code for the process  
      );


HTH,
Stef
uses tlhelp32;

procedure TForm1.GetProcessList;
var TP:TProcessEntry32;
    snapshot:THandle;
    s : string;
    counter : integer;
    error : DWORD;
begin
  TP.dwSize:=sizeof(MODULEENTRY32);
  snapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
  if snapshot<>0 then
  begin
    if Process32First(snapshot,TP) then
    begin
      counter:=1;
      Plist.Cells[0,counter]:=IntToStr(counter);
      Plist.Cells[1,counter]:=IntToStr(TP.th32ProcessID);
      Plist.Cells[2,counter]:=ExtractFileName(TP.szExeFile);
      Plist.Cells[3,counter]:=inttostr(TP.cntUsage);

      while Process32Next(snapshot,TP) do
      begin
        inc(counter);
        Plist.Cells[0,counter]:=IntToStr(counter);
        Plist.Cells[1,counter]:=IntToStr(TP.th32ProcessID);
        Plist.Cells[2,counter]:=ExtractFileName(TP.szExeFile);
        Plist.Cells[3,counter]:=inttostr(TP.cntUsage);
      end;
    end else
    begin
      ShowMessage(SysErrorMessage(GetLastError));
      error:=getlasterror;
      s:='Error getting Process Entry : '+inttostr(error)+ ', cannot display process list!';
      Application.MessageBox(PChar(s),'Error Occurred', MB_ICONERROR + MB_OK);
    end;
  end else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    error:=getlasterror;
    s:='Error getting System snapshot : '+inttostr(error)+ ', cannot display process list!';
    Application.MessageBox(PChar(s),'Error Occurred', MB_ICONERROR + MB_OK);
  end;
  CloseHandle(snapshot);
end;
0
 
prozor7Author Commented:
Thanks for answer,
How can I implement
BOOL TerminateProcess(
     HANDLE  hProcess, // handle to the process
     UINT  uExitCode // exit code for the process  
     );
In existing code

procedure TForm1.Timer1Timer(Sender: TObject);
var
 h: HWND;
 title, title2 : string;
begin
 title := 'Player';
 title2 := 'WPPlay';
   with DiskEject1 do
     begin
       if DiskEject.Ejected = True then
         h := FindWindow(nil,PChar(title));
          Application.ProcessMessages;
           PostMessage(h, WM_CLOSE, 0, 0);
       if DiskEject.Ejected = True then
         h := FindWindow(nil,PChar(title2));
          Application.ProcessMessages;
           PostMessage(h, WM_CLOSE, 0, 0);
   end;
end;

I need to terminate, close application, end process Player.exe what ever is called as soon as user press button on CD-DVD.
Thx.
0
 
TvigepCommented:
Below you'll find a snippet of how to implement TerminateProcess. The th32ProcessID you have to get through the calls to the ToolhelpSnapshot, they are also the process ID's listed in the Task Manager.

HTH,
Stef

    hProcess : THandle;
    TermSucc : boolean;
begin
  hProcess:=OpenProcess(0, TRUE, th32ProcessID);
  if hProcess = 0 then
  begin
    ShowMessage(SysErrorMessage(GetLastError));
  end else
  begin
    TermSucc := TerminateProcess(hProcess, 0);
    if not TermSucc  then
    begin
      ShowMessage(SysErrorMessage(GetLastError));
    end else
    begin
      Application.MessageBox('Process terminated successfully!','Termination succesful!', MB_ICONWARNING + MB_OK);
    end;
  end;  
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
prozor7Author Commented:
Please help,
Im litle confused,
Can we start from begining?
I need to close application (End Task) lets call them Player.exe, as soon as user press button on CD-DVD.
I cant use FindWindow

procedure TForm1.Timer1Timer(Sender: TObject);
var
h: HWND;
title, title2 : string;
begin
title := 'Player';
title2 := 'WPPlay';
  with DiskEject1 do
    begin
      if DiskEject.Ejected = True then
        h := FindWindow(nil,PChar(title));
         Application.ProcessMessages;
          PostMessage(h, WM_CLOSE, 0, 0);
      if DiskEject.Ejected = True then
        h := FindWindow(nil,PChar(title2));
         Application.ProcessMessages;
          PostMessage(h, WM_CLOSE, 0, 0);
  end;
end;

Please help
0
 
TvigepCommented:
OK. I'll write this down from the beginning, without code, you can find all the code you need in my previous postings:

Player.exe is running, and you need to close it.
FindWindow will not work, because the window title contains the title of the media playing and we don't know what is playing currently.
So, you need to use the process instead of the window, because that will always be named the same.
You can walk through the list of processes using the Toolhelp32 stuff (add uses tlhelp32; to your unit), an example of how to do that is in my first post.

Basically, it's like this:

Make a snapshot of the computer's running processes
snapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);

if the snapshot was created succesfully, get the first process out of the snapshot
Process32First(snapshot,TProcessEntry32)

if you can get the first process succesfully, get the next process
Process32Next(snapshot,TProcessEntry32)

repeat the previous step until the Process32Next returns false

then close the snapshot to release the memory
CloseHandle(snapshot);


From the TProcessEntry32 structure you can obtain a couple of things which are important to you:
1. TProcessEntry32.th32ProcessID contains an integer which identifies the process (this is the PID column in the Processlist of the Task Manager)
2. TProcessEntry32.szExeFile contains the filename of the application (Image Name column in the Processlist of the Task Manager)

so you want to run through the list of processes until
ExtractFileName(TProcessEntry32.szExeFile)='player.exe'

then TProcessEntry32.th32ProcessID contains the ID of the process you want to kill. To kill a process, you need to have a handle to the process. You get this handle by using
hProcess:=OpenProcess(0, TRUE, TProcessEntry32.th32ProcessID);

Once you've got the handle to the process, you can execute TerminateProcess with an exitcode of 0, which always indicates a proper shutdown:
TerminateProcess(hProcess, 0);

Does this clear it up a little bit?

HTH,
Stef
0
 
prozor7Author Commented:
It help a lot,
I need to learn litle more because I receive Access denid Error.
0
 
TvigepCommented:
hmmm. I assume you are administrator on your machine, so it shouldn't be user-rights.... maybe it is because you are running the app from Delphi? See if you can run it as a regular app, what happens then?
0
 
prozor7Author Commented:
Yes Im Admin its not user-right, Apps are running by third tool, I think its not problem with that.

Let me explain in short what Im trying to do:
HTPC to be user friendly no keyboard no mouse just Remote Control.
With disabled autoplay my tool scan CD-DVD drive and start appropriate Apps when new media is inserted.
Problem is very simple today Apps can play Audio and DVD media but I want specific Apps to play .avi second .mp3 third DVD….jpg… etc.
If Apps stay active it will start to play new media when is inserted and new Apps that was selected from CD-DVD scan will also start to play.

I will start from beginning, and I will probably stuck with same problem.

Thank you very much.
You were very helpful and patient with me.
Points will go to you.
0
 
prozor7Author Commented:
He was very helpful and patient with me.
0
 
TvigepCommented:
hmmm. maybe the access denied happens because it is windows running the stuff... but what you could also try is simply change the registry associations for the file types you mention to the proper apps. that would save you a lot of programming nightmares and would also work with a double click in the explorer. Maybe an idea?
0
 
prozor7Author Commented:
I already try that but Apps must be terminated when CD-DVD doors are opened. No double click no any other action from user.
I even contact with Software Company … no response.
0
 
TvigepCommented:
I think I have an idea why you are getting a Access Denied error. It happened to me last night as well, when I tried to kill a Service. What probably happens is that a windows Service (I don't know which one) keeps an eye on the CD-DVD, and when media is inserted the service checks what it is and fires up an application. Presumably the application then becomes a child of the Service, which can thus only be killed through the Service Control Panel. I am not 100% sure of this, but I think that is the problem. So instead of writing an application that kills your player, you might have to write it as a Service to make sure the rights are in order, and you may have to use the Service Control stuff to stop your player.exe. Maybe this is worth checking out?

Stef
0
 
prozor7Author Commented:
Thx for excellent suggestion,
There must be an simple and easy way to do this, it is in front of me but I cant see.

Damir

0
 
prozor7Author Commented:
As I sead early solution is simple. thanks to Carlos Ponce de Leon who create excellent unit (You can terminate processes by filename (only the first found or all) or ProcessID. No installation needed. Simply include the unit in your uses block).
Unit is possible to download from : http://www.delphispirit.com/rd/Delphi/35/241

This way I would like to thanks Stef aka Tvigep whos help was tremendues, without him I could not solve my problem.
Thx again

0
 
TvigepCommented:
Had a look at this unit. That is good stuff indeed. Hope it works for you!
Cheers,
Stef

PS. No problem, i've received so much help myself on different newsgroups and websites, I'm glad to finally be able to return the favor :-))
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now