0

I'm developing a Presentation software.

My application loops through the items of a playlist, get the Associated program for the item (=filename) to be showed, and then launches the associated program using "ShellExecute" function. So far so good...

But after specific time, the executed associated program needs to be properly closed (NOT terminated/killed). I'm able to get the processname (i.e. notepad.exe) and PID.

But I don't see a way to close the program using the Processname. I have found a way to Kill the program/process by using "TerminateProcess", but that is not the way I want to do it.

So my question is if there is a way to properly stop/close an external program by using the ProcessName or ProcessID.

Thanks in advance!!

  • 2
    What would you do if the application requires confirmation before quitting? See flow of [Closing the Window](https://learn.microsoft.com/en-us/windows/win32/learnwin32/closing-the-window). – Peter Wolf Oct 30 '19 at 09:33
  • 2
    Take a look at [this thread](https://stackoverflow.com/q/2055753/960757). – TLama Oct 30 '19 at 09:56
  • 2
    It depends on the program, and in full generality it's not even possible. Think of a program that opens all documents in a single process, for example. And think about processes that don't provide a standard mechanism to close. – David Heffernan Oct 30 '19 at 12:08
  • 2
    To add to David's list, think about programs that use an intermediate application to launch. For example, *.pas files aren't opened by bds.exe, they are opened by bdsLauncher.exe (That eventually forward the file to an instance of bds.exe). In those cases, the process referenced by the PID you have probably terminated ages before you'll want to close it, but the document is still open. – Ken Bourassa Oct 30 '19 at 13:16
  • @Peter: Ok, so WM_CLOSE may not be the best option here. Using WM_QUIT would be better. Normally, my application will only show some 'static' files (Jpg, Pdf, Pptx, Avi), so the application will never have to ask to save the file (since the files will never change). – user3261006 Oct 31 '19 at 11:15
  • @TLama: I will take a close look into this thread. Since I am just an amateur-devloper, it can take some time to understand the thread. But I will investigate. – user3261006 Oct 31 '19 at 11:18
  • @David: In my case, my application will only execute programs that have to show 'static' data/file. So the specific situations you are talking about will not happen in my case. – user3261006 Oct 31 '19 at 11:19
  • @Ken: Same remarks as for David. But thanks all for your input/feedback!! – user3261006 Oct 31 '19 at 11:20
  • The type of contents you're talking about (images, video, documents) can be perfectly displayed by your app and therefore you will gain total control over their presentation on the screen. Have you considered using [TOleContainer](http://docwiki.embarcadero.com/Libraries/Rio/en/Vcl.OleCtnrs.TOleContainer)? – Peter Wolf Oct 31 '19 at 12:44
  • I looked into TLama's provided link. I tried using the taskkill.exe approach, and this seems to do the trick! So, for now I will use the ShellExecute on 'taskkill.exe'. Thank you all for your suggestions and comments! – user3261006 Oct 31 '19 at 13:36
  • @Peter: My original attempt was using TOLEContainer for files like images, video, ...), and use the TWebbrowser component to show webpages, but the issue I had was that the application suffered from huge moemry-leaks (even when I destroyed and recreated tghe olecontainer and twebbrowser at runtime). – user3261006 Nov 02 '19 at 12:31

1 Answers1

0

You should use closing messages and send them to program, I succeed with this code, give it a try:

procedure TmyFRM.btn_closeClick(Sender: TObject);
var
  h: HWND;
begin
  h := FindWindow('Notepad', nil);
  if h <> 0 then
    PostMessage(h, WM_QUIT, 0, 0);
end;

and consider it sometimes you can use WM_Close instead of WM_Quit and you can work around SendMessage instead of PostMessage too. when you are trying to close a program properly without killing its process, so you are following the program routines and programs may respond diffrent to closing messages; for example, some programs will be Minimized to Tray after closing them and etc...

Armin Taghavizad
  • 1,625
  • 7
  • 35
  • 57
  • FindWindow is not working in my case, since I only have the ProcessName and ProcessID. FindWindow needs the WindowName (Title of the application), so not suitable for me here. – user3261006 Oct 31 '19 at 11:21