Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


safely closing another application that is running programmatically

Posted on 2005-05-04
Medium Priority
Last Modified: 2012-06-27
I've two executables and i want exe1 to be able to close exe2.

I konw that if i made them ActiveX EXEs then i could use COM to just call a method in teh 2nd exe that would get it to exit - but i don't want them to be ActiveX EXEs.

Is there a way to safely close another program from code?

i.e. - i still want all the events to fire in exe2 that normally fire when a program exits when the user clicks the "x" - i don't just want to terminate the process (because its always working with an access db and i'm afraid that if exe1 just terminates the exe2's process - then that will cause database corruption).

is there a win32 api call i can use to cause exe2 to exit naturally?
Question by:kenshaw
  • 5
  • 3
LVL 35

Expert Comment

by:[ fanpages ]
ID: 13931173
Why not change your exe1 to write a record to a pre-defined table in the database, and have the exe2 monitor this same table for the existence of a record.

Once the record is read by exe2, it is deleted, and exe2 closes normally.




Author Comment

ID: 13931182
yeah i could do that... its just not very elegant - its not event based at all.

I wolud rather the code be clear that the second executable is exiting directly in response to an event in the first exe
LVL 35

Expert Comment

by:[ fanpages ]
ID: 13931264
The SendMessage API should do want you need, as long as you know the window handle of the exe you wish to close.

Is the .exe filename know to you, or does the Window always have the same caption?
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 35

Expert Comment

by:[ fanpages ]
ID: 13931305
LVL 35

Accepted Solution

[ fanpages ] earned 1500 total points
ID: 13931343
Another approach:

This set of functions determines if a window is open and if necessary closes that window. This is useful to avoid opening multiple instances of an application, especially if the application is a hidden background operation. To achieve this function, 5 windows API calls are employed to determine all open applications, check their identity and message these applications in order to issue a closedown call if required. The code below can be copied to a module and forms a complete working unit:
   Option Explicit
   Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
     (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
   Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
     (ByVal hwnd As Long, ByVal lpString As String, _
     ByVal aint As Long) As Long
   Declare Function GetWindow Lib "user32" _
     (ByVal hwnd As Long, ByVal wCmd As Long) As Long
   Declare Function EnumWindows Lib "user32" _
     (ByVal wndenmprc As Long, ByVal lParam As Long) As Long
   Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
     (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
     lParam As Any) As Long

   Private Const WM_CLOSE = &H10
   Private Const GW_HWNDFIRST = 0
   Private Const GW_HWNDLAST = 1
   Private Const GW_HWNDNEXT = 2
   Private Const GW_HWNDPREV = 3
   Private Const GW_OWNER = 4
   Private Const GW_CHILD = 5
   Private Const GW_MAX = 5

   Private mstrTarget As String
   Private mblnSuccess As Boolean

Public Function blnFindWindow(strApplicationTitle As String) As Boolean

   Dim hWndTmp As Long
   Dim nRet As Integer
   Dim TitleTmp As String
   Dim TitlePart As String
   Dim MyWholeTitle As String
   Dim mCounter As Long
   Dim hWndOver As Integer
   Dim sClassName As String * 100

   blnFindWindow = False

   TitlePart = UCase$(strApplicationTitle)

   'loop through all the open windows
   hWndTmp = FindWindow(0&, 0&)

   Do Until hWndTmp = 0

      TitleTmp = Space$(256)
      nRet = GetWindowText(hWndTmp, TitleTmp, Len(TitleTmp))

      If nRet Then
         'retrieve window title
         TitleTmp = UCase$(VBA.Left$(TitleTmp, nRet))
         'compare window title & strApplicationTitle
         If InStr(TitleTmp, TitlePart) Then
            blnFindWindow = True
            Exit Do
         End If
      End If

      hWndTmp = GetWindow(hWndTmp, GW_HWNDNEXT)
      mCounter = mCounter + 1


   End Function

Public Function blnCloseWindow(strApplicationTitle As String) As Boolean

   ' retrieve Windows list of tasks.
   mblnSuccess = False
   mstrTarget = strApplicationTitle
   EnumWindows AddressOf EnumCallback, 0
   blnCloseWindow = mblnSuccess

End Function

Public Function EnumCallback(ByVal app_hWnd As Long, _
  ByVal param As Long) As Long

   Dim buf As String * 256
   Dim title As String
   Dim length As Long

   ' Checks a returned task to determine if App should be closed

   ' get window's title.
   length = GetWindowText(app_hWnd, buf, Len(buf))
   title = Left$(buf, length)

   ' determine if target window.
   If InStr(UCase(title), UCase(mstrTarget)) <> 0 Then
      ' Kill window.
      SendMessage app_hWnd, WM_CLOSE, 0, 0
      mblnSuccess = True
   End If

   ' continue searching.
   EnumCallback = 1

End Function
The usage of these function is straight forward and fall into 2 parts: determining if a specific application is open and if necessary closing that application. The 2 function all are as follows:

   If blnFindWindow("Notepad") Then
       If Not blnCloseWindow("Notepad") Then
           MsgBox "Problems encountered closing Window", _
             vbInformation, "API Call"
           Exit Sub
       End If
   End If



Author Comment

ID: 13931363
i know the exe filename - and only one of the file can run at any time

Author Comment

ID: 13931367
actually - that last bit is wrong - i'm actually closing two exes (i.e. exe2 and exe3) and exe3 is an activeX  EXE with singleuse classes in it - so there could be multiple processes running of that executable - all with the same name... i want to get all of them to exit though
LVL 35

Expert Comment

by:[ fanpages ]
ID: 13931424
Try the link I posted above, [ http://www.thescarms.com/vbasic/StopProcess.asp ], for help with closing all executables that share the same filename.
LVL 23

Expert Comment

ID: 13931630
Take a look at this PAQ :


It basically is to do with finding any running processes with the exe name and you would need to modify the code however I am sure you could alter the code in this PAQ to suit your needs :)

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses
Course of the Month14 days, 2 hours left to enroll

581 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