Kill-N-Launch: Kill one app then Launch another
Posted: Sun Jul 30, 2006 12:02 am
The basis for this program can be found in this thread
The usage is detailed in the header section of the code.
This code is for 3.94 but to make it 4.0 simply remove the PROCESSENTRY32 Structure declaration.
The usage is detailed in the header section of the code.
This code is for 3.94 but to make it 4.0 simply remove the PROCESSENTRY32 Structure declaration.
Code: Select all
; Kill-N-Launch by Straker 7/29/2006
; Kills one process (usually the calling process) and launches another
;
; Used mainly to broker an updater process by killing the calling main app so that
; it can be overwritten by the called updater app. In other words, sometimes the
; main app exe is locked when the updater is a child process of the main app (when
; launched from the main app) preventing it from being overwritten by its child updater
; process. This exe should instead be called by the main app, so as to make sure it
; has been terminated before calling the updater app (which becomes a child process of
; this broker app instead of its parent main app).
;
; Includes code by oryaaaaa and Hi-Toro
; Inspiration by Xombie
;
; Compile as knl.exe
;
; usage: knl.exe -t apptokill.exe [-d millisecs ] [-l apptolaunch.exe [-a argument [-w working dir]]] [-v]
; ------------------------------------------------------------------------------------
; example: knl.exe -t mainapp.exe -d 3000 -l updater.exe -v
;
; This example will kill the passed process mainapp.exe identified by -t argument but
; will delay for 3 seconds (-d 3000) giving the mainapp.exe time to close itself. It
; will then launch the updater.exe specified by the -l argument.
;
; This app can be used 4 ways:
; 1) To just kill a process (-t) with no delay;
; 2) kill process with delay (-t and -d);
; 3) kill process then launch another app (-t and -l) with no delay;
; 4) kill process with delay then launch another app (-t and -d and -l).
;
; -a = The argument(s) if any for the app to launch (can use multiple times).
; -w = The working directory for the app to launch.
; -v = Verbose mode: show messageboxes.
; ------------------------------------------------------------------------------------
;
;- Globals and Enums
Global gDelay.l, gPID.l, gArgCount.l
Global gLaunch.b, gVerbose.b
Global gAppToLaunch.s, gAppToKill.s, gCommandParm.s, gAppName.s, gArgs.s, gWorkDir.s
#PROCESS_TERMINATE = $1
#PROCESS_CREATE_THREAD = $2
#PROCESS_VM_OPERATION = $8
#PROCESS_VM_READ = $10
#PROCESS_VM_WRITE = $20
#PROCESS_DUP_HANDLE = $40
#PROCESS_CREATE_PROCESS = $80
#PROCESS_SET_QUOTA = $100
#PROCESS_SET_INFORMATION = $200
#PROCESS_QUERY_INFORMATION = $400
#PROCESS_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | $FFF
;- Structures
Structure PROCESSENTRY32
dwSize.l
cntUsage.l
th32ProcessID.l
th32DefaultHeapID.l
th32ModuleID.l
cntThreads.l
th32ParentProcessID.l
pcPriClassBase.l
dwFlags.l
szExeFile.b [#MAX_PATH]
EndStructure
;- Procedures
Procedure.l CheckRunningExe(FileName.s)
; Original procedure by oryaaaaa
; modified by Straker to return PID instead of True/False
; returns 0 if process is not found running.
lReturnPid.l = 0
Protected snap.l , Proc32.PROCESSENTRY32 , dll_kernel32.l
FileName = GetFilePart( FileName )
dll_kernel32 = OpenLibrary (#PB_Any, "kernel32.dll")
If dll_kernel32
snap = CallFunction (dll_kernel32, "CreateToolhelp32Snapshot",$2, 0)
If snap
Proc32\dwSize = SizeOf (PROCESSENTRY32)
If CallFunction (dll_kernel32, "Process32First", snap, @Proc32)
While CallFunction (dll_kernel32, "Process32Next", snap, @Proc32)
If (UCase(PeekS (@Proc32\szExeFile))=UCase(FileName))
lReturnPid.l = PeekL (@Proc32\th32ProcessID)
Break
EndIf
Wend
EndIf
CloseHandle_ (snap)
EndIf
CloseLibrary (dll_kernel32)
EndIf
ProcedureReturn lReturnPid.l
EndProcedure
Procedure.b KillProcess(pid)
; Original procedure by Hi-Toro
result = #False
phandle = OpenProcess_(#PROCESS_TERMINATE, #False, pid)
If phandle <> #Null
If TerminateProcess_(phandle, 1)
result = #True
EndIf
CloseHandle_(phandle)
EndIf
ProcedureReturn result
EndProcedure
;- Program Initialization
gDelay.l = 0
gLaunch.b = #False
gVerbose.b = #False
gAppToLaunch.s = ""
gAppToKill.s = ""
gAppName.s = "Kill-N-Launch"
gArgCount.l = 0
gArgs.s = ""
gWorkDir.s = ""
lRetVal.l = 0
gCommandParm.s = ProgramParameter()
If (gCommandParm.s = "")
MessageRequester(gAppName.s,"Usage:"+Chr(13)+Chr(13)+"knl.exe -t apptokill.exe [-d millisecs ] [-l apptolaunch.exe [-a argument [-w working dir]]] [-v]")
Goto TheEnd
Else
While (gCommandParm.s <> "")
If (LCase(gCommandParm.s) = "-t")
; next argument is the app to kill
gCommandParm.s = ProgramParameter()
gAppToKill.s = Trim(gCommandParm.s)
EndIf
If (LCase(gCommandParm.s) = "-d")
; next argument is the delay milliseconds
gCommandParm.s = ProgramParameter()
gDelay.l = Val(gCommandParm.s)
EndIf
If (LCase(gCommandParm.s) = "-l")
; next argument is the app to launch
gCommandParm.s = ProgramParameter()
gAppToLaunch.s = Trim(gCommandParm.s)
gLaunch.b = #True
EndIf
If (LCase(gCommandParm.s) = "-v")
; set verbose flag
gVerbose.b = #True
EndIf
If (LCase(gCommandParm.s) = "-a")
; next argument is an argument for the App to Launch
gCommandParm.s = ProgramParameter()
gArgCount.l = (gArgCount.l + 1)
gArgs.s = (gArgs.s + " " + gCommandParm.s)
EndIf
If (LCase(gCommandParm.s) = "-w")
; next argument is the working dirctory for the App to Launch
gCommandParm.s = ProgramParameter()
gWorkDir.s = Trim(gCommandParm.s)
EndIf
gCommandParm.s = ProgramParameter()
Wend
EndIf
;- Main Loop
; --- Delay section...
If (gDelay.l > 0)
; user has specified a delay...
Delay(gDelay.l)
EndIf
; --- Kill process section...
gPID.l = CheckRunningExe(gAppToKill.s)
; Is the process still running?
If (gPID.l > 0)
; yep still running...hunt it down and kill it...
If (KillProcess(gPID.l)=#False)
; could not kill it...
If (gVerbose.b = #True)
MessageRequester(gAppName.s,"Unable to terminate process:"+Chr(13)+Chr(13)+Str(gPID.l)+" : " + gAppToKill.s)
EndIf
Goto TheEnd
EndIf
EndIf
; --- Launch app section...
If (gLaunch.b = #True)
If (FileSize(gAppToLaunch.s) > -1)
; found the file...try to launch it...
If (gArgCount.l > 0)
lRetVal.l = RunProgram(gAppToLaunch.s, gArgs.s, gWorkDir.s)
Else
lRetVal.l = RunProgram(gAppToLaunch.s)
EndIf
If (lRetVal.l = 0)
; could not launch
If (gVerbose.b = #True)
MessageRequester(gAppName.s,"Unable to launch application:"+Chr(13)+Chr(13)+gAppToLaunch.s)
EndIf
Goto TheEnd
EndIf
Else
If (gVerbose.b = #True)
MessageRequester(gAppName.s,"Unable to locate file to launch:"+Chr(13)+Chr(13)+gAppToLaunch.s)
EndIf
Goto TheEnd
EndIf
EndIf
Goto TheEnd
;- Cleanup and Exit
TheEnd:
End
; --- ### ---