Link to home
Start Free TrialLog in
Avatar of KingSencat
KingSencat

asked on

VB6.0 - How can i end a running proccess to my windows2000

Hello experts ..

I want to end a running proccess to my windows2000 using vb project .. i have a source that is work only on windowsXP , please if you know the source for the windows2000 pls help me!



thanks
ASKER CERTIFIED SOLUTION
Avatar of hes
hes
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of liviutudor
liviutudor

use a bit of API -- look at GetWindowThreadProcessID, OpenProcess and TerminateProcess. That's one way.
The other way is (API again) to send a WM_CLOSE message to the main window of your process. However, depending on the application, this might not close the app, but instead simply prompt the user whether s/he wants to exit/save work/etc. And of course, the second approach doesn't work if your process is a windowless process.
Here is a more simpler one.  Just copy and paste into a Class Module, say, Class1

Private Sub Command1_Click()
   
    Dim oTask As New Class1

    If oTask.IsProcessRunning("Calc.exe") Then
      oTask.EndProcess "Calc.exe"
    End If

End Sub


========================================================================================

'------------------------------------------------------------------
' MODULE  : clsTaskMan                                            '
' PURPOSE : Locate a specified window title and terminate it.     '
'           Or a specified program by its executable name.        '
'           Or a specified process by its process handle.         '
'------------------------------------------------------------------
Option Explicit

Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
    ByVal hwnd As Long, _
    ByVal nIndex As Long) As Long

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
    ByVal hwnd As Long, _
    ByVal wMsg As Long, _
    ByVal wParam As Long, _
    ByVal lParam As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As Any, _
    ByVal lpWindowName As String) As Long

' Constants for the ShowWindow API function
Const SW_HIDE = 0
Const SW_NORMAL = 1
Const SW_SHOWMINIMIZED = 2
Const SW_SHOWMAXIMIZED = 3
Const SW_SHOWNOACTIVATE = 4
Const SW_SHOW = 5
Const SW_MINIMIZE = 6
Const SW_SHOWMINNOACTIVE = 7
Const SW_SHOWNA = 8
Const SW_RESTORE = 9
Const SW_SHOWDEFAULT = 10
Const SW_FORCEMINIMIZE = 11

' Constants for the GetWindowLong and PostMessage API functions
Const GWL_STYLE = -16
Const WS_DISABLED = &H8000000
Const WM_CLOSE = &H10

' Constants for the CreateProcess API function
Const NORMAL_PRIORITY_CLASS = &H20&       'this is for the dwCreationFlags param
Const PROCESS_QUERY_INFORMATION = &H400   'this is for the lpProcessAttributes param
Const STARTF_USESHOWWINDOW = &H1          'this is for the STARTUPINFO structure's dwFlags member

'===========================================================================================================
Private Type STARTUPINFO
   lCb            As Long
   sReserved      As String
   sDesktop       As String
   sTitle         As String
   lX             As Long
   lY             As Long
   lXSize         As Long
   lYSize         As Long
   lXCountChars   As Long
   lYCountChars   As Long
   lFillAttribute As Long
   lFlags         As Long
   iShowWindow    As Integer
   iReserved2     As Integer
   lReserved2     As Long
   lStdInput      As Long
   lStdOutput     As Long
   lStdError      As Long
End Type

Private Type SECURITY_ATTRIBUTES
   nLength        As Long
   lpSecurityDescriptor As Long
   bInheritHandle As Boolean
End Type

Private Type PROCESS_INFO
   hProcess    As Long  'Handle to the newly created process
   hThread     As Long  'Handle to the primary thread of the newly created process
   dwProcessID As Long  'Global process identifier that can be used to identify a process
   dwThreadID  As Long  'Global thread identifiers that can be used to identify a thread
End Type

Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFO) As Long
'Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, ByVal lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFO) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
'===========================================================================================================

Dim m_bAutoKill      As Boolean  'automatically kill processes when main app exits
Dim m_sProcessName   As String   'process executable name
Dim m_lHandle        As Long     'current process handle
Dim m_lProcessID     As Long     'current process ID
Dim m_coProcHandles  As New Collection
Dim m_coProcByNames  As New Collection

Property Let AutoKillOnExit(pValue As Boolean)
 m_bAutoKill = pValue
End Property

Property Get AutoKillOnExit() As Boolean
 AutoKillOnExit = m_bAutoKill
End Property

Public Property Get ProcessCount() As Long
 ProcessCount = m_coProcHandles.Count
End Property

Public Property Get ProcessNames() As Collection
 Set ProcessNames = m_coProcByNames
End Property

Public Property Get CurrentProcessHandle() As Long
 CurrentProcessHandle = m_lHandle
End Property

Public Property Get CurrentProcessID() As Long
 CurrentProcessID = m_lProcessID
End Property

Public Property Get CurrentProcessName() As String
 CurrentProcessName = m_sProcessName
End Property

Public Function IsTaskRunning(sWindowTitle As String) As Boolean

 Dim hwnd As Long, hWndOffline As Long
 
 If Trim(sWindowTitle) = "" Then Exit Function
 
 On Error GoTo IsTaskRunning_Eh
 'get handle of the application
 'if handle is 0 the application is currently not running
 hwnd = FindWindow(0&, sWindowTitle)
 
 If hwnd = 0 Then
   IsTaskRunning = False
   Exit Function
 Else
   IsTaskRunning = True
 End If
 
IsTaskRunning_Exit:
 Exit Function

IsTaskRunning_Eh:
 Call ShowError(sWindowTitle, "IsTaskRunning")
   
End Function

Public Function EndTask(sWindowTitle As String) As Integer

 Dim x As Long, ReturnVal As Long, TargetHwnd As Long
 
 If Trim(sWindowTitle) = "" Then Exit Function
 
 'find handle of the application
 TargetHwnd = FindWindow(0&, sWindowTitle)
 If TargetHwnd = 0 Then Exit Function
 
 If IsWindow(TargetHwnd) = False Then
   GoTo EndTaskFail
 Else
   'close application
   If Not (GetWindowLong(TargetHwnd, GWL_STYLE) And WS_DISABLED) Then
      x = PostMessage(TargetHwnd, WM_CLOSE, 0, 0&)
      DoEvents
   End If
 End If
 
 GoTo EndTaskSucceed
 
EndTaskFail:
 ReturnVal = False
 Call ShowError("EndTask: cannot terminate " & sWindowTitle & " task", "EndTask()")
 GoTo EndTaskEndSub
 
EndTaskSucceed:
 ReturnVal = True
 
EndTaskEndSub:
 EndTask = ReturnVal
 
End Function

Public Function EndProcess(ByVal sExeName As String) As Boolean

 '*****************************************
 ' This method uses WMI rather than API   *
 ' to terminate all running instances of  *
 ' a specified programs by its executable *
 ' name on the local computer.            *
 ' -------------------------------------- *
 ' oTask.EndProcess("calc.exe")           *
 '*****************************************
 If Trim(sExeName) = "" Then Exit Function
 
 On Error GoTo Err_Handler
 
 Dim oProcessCollection, oProcess
 Set oProcessCollection = GetObject("WinMgmts:").InstancesOf("Win32_Process")
 
 For Each oProcess In oProcessCollection
   DoEvents
   If UCase(oProcess.Name) = UCase(sExeName) Then
      If oProcess.Terminate = 0 Then
         EndProcess = True
      End If
   End If
 Next
 
 Exit Function
Err_Handler:
 EndProcess = False
 
End Function

Public Function IsProcessRunning(ByVal sExeName As String) As Boolean

 '*****************************************
 ' This method uses WMI rather than API   *
 ' to get the current running status of   *
 ' a specified programs by its executable *
 ' name on the local computer.            *
 ' -------------------------------------- *
 ' oTask.IsProcessRunning("calc.exe")     *
 '*****************************************
 If Trim(sExeName) = "" Then Exit Function
 
 On Error GoTo Err_Handler
 
 Dim oProcessCollection, oProcess
 Set oProcessCollection = GetObject("WinMgmts:").InstancesOf("Win32_Process")
 
 For Each oProcess In oProcessCollection
   DoEvents
   If UCase(oProcess.Name) = UCase(sExeName) Then
      'IsProcessRunning = (oProcess.ExecutionState = 3)
      IsProcessRunning = Len(oProcess.Name)
   End If
 Next
 
 Exit Function
Err_Handler:
 IsProcessRunning = False
 
End Function

Private Function ShowError(sText As String, sProcName As String)

 'this function displays an error that occured
 Dim sMsg As String
 sMsg = "Error # " & Str(Err.Number) & " was generated by " _
         & Err.Source & vbCrLf & Err.Description
 MsgBox sMsg, vbCritical, sText & Space(1) & sProcName

End Function

'-- added 10/06/2005
'******************************************************
' Starts a new process and, if successful, returns    *
' the process handle to the calling procedure.        *
'******************************************************
Public Function StartProcess(ByVal sCmdLine As String) As Long

 On Error Resume Next
 
 Dim tProcA As SECURITY_ATTRIBUTES
 Dim tProcI As PROCESS_INFO
 Dim tStart As STARTUPINFO
 Dim lWork  As Long
 
 ' Initialize the SECURITY_ATTRIBUTES structure
 ' NOTE: As of now 10/13/2005, this doesn't work
 tProcA.nLength = Len(tProcA)
 tProcA.lpSecurityDescriptor = PROCESS_QUERY_INFORMATION
 tProcA.bInheritHandle = True
 
 ' Initialize the STARTUPINFO structure
 tStart.lCb = Len(tStart)
 tStart.lFlags = STARTF_USESHOWWINDOW
 tStart.iShowWindow = SW_SHOWNOACTIVATE
 
 ' Start the shelled application
 lWork = CreateProcessA(0&, sCmdLine, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, tStart, tProcI)
 'lWork = CreateProcessA(0&, sCmdLine, tProcA, 0&, 0&, NORMAL_PRIORITY_CLASS, 0&, 0&, tStart, tProcI)
 
 If lWork <> 0 Then     'A non-zero means successful
   m_lHandle = tProcI.hProcess
   m_lProcessID = tProcI.dwProcessID
   StartProcess = m_lHandle
   m_sProcessName = sCmdLine
   m_coProcHandles.Add m_lHandle, "H" & m_lHandle
   m_coProcByNames.Add sCmdLine, "N" & m_lHandle
 End If
 
 ' NOTE: As a results of the tests today (10/13/2005), this API
 '       call is no need. The CreateProcess() takes care of the
 '       shelled application just fine, except for only one app
 '       the Calc.exe doesn't seem to honor the SW_SHOWNOACTIVATE
 '       flag in both API functions.
 '*** lWork = ShowWindow(m_lHandle, SW_SHOWNOACTIVATE)
 
 ' NOTE: Don't close the handle here coz you'll make the
 '       process no longer valid for the TerminateProcess
 '       API function.
 '*** lWork = CloseHandle(tProcI.hProcess)

End Function

'-- added 10/06/2005
'******************************************************
' This function is used in conjunction with the above *
' function (StartProcess). It is used to terminate a  *
' a process specified by its unique process handle.   *
'******************************************************
Public Function KillProcess(Optional ByVal lProcessHandle As Long) As Boolean
 
 On Error Resume Next
 
 Dim lWork As Long
 Dim lExit As Long
 
 If lProcessHandle = 0 Then
   lProcessHandle = m_lHandle
 End If
 
 lWork = GetExitCodeProcess(lProcessHandle, lExit)
 
 lWork = TerminateProcess(lProcessHandle, lExit)
 
 If lWork <> 0 Then
   KillProcess = True
 End If
 
 m_coProcHandles.Remove "H" & lProcessHandle
 m_coProcByNames.Remove "N" & lProcessHandle
 
 If m_coProcHandles.Count > 0 Then
   m_lHandle = m_coProcHandles(m_coProcHandles.Count)
   m_sProcessName = m_coProcByNames(m_coProcByNames.Count)
 Else
   m_lHandle = 0
   m_sProcessName = ""
 End If
 
End Function

'-- added 10/13/2005
'*******************************************************
' This function is used in conjunction with the above  *
' function (StartProcess). Unlike the TerminateProcess *
' function, this function is used to end a process in  *
' a clean process shutdown fashion. It's the preferred *
' method of ending a process.                          *
'                                                      *
' NOTE: As of now 10/13/2005, this seems to terminate  *
' the entire application and VB when run from within   *
' the VB environment. I haven't tested it in EXE mode. *
' Anyway, the KillProcess works fine enough.           *
'*******************************************************
Public Sub CloseProcess(Optional ByVal lProcessHandle As Long)
 
 On Error Resume Next
 
 Dim lWork As Long
 Dim lExit As Long
 
 If lProcessHandle = 0 Then
   lProcessHandle = m_lHandle
 End If
 
 lWork = GetExitCodeProcess(lProcessHandle, lExit)
 
 Call ExitProcess(lExit)
 
 m_coProcHandles.Remove "H" & lProcessHandle
 m_coProcByNames.Remove "N" & lProcessHandle
 
 If m_coProcHandles.Count > 0 Then
   m_lHandle = m_coProcHandles(m_coProcHandles.Count)
   m_sProcessName = m_coProcByNames(m_coProcByNames.Count)
 Else
   m_lHandle = 0
   m_sProcessName = ""
 End If
 
End Sub

Private Sub Class_Initialize()
 ' For future codes
End Sub

Private Sub Class_Terminate()

 ' Terminate all running processes when
 ' the AutoKillOnExit property is set.
 If m_bAutoKill Then
   Do Until (ProcessCount = 0)
      DoEvents
      KillProcess
   Loop
 End If
 
End Sub

========================================================================================