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

How to close a program thru code 2

Status
Not open for further replies.

RollyS

Programmer
Jan 28, 2001
42
PH
I have two questions:

How do I terminate a program that I call (using Shell) in my code?

Also I would like to respond to the idleness of a system. For example, I would like to execute an external program when the computer has been idle, say for, 3 minutes.

Thanks
 
To kill another process, simply call the TerminateProcess API. This will terminate another process (assuming of course you have right to it). The API declaration follows . . .

Code:
Private Declare Function TerminateProcess Lib "kernel32" Alias "TerminateProcess" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long





To get some event to fire after 3 minutes, you have 2 options. You could simply add a timer control to a form and have that fire an event after 3 minutes. That would work . . .personally, I prefer the timer APIs . . . these allow you to have a timer callback without relying an a form being loaded. The API declarations follow . . .



Code:
Private Declare Function SetTimer Lib "user32" Alias "SetTimer" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

Private Declare Function KillTimer Lib "user32" Alias "KillTimer" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long



For the API to work,you will need a call back function and that funciton MUST reside in a bas module (The AddressOf function will not work for functions inside of objects i.e. forms and classes). Here is a sample of the Call Back function signature that you will need to implement . . .

Code:
Private Sub TimerProc(lngHandle as long, intMessage as Integer, intEventID as integer, dblTime as double)


That should be enough information to get you started, if you need any more help or if you need some examples, I'd be glad to post them.


- Jeff Marler B-)
 
Hi, jmarler.

API programming is really like nuclear physics to me. How about sharing me the running code of the one you just told me above?

Thanks.
 
Jeff,
You did not mention the process handle. In order to call terminateProcess you need the handle. I used this routine to shut down an error screen that the Adobe Acrobat print driver would throw up during a batch process. I used the FindWindow api to detect that the message had popped up. In this case our questioner is using the Shell command to start up an external processes. I know that Shell returns a number lngVar = shell("whatever") but I was not aware that was a process handle. Is that the case??
 
Shell returns a Process Handle, but you won't have rights to it. You need to use the OpenProcess API to generate a handle off of the handle returned by the Shell command. You will have rights to the handle that is returned by OpenProcess. I don't have time right now (sun is up and I'm going hiking) but I'll post exactly how to do all of this in about a day (unless someone else wants to beat me to the punch). - Jeff Marler B-)
 
OK, here is the code that will modify the handle returned by the Shell command and allow you to shut down another process. Hope this helps!


Code:
Option Explicit
Code:
'** OpenHandle Desired Access Constants.
Code:
Private Const PROCESS_TERMINATE = 1
Code:
'** Required APIs to terminate other functions.
Code:
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Code:
'** External Process Handle.
Code:
Private mlngProcessHandle As Long
Code:
Private Sub cmdCreate_Click()
Code:
Code:
    '** Here we shell out the other process and store the returned Process ID.
Code:
    mlngProcessHandle = Shell("C:\winnt40\system32\calc.exe", vbNormalFocus)
Code:
    '** Based on the original Process handle, we generate a new Process handle
    '** (but not a new process) that has terminate rights.
Code:
    mlngProcessHandle = OpenProcess(PROCESS_TERMINATE, 0, mlngProcessHandle)
Code:
End Sub
Code:
Code:
Private Sub cmdTerminate_Click()
Code:
    Dim lngExitCode As Long
Code:
    '** We Call Terminate Process with the process handle that has terminate rights.
    '** If the API return a 1, then the function completed without error.
Code:
    MsgBox TerminateProcess(mlngProcessHandle, lngExitCode)
Code:
End Sub[/B]

 - Jeff Marler B-)
 
Note that in the code above, for the TerminateProcess API to work, we had to generate our own ProcessHandle based on the original handle (using the OpenProcess API) and that the newly generate process Handle had to have Process_Terminate rights.
If you have any more question as to how or why this works, please feel free to post them!
- Jeff Marler B-)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top