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!

End a task from VB 6

Status
Not open for further replies.

russellbcopeland

Programmer
Apr 26, 2001
113
0
0
US
Does anyone know how to end a task from VB6?

I can get a list of all of the process running using the psapi and the tools calls in the kernel32 but cant seem to kill any of the process I find. I have tried sending a WM_CLOSE and TerminateProcess and have not been able to close any.

My end goal is to kill a task that I did not start.

Any ideas?

Thanks,
Russell
 
I use:

AppRunning = True
AppActivate "Calculator"
If AppRunning = True Then
SendKeys "%{F4}", True
AppWasTerminated = True
End If

Hope this helps.

Ralph
 
Thanks but tht wont do it in this case.. The process is an exe that runs as a process (probably an activeX server process). It has no window so I cant activate it and close it with a sendkeys... I wish it were that simple..
 
Under NT I'm afraid that TerminateProcess will not terminate a process that is running under a different security context than the security level of the user issuing the call.

One potential way around this is to get a duplicate handle to the process with termination rights, e.g something like the following:

Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_TERMINATE = &H1

lDesiredAccess = SYNCHRONIZE Or PROCESS_TERMINATE
hProc = OpenProcess(lDesiredAccess, 0&, ProcessID)
TerminateProcess hProc, 0&
 
If you're running WIN 4.0 or later this code will work:

Call like this:

KillRunningProgram("Calc.exe")



Add this to a module:
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 "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Public Declare Sub CloseHandle Lib "kernel32.dll" (ByVal hPass As Long)

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

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

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

Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" (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

Add this to another module:
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

You could consolidate them into one module if you wish.

Hope this works for you.

Brian
 
Thanks! That all worked.. The part I was missing was setting the PROCESS_TERMINATE in the openProcess call.

 
Brian,
Exellenct post, my complements. When I copied the code into the mods and tried the KillRunningProgram I keep erroring out stating &quot;Run-time error '424': Object required&quot; was there a reference that I need to make? Sorry for the stupidity but it will not let me debug
Thanks
Scoty ::) &quot;Learn from others' mistakes. You could not live long enough to make them all yourself.&quot;
-- Hyman George Rickover (1900-86),
 
Whoops,
Nevermind...Sorry bout that forgot to enclose my string with quotes. thanks heres a star
Scoty ::) &quot;Learn from others' mistakes. You could not live long enough to make them all yourself.&quot;
-- Hyman George Rickover (1900-86),
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top