Start end Stop application

mtheriault2000

Well-known Member
Joined
Oct 23, 2008
Messages
826
Hello

I have ask a similar question, but no success with the answer

When my workbook_Open, i start to applications

Code:
 Hypersnap = Shell("C:\Program Files\HyperSnap 6\HprSnap6.exe" & " -hidden", 1) ' Sonray application
       Title_HLOC = Shell("C:\Program Files\HyperSnap 6\SonrayTitle_And_HLOC.exe")    ' AutoHotKey application

How can i close them in my worbook_Beforeclose

Martin
 

Excel Facts

Square and cube roots
The =SQRT(25) is a square root. For a cube root, use =125^(1/3). For a fourth root, use =625^(1/4).
Try this, based on http://www.thescarms.com/vbasic/stopprocess.aspx.

Put this in the ThisWorkbook module:
Code:
Option Explicit

'Start applications using the Shell function and stop them.
'Based on http://www.thescarms.com/vbasic/stopprocess.aspx

Dim Hypersnap As Long
Dim Title_HLOC As Long

Private Sub Workbook_Open()
    Hypersnap = Shell("C:\Program Files\HyperSnap 6\HprSnap6.exe" & " -hidden", 1) ' Sonray application
    Title_HLOC = Shell("C:\Program Files\HyperSnap 6\SonrayTitle_And_HLOC.exe")    ' AutoHotKey application
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    StopProcess Hypersnap
    StopProcess Title_HLOC
End Sub

Private Sub StopProcess(pid)
    Dim i As Long
    '
    ' Enumerate all parent windows for the process to be stopped
    '
    Call fEnumWindows(pid)
    '
    ' Send a close command to each parent window.
    ' The app may issue a close confirmation dialog
    ' depending on how it handles the WM_CLOSE message.
    '
    'WM_CLOSE instructs the windows to close in their normal fashion as if you manually closed them.
    'The window may display a confirmation dialog depending on how it handles the close message.
    'To avoid being asked to confirm closing the window, you can send the WM_DESTROY command instead.
    
    For i = 1 To colHandle.Count
        Call SendMessage(colHandle.Item(i), WM_CLOSE, 0&, 0&)
    Next

End Sub
Put this in a new Module:
Code:
Option Explicit

Public colHandle As New Collection

Public Const WM_CLOSE = &H10
Public Const WM_DESTROY = &H2

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

Public Function fEnumWindowsCallBack(ByVal hwnd As Long, ByVal lpData As Long) As Long
    Dim lParent    As Long
    Dim lThreadId  As Long
    Dim lProcessId As Long
    '
    ' This callback function is called by Windows (from the EnumWindows
    ' API call) for EVERY top-level window that exists.  It populates a
    ' collection with the handles of all parent windows owned by the
    ' process that we started.
    
    ' The lpData argument is the process id of the window(s) to be closed.
    
    fEnumWindowsCallBack = 1
    lThreadId = GetWindowThreadProcessId(hwnd, lProcessId)
    
    If lpData = lProcessId Then
        lParent = GetParent(hwnd)
        If lParent = 0 Then
            colHandle.Add hwnd
        End If
    End If
End Function


Public Function fEnumWindows(ByVal pid As Long) As Boolean
    '
    ' The EnumWindows function enumerates all top-level windows
    ' by passing the handle of each window, in turn, to an
    ' application-defined callback function. EnumWindows
    ' continues until the last top-level window is enumerated or
    ' the callback function returns FALSE.
    
    ' The pid parameter passed to the fEnumWindowsCallBack function is
    ' the process id of the window(s) to be closed.
    
    Call EnumWindows(AddressOf fEnumWindowsCallBack, pid)
End Function
 
Upvote 0
Hello John

Not succeed with your code. I think their is one error on

<<Private Sub StopProcess(pid)>>
Should be
<< Private Function StopProcess>>

Maybe i need to add some reference.

I download the code on http://www.thescarms.com/vbasic/stopprocess.aspx.

I'm not able yet to have it run to.

Did you succeeded to use it? will continu to look around your code.

Martin
Montreal, Canada
 
Upvote 0
Hello John

Not succeed with your code. I think their is one error on

<<Private Sub StopProcess(pid)>>
Should be
<< Private Function StopProcess>>

Maybe i need to add some reference.
No, nothing wrong with that. StopProcess needs the pid of the process you want to stop. It doesn't need to be a Function either. The Scarms code only works for one process so I've modified it to work for one or more processes.

The pid parameter is a Long and I've now changed the sub definition to: Private Sub StopProcess(pid As Long)

The following code in ThisWorkbook works for me. It starts and stops Calculator and Notepad.
Code:
Option Explicit

'Start applications using the Shell function and stop them.
'Based on http://www.thescarms.com/vbasic/stopprocess.aspx

Dim notepadPid As Long
Dim calcPid As Long


Private Sub Workbook_Open()
    notepadPid = Shell("C:\Windows\system32\notepad.exe", 1)
    calcPid = Shell("C:\Windows\system32\calc.exe", 1)
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    StopProcess notepadPid
    StopProcess calcPid
End Sub

Private Sub StopProcess(pid As Long)
    Dim i As Long
    '
    ' Enumerate all parent windows for the process to be stopped
    '
    Call fEnumWindows(pid)
    '
    ' Send a close command to each parent window.
    ' The app may issue a close confirmation dialog
    ' depending on how it handles the WM_CLOSE message.
    '
    'WM_CLOSE instructs the windows to close in their normal fashion as if you manually closed them.
    'The window may display a confirmation dialog depending on how it handles the close message.
    'To avoid being asked to confirm closing the window, you can send the WM_DESTROY command instead.
    
    For i = 1 To colHandle.Count
        Call SendMessage(colHandle.Item(i), WM_CLOSE, 0&, 0&)
    Next

End Sub
 
Upvote 0
Ok John, i will test it.

I will get back to you later in the day as i have to go

I'm shure i will succeed to implement that eventualy

Many Many thanks

Martin
 
Upvote 0
Hello again John

No go yet

2 things that i have in mind

- Need to had a reference
- No the same version. I use the French version of Office & Windows

Win Xp
Office 2007 French version

I opened a new clean worksheet and copy the code in the appropriate location. The workbook_Open work as it should. Both programs open normaly

On the Worbook_beforeClose. I got no notification of error, only a click from the bell. No error is displayed

My quest continu

Martin T.
Montreal, Canada
 
Upvote 0
Hello John

I have succeeded to put your code working for my application. I made these changes

PID' variables where defined as Public, Removed the Private definition for Sub only.

Many thanks again. I wish i could pay you a beer!


Martin

Code:
Public HypersnapPID As Long
Public Title_HLOCPID As Long
'
 
 Sub Workbook_BeforeClose(Cancel As Boolean)
    Sheets("Init_").Select
    ActiveSheet.Unprotect
    Application.ActivePrinter = Worksheets("Init_").RANGE("Printer_Name_adresse")
    ActiveSheet.Protect DrawingObjects:=False, Contents:=True, Scenarios:=True _
        , AllowFormattingRows:=False, AllowInsertingColumns:=False, _
        AllowInsertingRows:=False
    Sheets("Sat_Sheet").Select
    Application.OnKey "{F2}"
    Application.OnKey "{F3}"
    Application.OnKey "{F4}"
 
    ' Close the following applications
    MsgBox HypersnapPID & Title_HLOCPID
    StopProcess (HypersnapPID)
    StopProcess (Title_HLOCPID)
End Sub

Module

Code:
Public colHandle As New Collection
Public Const WM_CLOSE = &H10
Public Const WM_DESTROY = &H2
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Function fEnumWindowsCallBack(ByVal hwnd As Long, ByVal lpData As Long) As Long
    Dim lParent    As Long
    Dim lThreadId  As Long
    Dim lProcessId As Long
    '
    ' This callback function is called by Windows (from the EnumWindows
    ' API call) for EVERY top-level window that exists.  It populates a
    ' collection with the handles of all parent windows owned by the
    ' process that we started.
 
    ' The lpData argument is the process id of the window(s) to be closed.
 
    fEnumWindowsCallBack = 1
    lThreadId = GetWindowThreadProcessId(hwnd, lProcessId)
 
    If lpData = lProcessId Then
        lParent = GetParent(hwnd)
        If lParent = 0 Then
            colHandle.Add hwnd
        End If
    End If
End Function
 
Public Function fEnumWindows(ByVal pid As Long) As Boolean
    '
    ' The EnumWindows function enumerates all top-level windows
    ' by passing the handle of each window, in turn, to an
    ' application-defined callback function. EnumWindows
    ' continues until the last top-level window is enumerated or
    ' the callback function returns FALSE.
 
    ' The pid parameter passed to the fEnumWindowsCallBack function is
    ' the process id of the window(s) to be closed.
 
    Call EnumWindows(AddressOf fEnumWindowsCallBack, pid)
End Function
 
 
 
Sub StopProcess(pid As Long)
    Dim i As Long
    '
    ' Enumerate all parent windows for the process to be stopped
    '
    Call fEnumWindows(pid)
    '
    ' Send a close command to each parent window.
    ' The app may issue a close confirmation dialog
    ' depending on how it handles the WM_CLOSE message.
    '
    'WM_CLOSE instructs the windows to close in their normal fashion as if you manually closed them.
    'The window may display a confirmation dialog depending on how it handles the close message.
    'To avoid being asked to confirm closing the window, you can send the WM_DESTROY command instead.
 
    For i = 1 To colHandle.Count
        Call SendMessage(colHandle.Item(i), WM_CLOSE, 0&, 0&)
    Next
End Sub
 
Upvote 0

Forum statistics

Threads
1,213,534
Messages
6,114,184
Members
448,554
Latest member
Gleisner2

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