The version I updated includes the ability to monitor when the process is closed and/or the timer is reached, therefore if an error was to occur with your program and the _SelfDelete() function was called before, it will still delete the executable even with an AutoIt error (due to bad coding of course!) This can't be said for the old version of _SelfDelete() as you'll never have chance to call the function! I also included the option to check either the process name or PID, depending on your preference. Thanks.
Function: Using a Batch script. Save as _SelfDelete.au3
#include-once #include <Constants.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _SelfDelete ; Description ...: Delete the current executable after it's finished processing and/or the timer has been reached. ; Syntax ........: _SelfDelete([$iDelay = 5[, $fUsePID = False[, $fRemoveDir = False]]]) ; Parameters ....: $iDelay - [optional] An integer value for the delay to wait (in seconds) before stopping the process and deleting the executable. ; If 0 is specified then the batch will wait indefinitely until the process no longer exits. Default is 5 (seconds). ; $fUsePID - [optional] Use the process name (False) or PID (True). Default is False. ; $fRemoveDir - [optional] Remove the script directory as well (True) or only the running executable (False). Default is False. ; Return values .: Success - Returns the PID of the batch file. ; Failure - Returns 0 & sets @error to non-zero ; Author ........: guinness ; Modified ......: ; Remarks .......: The idea for removing the directory came from: http://www.autoitscript.com/forum/topic/137287-delete-scriptdir/ ; Example .......: Yes ; =============================================================================================================================== Func _SelfDelete($iDelay = 5, $fUsePID = Default, $fRemoveDir = Default) If @Compiled = 0 Then Return SetError(1, 0, 0) EndIf Local Const $STR_NOCASESENSEBASIC = 2 Local $sTempFileName = @ScriptName $sTempFileName = StringLeft($sTempFileName, StringInStr($sTempFileName, '.', $STR_NOCASESENSEBASIC, -1) - 1) While FileExists(@TempDir & '\' & $sTempFileName & '.bat') $sTempFileName &= Chr(Random(65, 122, 1)) WEnd $sTempFileName = @TempDir & '\' & $sTempFileName & '.bat' $iDelay = Int($iDelay) Local $sDelay = '' If $iDelay > 0 Then $sDelay = 'IF %TIMER% GTR ' & $iDelay & ' GOTO DELETE' EndIf Local $sRemoveDir = '' If $fRemoveDir Then $sRemoveDir = 'RD /S /Q "' & FileGetShortName(@ScriptDir) & '"' & @CRLF EndIf Local $sAppID = @ScriptName, $sImageName = 'IMAGENAME' If $fUsePID Then $sAppID = @AutoItPID $sImageName = 'PID' EndIf Local Const $iInternalDelay = 2, _ $sScriptPath = FileGetShortName(@ScriptFullPath) Local Const $sData = 'SET TIMER=0' & @CRLF _ & ':START' & @CRLF _ & 'PING -n ' & $iInternalDelay & ' 127.0.0.1 > nul' & @CRLF _ & $sDelay & @CRLF _ & 'SET /A TIMER+=1' & @CRLF _ & @CRLF _ & 'TASKLIST /NH /FI "' & $sImageName & ' EQ ' & $sAppID & '" | FIND /I "' & $sAppID & '" >nul && GOTO START' & @CRLF _ & 'GOTO DELETE' & @CRLF _ & @CRLF _ & ':DELETE' & @CRLF _ & 'TASKKILL /F /FI "' & $sImageName & ' EQ ' & $sAppID & '"' & @CRLF _ & 'DEL "' & $sScriptPath & '"' & @CRLF _ & 'IF EXIST "' & $sScriptPath & '" GOTO DELETE' & @CRLF _ & $sRemoveDir _ & 'GOTO END' & @CRLF _ & @CRLF _ & ':END' & @CRLF _ & 'DEL "' & $sTempFileName & '"' Local Const $hFileOpen = FileOpen($sTempFileName, $FO_OVERWRITE) If $hFileOpen = -1 Then Return SetError(2, 0, 0) EndIf FileWrite($hFileOpen, $sData) FileClose($hFileOpen) Return Run($sTempFileName, @TempDir, @SW_HIDE) EndFunc ;==>_SelfDelete
Function: Using a VBScript file. Save as _SelfDelete.au3
#include-once #include <Constants.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _SelfDelete ; Description ...: Delete the current executable after it's finished processing and/or the timer has been reached. ; Syntax ........: _SelfDelete([$iDelay = 5[, $fUsePID = False[, $fRemoveDir = False]]]) ; Parameters ....: $iDelay - [optional] An integer value for the delay to wait (in seconds) before stopping the process and deleting the executable. ; If 0 is specified then the script will wait indefinitely until the process no longer exits. Default is 5 (seconds). ; $fUsePID - [optional] Use the process name (False) or PID (True). Default is False. ; $fRemoveDir - [optional] Remove the script directory as well (True) or only the running executable (False). Default is False. ; Return values .: Success - Returns True. ; Failure - Returns False & sets @error to non-zero ; Author ........: guinness ; Modified ......: ; Remarks .......: The idea for removing the directory came from: http://www.autoitscript.com/forum/topic/137287-delete-scriptdir/ ; Example .......: Yes ; =============================================================================================================================== Func _SelfDelete($iDelay = 5, $fUsePID = Default, $fRemoveDir = Default) If @Compiled = 0 Then Return SetError(1, 0, False) EndIf Local Const $STR_NOCASESENSEBASIC = 2 Local $sTempFileName = @ScriptName $sTempFileName = StringLeft($sTempFileName, StringInStr($sTempFileName, '.', $STR_NOCASESENSEBASIC, -1) - 1) While FileExists(@TempDir & '\' & $sTempFileName & '.bat') $sTempFileName &= Chr(Random(65, 122, 1)) WEnd $sTempFileName = @TempDir & '\' & $sTempFileName & '.vbs' $iDelay = Int($iDelay) Local $sDelay = '' If $iDelay > 0 Then $sDelay = @TAB & 'iTimeOut = iTimeOut + 1' & @CRLF _ & @TAB & 'If iTimeOut > ' & $iDelay & ' Then' & @CRLF _ & @TAB & @TAB & 'For Each oProcess in oWMIQuery' & @CRLF _ & @TAB & @TAB & @TAB & 'oProcess.Terminate()' & @CRLF _ & @TAB & @TAB & 'Next' & @CRLF _ & @TAB & @TAB & 'iExit = 2' & @CRLF _ & @TAB & 'End If' & @CRLF EndIf Local $sRemoveDir = '' If $fRemoveDir Then $sRemoveDir = 'oFileSystem.DeleteFolder "' & @ScriptDir & '", True' & @CRLF EndIf Local $sAppID = @ScriptName, $sImageName = 'Name' If $fUsePID Then $sAppID = @AutoItPID $sImageName = 'ProcessId' EndIf Local Const $iInternalDelay = 10, _ $sScriptPath = @ScriptFullPath Local Const $sData = 'Option Explicit' & @CRLF _ & 'Dim iExit, iTimeOut, oFileSystem, oProcess, oWMIQuery, oWMIService, sComputer, sFilePath, sWMIQuery' & @CRLF _ & @CRLF _ & 'sFilePath = "' & $sScriptPath & '"' & @CRLF _ & @CRLF _ & 'iExit = 0' & @CRLF _ & 'iTimeOut = 0' & @CRLF _ & 'sComputer = "."' & @CRLF _ & @CRLF _ & 'Set oWMIService = GetObject("winmgmts:" _' & @CRLF _ & @TAB & @TAB & '& "{impersonationLevel=impersonate}!\\" _' & @CRLF _ & @TAB & @TAB & '& sComputer & "\root\cimv2")' & @CRLF _ & @CRLF _ & 'sWMIQuery = "Select * From Win32_Process Where ' & $sImageName & ' = ''' & $sAppID & '''"' & @CRLF _ & @CRLF _ & 'While (iExit = 0)' & @CRLF _ & @TAB & 'Set oWMIQuery = oWMIService.ExecQuery(sWMIQuery)' & @CRLF _ & @TAB & 'If oWMIQuery.Count = 0 Then' & @CRLF _ & @TAB & @TAB & 'iExit = 1' & @CRLF _ & @TAB & 'End If' & @CRLF _ & @TAB & 'WScript.Sleep(1000)' & @CRLF _ & $sDelay _ & 'Wend' & @CRLF _ & @CRLF _ & 'WScript.Sleep(1000)' & @CRLF _ & 'iExit = 0' & @CRLF _ & 'iTimeOut = 0' & @CRLF _ & 'Set oFileSystem = CreateObject("Scripting.FileSystemObject")' & @CRLF _ & 'While (iExit = 0)' & @CRLF _ & @TAB & 'iTimeOut = iTimeOut + 1' & @CRLF _ & @TAB & 'If oFileSystem.FileExists(sFilePath) Then' & @CRLF _ & @TAB & @TAB & 'oFileSystem.DeleteFile sFilePath, True' & @CRLF _ & @TAB & 'End If' & @CRLF _ & @TAB & 'If oFileSystem.FileExists(sFilePath) <> True Then' & @CRLF _ & @TAB & @TAB & 'iExit = 1' & @CRLF _ & @TAB & 'End If' & @CRLF _ & @TAB & 'If iTimeOut > ' & $iInternalDelay & ' Then' & @CRLF _ & @TAB & @TAB & 'iExit = 2' & @CRLF _ & @TAB & 'End If' & @CRLF _ & 'Wend' & @CRLF _ & @CRLF _ & $sRemoveDir _ & 'oFileSystem.DeleteFile WScript.ScriptFullName, True' & @CRLF _ Local Const $hFileOpen = FileOpen($sTempFileName, $FO_OVERWRITE) If $hFileOpen = -1 Then Return SetError(2, 0, False) EndIf FileWrite($hFileOpen, $sData) FileClose($hFileOpen) Return ShellExecute($sTempFileName, @TempDir, @TempDir, '', @SW_HIDE) = 1 EndFunc ;==>_SelfDelete
Example use of Function:
#include <Constants.au3> #include '_SelfDelete.au3' _SelfDelete(30, 0) ; Start the SelfDelete batch file with a 30 second timer and using the prcocess name rather than the PID. If @error Then Exit MsgBox($MB_SYSTEMMODAL, '_SelfDelete()', 'The script must be a compiled exe to work correctly.') ; Display a warning if the script isn't compiled. EndIf While 1 Sleep(100) ; Wait or manually close the application via the traymenu icon. WEnd
Edited by guinness, 05 April 2013 - 05:50 AM.




