Solved

Creating and Killing app within app

Posted on 1998-07-24
15
201 Views
Last Modified: 2011-09-20
I am trying to run 'another exe' from within my program. I have gotten the 'other exe' to run. But am having troubles getting the main program to kill the 'other exe'. I am using createprocess to start the 'other exe' I am trying to use the exitprocess to close the other app but it only closes the main program
Thanks for Help
0
Comment
Question by:bozo7
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 2
  • +1
15 Comments
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358659
Hi

The call to ExitProcess will kill the current process, that's why your main app closes.  To kill another process, call TerminateProcess.

Example:  I will start Notepad, then show you 2 ways to close Notepad from our app.  The 1st method is quick & dirty, the 2nd method is longer but safer.  You can choose which one you need.

First, declare these variables (in your form's public section):
    ProcessInfo: TProcessInformation;
    StartUpInfo: TStartUpInfo;

(1) To start Notepad:
procedure TForm1.btnStartNotepadClick(Sender: TObject);
begin
  ZeroMemory(@StartUpInfo, SizeOf(TStartUpInfo));
  with StartUpInfo do
    begin
      cb := SizeOf(TStartUpInfo);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_SHOWNORMAL;;
    end;
  CreateProcess(nil, PChar('C:\Windows\Notepad.exe'), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo);
end;

(2) To kill Notepad (the quick & dirty way):
procedure TForm1.btnKillNotepadClick(Sender: TObject);
begin
  TerminateProcess(ProcessInfo.hProcess, 0);
end;

There is one major problem with this approach.  TerminateProcess will kill the process without prompting to save changes.  You can test this by starting Notepad using the above method and then entering some data before calling TerminateProcess.

The correct way to do this is to send a WM_CLOSE to Notepad.  But, how to get Notepad's HWND?  To do this we use EnumThreadWindows to enumerate each of the thread's windows (in this case there is only one window: Notepad).  This is done as follows:

(3) Closing Notepad "gently" (the safe method)
Declare a callback function as follows:
function ThreadWndProc(hWnd: HWND; lParam: LParam): Bool; stdcall;
begin
  // lParam is WM_CLOSE, because that's what we send in when
  // we call EnumThreadWindows.
  // Thus, the following will send WM_CLOSE to the window.
  SendMessage(hWnd, lParam, 0, 0);

  // Return True to continue enumeration.
  Result := True;
end;

Then, implement this code:
procedure TForm1.btnCloseNotepadClick(Sender: TObject);
begin
  if not (EnumThreadWindows(ProcessInfo.dwThreadId, @ThreadWndProc, WM_CLOSE)) then
    ShowMessage('EnumThreadWindows failed!');
end;

This should result in Notepad closing "normally".

Cheers,
JB
0
 
LVL 1

Author Comment

by:bozo7
ID: 1358660
The problem with the previous answer is the folowing :
 1: with the stdcall at the end of the function delcleration i get an 'Incorrect Method Declaration' error
 2: Take away the stdcall and at the @ThreadWndProc I get 'Variable Required'

Bozo
0
 
LVL 3

Expert Comment

by:vladika
ID: 1358661
Why method?
Are you declare  ThreadWndProc as Form1 method???

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358662
Hi

I copy & pasted the code straight from my Delphi 3 sample.  It worked fine, and should also work in Delphi 2 and 4.  (Not Delphi 1.)  I can e-mail you the sample if you want it.

As Vladika says, make sure that the "ThreadWndProc" callback function does NOT have "function TMyForm.ThreadWndProc" because it is NOT a method of your form.  It should be declared exactly as follows:
function ThreadWndProc(hWnd: HWND; lParam: LParam): Bool; stdcall;

Cheers,
JB
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358663
Hi

I copy & pasted the code straight from my Delphi 3 sample.  It worked fine, and should also work in Delphi 2 and 4.  (Not Delphi 1.)  I can e-mail you the sample if you want it.

As Vladika says, make sure that the "ThreadWndProc" callback function does NOT have "function TMyForm.ThreadWndProc" because it is NOT a method of your form.  It should be declared exactly as follows:
function ThreadWndProc(hWnd: HWND; lParam: LParam): Bool; stdcall;

Cheers,
JB
0
 
LVL 1

Author Comment

by:bozo7
ID: 1358664
I am using Delphi 3.
It won't shutdown the exe I am opening consistently. Sometimes it does other times it doesn't.
JB if you could email me your sample that would be great. ross@stiix.com
Thanks
Bozo
0
 
LVL 3

Expert Comment

by:Matvey
ID: 1358665
Hi all, can't say much about the example here, but I use a good component in such cases always. So you might consider using it too. I sent it to you.
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358666
Hi all

bozo7: I have sent the sample to you.

Matvey: I got your mail.  Thanks.  The component you sent uses the "quick & dirty" method I described, that is "TerminateProcess".  This means that (in my example) if you run Notepad and type some text, then when you terminate Notepad it doesn't ask you if you want to save changes.  That's why I used the longer but safer method too, which uses "EnumThreadWindows".

But it's given me an idea.  It wouldn't be hard to modify that component (if the author, Kevin Savko, doesn't mind) so that it uses the "safe" method too.

Cheers,
JB
0
 
LVL 3

Expert Comment

by:Matvey
ID: 1358667
Great idea, if you have some time than it's very cool...
0
 
LVL 1

Author Comment

by:bozo7
ID: 1358668
JB
Your example works great Thank You Very Much
I have not tried the component from Matvey yet. But if JB is right i will stick with the long and clean method.
Bozo

0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358669
Hi Bozo,
Glad it works for you.  Let me know if you want me to post an answer again.

Cheers,
JB
0
 
LVL 1

Author Comment

by:bozo7
ID: 1358670
JB
Please post you answer again
One thing i discovered is that the exe fired from within my exe is a systray application where the form close action is caNone. The only way to close the app is to call application.terminate
Any advice on calling application.terminate would help
Bozo
0
 
LVL 5

Accepted Solution

by:
JimBob091197 earned 200 total points
ID: 1358671
Hi Bozo

Here is the answer again.

I'm not sure how you would get the Application object of the systray app.  In this case you may have to use the TerminateProcess method, but this is not ideal.

Did you write the systray app?

JB
0
 
LVL 1

Author Comment

by:bozo7
ID: 1358672
Yes I did write the systray app. it is only one form that would show our company logo.I want it to run while another program uses our security library. So i think i will try to do some message handling and trap a message to terminate application.
Any advice email me at
ross@stiix.com
Thank You, JB
Bozo
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1358673
Hi

Well, I was going to suggest you handle a msg to terminate the systray app, but you beat me to it.  :)

JB
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month9 days, 1 hour left to enroll

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question