Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Closing External App 1

Status
Not open for further replies.

grnfvr

MIS
Dec 21, 2000
111
0
0
US
If someone knows specificaly how to close another application (one that my current app did NOT start), I would appreciate some help. I have a fundamental understanding of and a little experience with API calls. So let me have it.
 
You can try this. The only thing you must know is the nam,e in the title bar of the app you wanna shut down. Put this in here instaed of "name_in_apps_titlebar". It'll then find its handle and shut it down. It makes the program shut itself down rather than just killing it. Which is probably what you want in this case.

Declaration:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Code:

Dim winHwnd As Long
winHwnd = FindWindow(vbNullString, "name_in_apps_titlebar")
Debug.Print winHwnd
If winHwnd <> 0 Then
Call SendMessage(winHwnd, WM_CLOSE, 0, 0)
Debug.Print intRet
Else
MsgBox &quot;The app is not running.&quot;, vbOKOnly, &quot;Info:&quot;
End If

If anyone knows how to kill a program in its tracks like closing it from the task manager then I'd like to hear how!

Enjoy,

elziko
 
It says the FindWindow function/sub isn't defined.
Any ideas? Thanks
 
Yeah you havent defined findwindow:


Private Declare Function FindWindow Lib &quot;user32&quot; _
Alias &quot;FindWindowA&quot; (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
 
Add this declaration in after the SendMessage declaration then:

Private Declare Function FindWindow Lib &quot;user32&quot; Alias _
&quot;FindWindowA&quot; (ByVal lpClassName As String, ByVal _
lpWindowName As String) As Long

elziko
 
Ok it runs now, but don't think it's working.
I've got the exact name of the program from the title bar entered and when the vb prog is run it doesn't bring up the msg box, saying the prog can't be found - so it has found it - but just can't close it.
 
I have some code that I'll paste here that you can pass the EXE name to and it will close it. If there is multiple instances of the EXE running, you will need to loop through and close them all as this only closes one of them.

I have the code in two modules here is module 1:

Code:
Public Const MAX_PATH As Integer = 260

'** OpenHandle Constants.
Public Const PROCESS_QUERY_INFORMATION = 1024
Public Const PROCESS_VM_READ = 16
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const SYNCHRONIZE = &H100000

'** WaitForSingleObject Return Values.
Public Const WAIT_FAILED = &HFFFFFFFF
Public Const WAIT_OBJECT_0 = &H0
Public Const WAIT_TIMEOUT = &H102

'** API declarations.
Public Declare Function WaitForSingleObject Lib &quot;kernel32&quot; (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Public Declare Sub CloseHandle Lib &quot;kernel32.dll&quot; (ByVal hPass As Long)

Public Declare Function OpenProcess Lib &quot;kernel32.dll&quot; (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long

Public Declare Function EnumProcesses Lib &quot;psapi.dll&quot; (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long

Public Declare Function GetModuleBaseNameA Lib &quot;psapi.dll&quot; (ByVal lngProcessHandle As Long, ByVal lngModuleHandle As Long, ByVal strModuleName As String, ByVal lngSize As Long) As Long

Public Declare Function EnumProcessModules Lib &quot;psapi.dll&quot; (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib &quot;kernel32&quot; (ByVal hProcess As Long, ByVal uExitCode As Long) As Long

Public Function GetProcessHandle(strName As String) As Long
    

    'This Function accepts the name of the EXE (i.e. SomeProgram.exe) and scans
    'the process list for it. When it is found, the Process ID is returned. If
    'it is not found, then the function returns 0.

    Dim lngProcessID()  As Long
    Dim lngCB As Long
    Dim lngCBNeeded As Long
    Dim lngRetCode As Long
    Dim lngLoop As Long
    Dim lngProcessHandle As Long
    Dim strModuleName As String
    Dim strTemp() As String
    Dim lngModules(1 To 200) As Long
    Dim lngCbNeeded2 As Long
    Dim intTemp As Integer
    
    '** Get the current list of running Processes IDs
    '******************************************************************************
    lngCB = 8
    lngCBNeeded = 96
    Do While lngCB <= lngCBNeeded
        lngCB = lngCB * 2
        ReDim lngProcessIDs(lngCB / 4) As Long
        lngRetCode = EnumProcesses(lngProcessIDs(1), lngCB, lngCBNeeded)
        
        If lngRetCode = 0 Then
            MsgBox Err.LastDllError
            Exit Do
        End If
    Loop
    '******************************************************************************


    '** Get the name of the Base Module in each Process Space.
    '** NOTE : If you wanted to, you could also use the GetModuleBaseNameA API
    '**        to get every DLL and OCX loaded in the process space.
    '******************************************************************************
   
    For lngLoop = 1 To lngCBNeeded / 4
       'Get a handle to the Process
       lngProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION _
          Or PROCESS_VM_READ, 0, lngProcessIDs(lngLoop))
       'Got a Process handle
       If lngProcessHandle <> 0 Then
           'Get an array of the module handles for the specified
           'process
           lngRetCode = EnumProcessModules(lngProcessHandle, lngModules(1), 200, lngCbNeeded2)
           'If the Module Array is retrieved, Get the ModuleFileName
           If lngRetCode <> 0 Then
              strModuleName = Space(MAX_PATH)
              lngRetCode = GetModuleBaseNameA(lngProcessHandle, lngModules(1), strModuleName, 500)
              ReDim Preserve strTemp(intTemp)
              strTemp(intTemp) = Trim$(strModuleName)
              
            
              '** Check to see if the current process is the target process.
              If UCase$(Trim$(strModuleName)) = UCase$(Trim$(strName & Chr$(0))) Then
                GetProcessHandle = lngProcessIDs(lngLoop)
                Exit For
              End If
              
              intTemp = intTemp + 1
           End If
       End If
    Next lngLoop
    '******************************************************************************
End Function
[code]

Here is module 2:
[code]
'****************************
'For this module to work correctly, you must also inclue
'modGetProcessHandle.bas into your project


Option Explicit
'** OpenHandle Desired Access Constants.
Private Const PROCESS_TERMINATE = 1


'** Required APIs to terminate other functions.
Private Declare Function TerminateProcess Lib &quot;kernel32&quot; (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib &quot;kernel32&quot; (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Private Const PROCESS_ALL_ACCESS = &H1F0FFF

Public Function KillRunningProgram(EXEname As String) As Long

    Dim ProcHand As Long
    Dim PIDToKill As Long
    Dim lResult As Long
    
    ProcHand = GetProcessHandle(EXEname)
    
    If ProcHand = 0 Then
        KillRunningProgram = 0
        Exit Function
    End If
    
    PIDToKill = OpenProcess(PROCESS_TERMINATE, 0, ProcHand)
    KillRunningProgram = TerminateProcess(PIDToKill, 0)
        
End Function
[code]

You call it like this:

[code]

Dim RetValue As Long

RetValue = KillRunningProgram(&quot;Notepad.exe&quot;)

RetValue will be non-zero if the function succeeds and zero if the function fails or the application is not runnintg.

Hope this is what you want.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top