Closing/ending an external program

Von Pookie

MrExcel MVP
Joined
Feb 17, 2002
Messages
13,686
I know I can start an external program by using the Shell command, but how can I *end* the program?

I'm assuming something to do with API, which I have never used. I've searched and searched, and can't seem to find any already-written code that works. You would think someone, somewhere would have asked this already but if they have, it is very well hidden. All I keep finding is code to close instances of Excel or run a program and then continue a macro after the shell program ends, neither of which are the scenario that applies here. Actually, I take that back. I found this newsgroup post which is asking the exact same thing but the code posted does not work. I've also skimmed www.allapi.net but I can't figure out how to put the code together myself.

All I'm trying to do is start VBScroll when Excel opens and end it when Excel closes.

VBScroll simply sits in the taskbar; I have to right-click the icon and select Exit from the menu to close it. Current specs would be Excel 2002, Windows 2000. I was figuring on just adding the code to Personal.xls, nothing fancy. It's easy enough to start VBScroll with the shell command, no problems there. I just can't figure out how to end it.

Any <s>delicious cookies,</s> ideas, links, what have you?
 

Excel Facts

Add Bullets to Range
Select range. Press Ctrl+1. On Number tab, choose Custom. Type Alt+7 then space then @ sign (using 7 on numeric keypad)
Kristy

What I think you need is the FindWindow(Ex?) and SendMessage API functions.

I see in the link Ivan uses PostMessage.

Here's a short discussion on SendMessage vs PostMessage.
 
Upvote 0
I'm afraid that Ivan's code isn't working. No error messages--the code runs with no (visible) problems--but VBScroll remains open.

I searched here but somehow never found that thread. I found some code elsewhere that was reminiscent of that--had to put the text that was in the titlebar into the code. It didn't work, either.

What I'm wondering is if the fact that the program does not run in a window isn't the issue, e.g. there is no open window to find and therefore close. If this is indeed the case, wouldn't FindWindow have the same limitation?
 
Upvote 0
Kristy

So this VBScroll is in the system tray?

Perhaps what you need is some code that finds all the running processes?

I used to have a great guide to the Window API but lost it, I'll see if I can find it again.

By the way I'm not sure but in the link I posted does it not have code/explanation for using EnumWindows?

I'm sure I had a small application written in VB6 that used that to list all windows in a listbox, and closed them if you double clicked them.

Seem to remember it had problems with some types of windows, plus I think it used a callback function which I don't think is available in VBA.
 
Upvote 0
Norie:
So this VBScroll is in the system tray?

Yes, it runs in the system tray (looks like I said 'taskbar' above, oops).


The program *does* have an option to automatically start when Windows does, but that is not what I want. This question mainly came about because I keep forgetting to close VBScroll. It doesn't take up much memory, but there is absolutely no reason for it to be running if Excel is not open.
 
Upvote 0
Slightly edited the example from the link I sent you. It works. Edit the assignment to the Const.

VBScrollVonPookster.zip

<table width="100%" border="1" bgcolor="White" style="filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#C0CFE2', startColorstr='#FFFFFF', gradientType='0');"><tr><TD><font size="2" face=Courier New>  <font color="#0000A0">Option</font> <font color="#0000A0">Explicit</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> PROCESS_ALL_ACCESS = &H1F0FFF

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> OpenProcess <font color="#0000A0">Lib</font> "kernel32" _
     (ByVal dwDesiredAccess <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> bInheritHandle <font color="#0000A0">As</font> Long, _
      <font color="#0000A0">ByVal</font> dwProcessId <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GetExitCodeProcess <font color="#0000A0">Lib</font> "kernel32" _
      (ByVal hProcess <font color="#0000A0">As</font> Long, lpExitCode <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> TerminateProcess <font color="#0000A0">Lib</font> "kernel32" _
      (ByVal hProcess <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> uExitCode <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> ShellReturnValue <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> VBScrollFullname <font color="#0000A0">As</font> <font color="#0000A0">String</font> = "C:\Documents and Settings\Tom\Desktop\VBScroll.exe"

  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_Open()
       ShellReturnValue = Shell(VBScrollFullname)
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_BeforeClose(Cancel <font color="#0000A0">As</font> Boolean)
       <font color="#0000A0">Call</font> EndShelledProcess
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> EndShelledProcess() <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>

      <font color="#008000"> 'PURPOSE: End a process started with VB's Shell Statement</font>
      <font color="#008000"> 'INPUT: Task ID returned by Shell</font>
      <font color="#008000"> 'RETURNS: True if successful, false otherwise</font>

       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">Resume</font> <font color="#0000A0">Next</font>

       <font color="#0000A0">Dim</font> hInst <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
       <font color="#0000A0">Dim</font> hProcess <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
       <font color="#0000A0">Dim</font> lExitCode <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
       <font color="#0000A0">Dim</font> lRet <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

       hInst = ShellReturnValue
       <font color="#0000A0">If</font> hInst = 0 <font color="#0000A0">Then</font> <font color="#0000A0">Exit</font> <font color="#0000A0">Function</font>

      <font color="#008000"> 'Get handle to process</font>
       hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, hInst)
       <font color="#0000A0">If</font> hProcess <> 0 <font color="#0000A0">Then</font>
          <font color="#008000"> 'get exit code</font>
           GetExitCodeProcess hProcess, lExitCode
               <font color="#0000A0">If</font> lExitCode <> 0 <font color="#0000A0">Then</font>
                      <font color="#008000"> 'bye-bye</font>
                   lRet = TerminateProcess(hProcess, lExitCode)
                   EndShelledProcess = lRet > 0
               <font color="#0000A0">End</font> <font color="#0000A0">If</font>
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>

  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>
</FONT></td></tr></table><button onclick='document.all("9212006144126468").value=document.all("9212006144126468").value.replace(/<br \/>\s\s/g,"");document.all("9212006144126468").value=document.all("9212006144126468").value.replace(/<br \/>/g,"");window.clipboardData.setData("Text",document.all("9212006144126468").value);'>Copy to Clipboard</BUTTON><textarea style="position:absolute;visibility:hidden" name="9212006144126468" wrap="virtual">
Option Explicit

Private Const PROCESS_ALL_ACCESS = &H1F0FFF

Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long

Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long

Private Declare Function TerminateProcess Lib "kernel32" _
(ByVal hProcess As Long, ByVal uExitCode As Long) As Long

Private ShellReturnValue As Long
Private Const VBScrollFullname As String = "C:\Documents and Settings\Tom\Desktop\VBScroll.exe"

Private Sub Workbook_Open()
ShellReturnValue = Shell(VBScrollFullname)
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call EndShelledProcess
End Sub

Private Function EndShelledProcess() As Boolean

'PURPOSE: End a process started with VB's Shell Statement
'INPUT: Task ID returned by Shell
'RETURNS: True if successful, false otherwise

On Error Resume Next

Dim hInst As Long
Dim hProcess As Long
Dim lExitCode As Long
Dim lRet As Long

hInst = ShellReturnValue
If hInst = 0 Then Exit Function

'Get handle to process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, hInst)
If hProcess <> 0 Then
'get exit code
GetExitCodeProcess hProcess, lExitCode
If lExitCode <> 0 Then
'bye-bye
lRet = TerminateProcess(hProcess, lExitCode)
EndShelledProcess = lRet > 0
End If
End If

End Function</textarea>

VBScrollVonPookster.zip
 
Upvote 0
Because it's in the tray, I do not know how to close the app properly using SendMessage. It probably does not matter in this case. Just kill it. Smile

End an Application that was Started by the Shell Function

Oops! Didn't see you there, Tom (s'what I get for not refreshing the page).

That code *does* work. Yippee! The little icon stays in the system tray, but that disappears when I mouseover it. That happens even when I manually end it from the taskmanager, so that's not a problem for me.

Thanks! And a big :p for Google for not turning up anything remotely useful even when I entered almost the exact text that is on that page ("End an Application that was Started by the Shell Function").
 
Upvote 0
Tom

Nice code.:)

I don't suppose you know anywhere I can get a decent Windows API guide?
 
Upvote 0

Forum statistics

Threads
1,214,792
Messages
6,121,612
Members
449,039
Latest member
Mbone Mathonsi

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top