Advertisement
Guest User

CShellProc.cls

a guest
Feb 14th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Option Explicit
  2.  
  3. ' APIs
  4. Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
  5. Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
  6. Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
  7. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  8. Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
  9. Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
  10.  
  11. ' process flags
  12. Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
  13. Private Const SYNCHRONIZE = &H100000
  14. Private Const PROCESS_QUERY_INFORMATION As Long = &H400
  15. Private Const PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF&)
  16.  
  17. ' invalid handle
  18. Private Const INVALID_HANDLE = &H0&
  19.  
  20. ' wait constants
  21. Private Const WAIT_OBJECT_0 = &H0&          ' wait terminated
  22. Private Const WAIT_TIMEOUT = &H102&         ' wait timed out
  23. Private Const WAIT_IO_COMPLETION = &HC0&    ' wait I/O completion port
  24. Private Const WAIT_ABANDONED = &H80&        ' wait failed, process aborted
  25. Private Const WAIT_FAILED = &HFFFFFFFF      ' wait failed, cannot wait handle
  26.  
  27. ' timeout for the Wait call
  28. Private Const WAIT_TIME = 11                ' use a prime number here ;-)
  29.  
  30. ' internal storage
  31. Private mvAppID         As Variant          ' application ID
  32. Private msCmdLine       As String           ' command line
  33. Private mdwPID          As Long             ' process ID
  34. Private mhProcHandle    As Long             ' process handle
  35. Private mlDLLerr        As Long             ' DLL error (GetLastError)
  36. Private mlExitCode      As Long             ' application exit code
  37.  
  38.  
  39. ' instance
  40. Private Sub Class_Initialize()
  41.   mdwPID = INVALID_HANDLE
  42.   mhProcHandle = INVALID_HANDLE
  43.   mlDLLerr = -1
  44.   mlExitCode = -1
  45.   mvAppID = -1
  46.   msCmdLine = sCmdLine
  47. End Sub
  48.  
  49. ' destroy
  50. Private Sub Class_Terminate()
  51.   If mhProcHandle <> INVALID_HANDLE Then
  52.     EndApp
  53.   End If
  54. End Sub
  55.  
  56. ' application ID
  57. Public Property Get AppID() As Variant
  58.   AppID = mvAppID
  59. End Property
  60.  
  61. ' command line
  62. Public Property Get CmdLine() As String
  63.   CmdLine = msCmdLine
  64. End Property
  65.  
  66. ' error number (if any)
  67. Public Property Get ErrNum() As Long
  68.   ErrNum = mlDLLerr
  69. End Property
  70.  
  71. ' application exit code
  72. Public Property Get ExitCode() As Long
  73.   ExitCode = mlExitCode
  74. End Property
  75.  
  76. ' starts the given app, returns true if started
  77. Public Function StartApp(ByVal vAppID As Variant, ByVal sCmdLine As String, Optional ByVal vStyle As VbAppWinStyle = vbNormalFocus) As Boolean
  78.   ' catch shell errors
  79.  On Local Error Resume Next
  80.  
  81.   ' initialize
  82.  StartApp = False
  83.   mdwPID = INVALID_HANDLE
  84.   mhProcHandle = INVALID_HANDLE
  85.   mlDLLerr = -1
  86.   mlExitCode = -1
  87.   bCancel = False
  88.  
  89.   ' store infos
  90.  mvAppID = vAppID
  91.   msCmdLine = sCmdLine
  92.  
  93.  
  94.   ' shell the program and get the PID
  95.  Err.Clear
  96.   mdwPID = Shell(sCmdLine, vStyle)
  97.   If Err.Number <> 0 Then
  98.     ' shell error, set values and return
  99.    mlDLLerr = Err.Number
  100.     mlExitCode = -1
  101.     Exit Function
  102.   End If
  103.  
  104.   If mdwPID <> INVALID_HANDLE Then
  105.     ' obtain a process handle from PIC
  106.    mhProcHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, mdwPID)
  107.     mlDLLerr = Err.LastDllError
  108.     If mhProcHandle = INVALID_HANDLE Then
  109.       Exit Function
  110.     End If
  111.   End If
  112.  
  113.   StartApp = True
  114. End Function
  115.  
  116. ' check if the started app is still running
  117. Public Function IsRunning() As Boolean
  118.   Dim lWait As Long, lRet As Long
  119.   Dim bRun As Boolean
  120.  
  121.   ' init
  122.  bRun = False
  123.   IsRunning = bRun
  124.  
  125.   ' check if we have a handle
  126.  If mhProcHandle = INVALID_HANDLE Then
  127.     ' not started !
  128.    Exit Function
  129.   End If
  130.  
  131.   ' run a quick check to see if the process is running
  132.  lWait = WaitForSingleObject(mhProcHandle, WAIT_TIME)
  133.   mlDLLerr = Err.LastDllError
  134.  
  135.   ' check the result
  136.  Select Case lWait
  137.     Case WAIT_OBJECT_0
  138.       ' process terminated
  139.      lRet = GetExitCodeProcess(mhProcHandle, mlExitCode)
  140.       If lRet = 0 Then
  141.         mlExitCode = -1
  142.         mlDLLerr = Err.LastDllError
  143.       End If
  144.       bRun = False
  145.     Case WAIT_TIMEOUT
  146.       ' timed out, still running
  147.      bRun = True
  148.     Case Else
  149.       ' error
  150.      If mlDLLerr = 0 Then
  151.         mlDLLerr = lWait
  152.       End If
  153.       mlExitCode = -1
  154.       bRun = False
  155.   End Select
  156.  
  157.   If bRun = False Then
  158.     ' not running, cleanup
  159.    EndApp
  160.   End If
  161.  
  162.   ' true if running
  163.  IsRunning = bRun
  164. End Function
  165.  
  166. ' started process terminated (or must be killed)
  167. Public Sub EndApp(ByVal bKill As Boolean)
  168.   ' do we have a process handle ?
  169.  If mhProcHandle = INVALID_HANDLE Then
  170.     Exit Sub
  171.   End If
  172.  
  173.   ' are we asked to KILL the process ?
  174.  If bKill Then
  175.     Call TerminateProcess(mhProcHandle, -1&)
  176.     If Err.LastDllError <> 0 Then
  177.       mlDLLerr = Err.LastDllError
  178.     End If
  179.   End If
  180.  
  181.   ' cleanup
  182.  Call CloseHandle(mhProcHandle)
  183.   mhProcHandle = INVALID_HANDLE
  184.   mdwPID = INVALID_HANDLE
  185. End Function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement