 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Srinath Guest
|
Posted: Tue Nov 13, 2007 12:54 pm Post subject: Self-Delete code that does not work on some computers |
|
|
Whilst browsing through this forum for a code that would allow me to self-delete an exe compiled file, I came across this code (given below) from here posted by user Skan.
Code -
| Code: | If A_IsCompiled {
FileSetAttrib, -R-A-S-H-N-O-T, %A_ScriptFullPath%
FileDelete, %A_Temp%\selfDelete.VBS
FileAppend,
(
Wscript.Sleep 2000
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.GetFile("%A_ScriptFullPath%")
MyFile.Delete
'Delete the currently executing script
Dim objFSO 'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile WScript.ScriptFullName
Set objFSO = Nothing
)
, %A_Temp%\selfDelete.VBS
Run, %A_Temp%\selfDelete.VBS
ExitApp
} |
I used the above code and it worked perfectly when I was experimenting with it at home until I tried it on another computer and it did not function as intended.
It gave an error message that said – Loading script “C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\selfDelete.VBS” failed (Access is denied.).
The WinTitle of this error message was – Windows Script Host
Subsequently I tried this same code on quite a few computers and found that it worked on a few computers and did not work on some.
Can anyone decipher the error message given above and perhaps modify the code so that it can work on all computers or is there any other better code that can get the job done.
P.S. – Also in the same post from where I picked up this code it seems that user Freddie also had had some error messages thrown in. His error messages seem quite similar to the one that I am getting (though I could be mistaken). It would be great if one you better coders could figure out why this code does not work on some computers. I feel this code that Skan has compiled is truly great but somehow becomes amiss at times. |
|
| Back to top |
|
 |
Loriss
Joined: 26 Jul 2004 Posts: 64
|
Posted: Tue Nov 13, 2007 2:00 pm Post subject: |
|
|
This is the better and simple File Autodelete.
| Code: | Run, %comspec% /c del "%a_scriptname%",,hide
exit |
Exit is necessary , If Not , file do not autodelete. _________________ Loriss |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6264
|
Posted: Tue Nov 13, 2007 2:40 pm Post subject: |
|
|
Try including a small delay between creation and execution of WSH:
| Code: | If A_IsCompiled {
FileSetAttrib, -R-A-S-H-N-O-T, %A_ScriptFullPath%
FileDelete, %A_Temp%\selfDelete.VBS
FileAppend,
(
Wscript.Sleep 500
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.GetFile("%A_ScriptFullPath%")
MyFile.Delete
'Delete the currently executing script
Dim objFSO 'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile WScript.ScriptFullName
Set objFSO = Nothing
)
, %A_Temp%\selfDelete.VBS
Sleep 50
Run, %A_Temp%\selfDelete.VBS
ExitApp
} |
 |
|
| Back to top |
|
 |
Srinath Guest
|
Posted: Thu Nov 15, 2007 1:48 pm Post subject: |
|
|
As suggested by Skan, I tried this code with the delay modification. I added the delay value as Sleep 2000 instead of Sleep 50 (as suggested by Skan) for enhanced measure. When I ran it on one of the computers on which this code did not work previously, unfortunately it resulted in the same output. I got the same error message as before - Loading script “C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\selfDelete.VBS” failed (Access is denied.).
Then I manually erased the selfDelete.VBS file from the Temp directory (assuming that perhaps the existence of this file, which might have been created earlier, wasn’t allowing the new code to work) and re-ran this exe file but got the same result.
Whereas the code given by Loris also seems to work on its own, it did not work when I combined it with another code. After browsing through this forum I have put together a code, which worked perfectly till I started getting this error message given above. The code I have compiled is –
| Code: | SetTerminate:
FormatTime, PartialDate,, yyyyMMddHHmmss
EndTime = 20071115163000
TimeLeft := EndTime - PartialDate
If TimeLeft < 0
If A_IsCompiled {
FileSetAttrib, -R-A-S-H-N-O-T, %A_ScriptFullPath%
FileDelete, %A_Temp%\selfDelete.VBS
FileAppend,
(
Wscript.Sleep 2000
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.GetFile("%A_ScriptFullPath%")
MyFile.Delete
'Delete the currently executing script
Dim objFSO 'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile WScript.ScriptFullName
Set objFSO = Nothing
)
, %A_Temp%\selfDelete.VBS
Sleep 2000
Run, %A_Temp%\selfDelete.VBS
ExitApp
}
{
RegRead, RunOk, HKEY_LOCAL_MACHINE, Software\Microsoft\GroupFiles, Strata_4598
If (ErrorLevel)
ExitApp
Return
} |
The code given above does three things – namely –
The code in blue allows me to set an expiration date till when this exe file must run. In the example given above, the exe file will run okay till 4:00pm on 15/Nov/2007. If this file is run after 4:00pm on 15/Nov/2007, the code in red will take over and self-delete the exe file.
This code works exactly as intended except that on some computers the self-delete code in red goofs-up. (The reason why I initiated this post)…
The code given in brown is something I added for extra measure. Using another exe file, I first insert some information in the Registry (in this case GroupFiles, Strata_4598) and the exe file will function only if it reads this information in the Registry.
When I tried the above using the code given by Loris, it just did not work. The code I used for the same is –
| Code: | SetTerminate:
FormatTime, PartialDate,, yyyyMMddHHmmss
EndTime = 20071115163000
TimeLeft := EndTime - PartialDate
If TimeLeft < 0
If A_IsCompiled {
Run, %comspec% /c del "%a_scriptname%",,hide
Exit
}
{
RegRead, RunOk, HKEY_LOCAL_MACHINE, Software\Microsoft\GroupFiles, Strata_4598
If (ErrorLevel)
ExitApp
Return
} |
Can anyone think of a way whereby I can make the above work as intended, even if I need to use another self-delete code? Personally I truly like the code given by Skan as it can make a running exe file self-delete, except that it has it’s glitches on some computers. |
|
| Back to top |
|
 |
Loriss
Joined: 26 Jul 2004 Posts: 64
|
Posted: Thu Nov 15, 2007 5:51 pm Post subject: |
|
|
| Code: | SetTerminate:
FormatTime, PartialDate,, yyyyMMddHHmmss
EndTime = 20071115163000
TimeLeft := EndTime - PartialDate
If TimeLeft < 0
;---------------------no code under tis line-------------
Run, %comspec% /c del "%a_scriptname%",,hide
Exitapp
|
Compile in this way , and tray. _________________ Loriss |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Fri Nov 16, 2007 11:29 am Post subject: |
|
|
Using del that way will always be a "race condition" -- sometimes del might run first, resulting in "Access is denied", or it might run after the script exits. One way to increase the likelihood that the script will exit first is to raise the script's priority before calling Run: | Code: | | Process, Priority,, H | This will not provide 100% reliability.
The VBS method is for now the most reliable. Perhaps the Windows Script Host is somehow running in a user other than the current one - i.e. one that does not have access to the current user's Temp directory. You could try writing the script to somewhere that all users have read/execute access to.
If you can't get VBS to work, perhaps you'd have better luck with a batch file (.bat).
Edit: Here's one way that should be reliable:
| Code: | FileDelete, %A_Temp%\~del%A_ScriptName%.bat
Process, Exist
FileAppend,
(
taskkill /PID %ErrorLevel%
del %A_ScriptFullPath%
del %A_Temp%\~del%A_ScriptName%.bat
), %A_Temp%\~del%A_ScriptName%.bat
Run, %A_Temp%\~del%A_ScriptName%.bat,, Hide
ExitApp | Taskkill should ensure the script is closed before attempting to delete it.
Edit2: I just discovered &&
| Code: | Process, Exist
RunWait, %comspec% /c taskkill /PID %ErrorLevel% && del %A_ScriptFullPath%,, hide | This removes the need for a temporary batch file. RunWait should be used to ensure the script doesn't exit until taskkill terminates it, otherwise taskkill would fail and del would not be executed. |
|
| Back to top |
|
 |
Srinath Guest
|
Posted: Sat Nov 17, 2007 12:44 pm Post subject: |
|
|
Lexikos said –
| Quote: | | The VBS method is for now the most reliable. Perhaps the Windows Script Host is somehow running in a user other than the current one - i.e. one that does not have access to the current user's Temp directory. You could try writing the script to somewhere that all users have read/execute access to. |
From the above - The VBS method is for now the most reliable – I think I tend to agree. Not only does this script (given by Skan) effectively delete the file but is the only one that works in tandem with the other two codes that I have given above on 15/Nov/2007 in blue and brown. The problem with the other codes given by Loris and Lexikos is that the code in brown does not work in tandem with the entirety of the intended script. Sure it will delete when the expiration date (as set by the code in blue) is reached but it will work even if there is no registry entry thereby making the code in brown redundant.
Given my limited knowledge with coding and AHK, I had blindly copied the code given by Skan. Thereafter, after trying to decipher the script upon reading Lexikos’s view on the same (Perhaps the Windows Script Host is somehow running in a user other than the current one - i.e. one that does not have access to the current user's Temp directory. You could try writing the script to somewhere that all users have read/execute access to.), I have come up with the following modification of Skan’s original code.
| Code: | If A_IsCompiled {
FileSetAttrib, -R-A-S-H-N-O-T, %A_ScriptFullPath%
FileDelete, %A_Temp%\selfDelete.VBS
FileAppend,
(
Wscript.Sleep 2000
Dim fso, MyFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.GetFile("%A_ScriptFullPath%")
MyFile.Delete
'Delete the currently executing script
Dim objFSO 'Create a File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile WScript.ScriptFullName
Set objFSO = Nothing
)
, %A_WorkingDir%\selfDelete.VBS
Sleep 2000
Run, %A_WorkingDir%\selfDelete.VBS
;substituted %A_Temp% with %A_WorkingDir%
ExitApp
} |
The above is obviously under the assumption that if the script does not have access to the current user's Temp directory (as highlighted by Lexikos), if I were to set the VBS file to function in the Working Directory then it should have 100% access to this directory thereby making this script supposedly flawless. This is perceptibly on the theory that if the user has access to the Directory where the exe exists, which will be self-deleted, the directory would also be available for the code to run the VBS file and work as intended. The only thing is that the person who is accessing the exe file which will be self-deleted can see the VBS file in action but I reckon that is okay. Another idea I had was to perhaps give the script directive to operate in the root of the C Drive (C:\) as every user logged into the computer would / should have access to the C Drive, but I could not figure out the code for the same.
If anyone knows otherwise or feels that the above code is still susceptible to any flaws, I would appreciate any modification / guidance for the same. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sat Nov 17, 2007 1:22 pm Post subject: |
|
|
| Srinath wrote: | | The problem with the other codes given by Loris and Lexikos is that the code in brown does not work in tandem with the entirety of the intended script. Sure it will delete when the expiration date (as set by the code in blue) is reached but it will work even if there is no registry entry thereby making the code in brown redundant. | Sounds like you're missing some { braces }. Braces define what code belongs to an if, else, loop, etc. and without them, only the next line (and its associated line/block, if applicable) will belong to the if/else/loop. For instance, in the code Loriss posted... | Code: | If TimeLeft < 0
;---------------------no code under tis line-------------
Run, %comspec% /c del "%a_scriptname%",,hide
Exitapp | ...it may not be clear, but "ExitApp" will be called regardless of whether TimeLeft < 0. I'm not sure whether that was the intention in this particular case, which is all the more reason to indent for clarity: | Code: | If TimeLeft < 0
Run, %comspec% /c del "%a_scriptname%",,hide
Exitapp | or use braces (to change the behaviour): | Code: | If TimeLeft < 0
{
Run, %comspec% /c del "%a_scriptname%",,hide
Exitapp
} |
Of course, I still recommend something like: | Code: | If TimeLeft < 0
{
Process, Exist
RunWait, %comspec% /c taskkill /PID %ErrorLevel% && del %A_ScriptFullPath%,, hide
ExitApp
} |
|
|
| Back to top |
|
 |
Srinath Guest
|
Posted: Sat Nov 17, 2007 2:16 pm Post subject: |
|
|
Hmm! This does seem interesting and I will try it out. If this code is more dependable than the VBS one given by Skan then I reckon I will use this one. There is only one thing I forgot to previously mention. Using the code that Skan has given the file would self delete only if it is a compiled exe file and not when it is in .ahk mode. I think the line If A_IsCompiled takes care of that. If it is possible with the new code, ideally that is how I would like it to be so that whilst editing the file in ahk mode, I do not inadvertently delete it.
Can a reworked code be posted that can include this option. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2739 Location: Australia, Qld
|
Posted: Sat Nov 17, 2007 11:34 pm Post subject: |
|
|
| Code: | If TimeLeft < 0
{
Process, Exist
if A_IsCompiled
RunWait, %comspec% /c taskkill /PID %ErrorLevel% && del %A_ScriptFullPath%,, hide
ExitApp
} | Too simple.  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|