Solved

Creating and Killing app within app

Posted on 1998-07-24
15
186 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
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…
This is a video describing the growing solar energy use in Utah. This is a topic that greatly interests me and so I decided to produce a video about it.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

914 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

16 Experts available now in Live!

Get 1:1 Help Now