Solved

Creating and Killing app within app

Posted on 1998-07-24
15
184 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
  • 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
 
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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

706 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now