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 dencom on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to kill a task in VBA ? 1

Status
Not open for further replies.

nghiapp

Technical User
Dec 5, 2006
6
DK
In Excel VBA, I invoke a process to run in background. After finish, the process should be closed by setting to Nothing, but sometime it fails to close. I can go to the Task manager or use command line "Taskkill" to kill the process manually.
How can I check if it is closed and kill the process from inside the VBA ?
 
Without API you can create MS Word instance and use its Task object (in Tasks collection).

combo
 
you do not kill a process by setting it to nothing - you kill a process by using its native "Quit" command. Setting it to nothing simply releases the object from memory in VBA

Rgds, Geoff

We could learn a lot from crayons. Some are sharp, some are pretty and some are dull. Some have weird names and all are different colours but they all live in the same box.

Please read FAQ222-2244 before you ask a question
 
Thank for the input.
I tried to use the "quit" command just before setting the object to Nothing, but it did not work.
The object start with:
Set PvDbs = CreateObject(OleDbsObjName$)
where OleDbsObjName$ is provided by the other.
After finish working with the object, I closed the object by:
PvDbs.Quit
Set PvDBs=Nothing
I got the message "Run-time error 438. Object doesn't support this property or method" at line "PvDbs.Quit"
Is the "Quit" command a general command for any OLE object, or it should be defined by the provider of the object.
Please note that setting to "Nothing" normally works fine, but sometime it fails to close the object.
I'm looking for a API method where the input is process name like the input for command line "TaskKill"
Thanks
 
it should be defined by the object library of the task you are manipulating - if it doesn't have a "Quit" command, there should be something similar. Setting an object to nothing releases it from VBA memory only - it has nothing to do with whether a prcess is still live in the task manager

Rgds, Geoff

We could learn a lot from crayons. Some are sharp, some are pretty and some are dull. Some have weird names and all are different colours but they all live in the same box.

Please read FAQ222-2244 before you ask a question
 
Code:
Private Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded 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 Const PROCESS_TERMINATE = &H1
Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_READ = 16
Private Const MAX_PATH = 260

Private Sub Command1_Click()
   ' Cell A1:  iexplore.exe, firefox.exe, etc.
   Call Kill_Process(Sheets(1).Range("A1"))
End Sub

Private Sub Kill_Process(process_name As String)
   Dim Modules(1 To 200) As Long
   Dim ProcessIDs() As Long
   
   Dim hProcess As Long, cb As Long, cbNeeded As Long, NumElements As Long, cbNeeded2 As Long
   Dim i As Long, NumElements2 As Long, lRet As Long, nSize As Long, ExCode As Long
   Dim ModuleName As String

   List1.Clear

   cb = 8
   cbNeeded = 96

   Do While cb <= cbNeeded
      cb = cb * 2
      ReDim ProcessIDs(cb / 4) As Long
      lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
   Loop

   NumElements = cbNeeded / 4

   For i = 1 To NumElements
      hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ Or PROCESS_TERMINATE, 0, ProcessIDs(i))

      If hProcess <> 0 Then
          lRet = EnumProcessModules(hProcess, Modules(1), 200, cbNeeded2)
          
          If lRet <> 0 Then
             ModuleName = Space(MAX_PATH)
             nSize = 500
             lRet = GetModuleFileNameExA(hProcess, Modules(1), ModuleName, nSize)
             List1.AddItem ModuleName

             If InStr(1, UCase(Trim(ModuleName)), UCase(Trim(process_name))) <> 0 Then
                lRet = GetExitCodeProcess(hProcess, ExCode)
                lRet = TerminateProcess(hProcess, ExCode)
                
                MsgBox "Killed --> " & process_name
             End If
          End If
      End If
      
      lRet = CloseHandle(hProcess)
   Next
End Sub
 
Thank WinblowsMe,
That is what I 'm looking for. It works perfectly (after remove List1).
Regards
Nghia
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top