au3自删除的多种方法

相信很多弟兄都是做系统的,要写写au3脚本来进行任务调度,那么在任务调度以后,必然是需要对脚本进行自删除。现在简单作下归结。
常规的做法:

Run(@ComSpec&' /c ping 127.0.0.1 -n 3&del /q "'&@ScriptFullPath&'"',@ScriptDir,@SW_HIDE)

其实也可以写下面的方法:
在exit函数后面加个括号,里面写要执行的函数

Exit(FileDelete(@ScriptFullPath))

exit方式貌似在新版的au3中,编译以后存在一定问题。
另一个办法:

exit (run(@ComSpec & ' /c del/f/q "' & @ScriptFullPath & '"||del/f/q "' & @ScriptFullPath & '"||del/f/q "' & @ScriptFullPath & '"', @ScriptDir, @SW_HIDE))

au3中全局缩写文件里面已经集成了这样的一个函数
函数原型如下

Func _SelfDelete($iDelay = 0)
 ;ping的超时时间
 Local $sCmdFile
 FileDelete(@TempDir & "scratch.bat")
 $sCmdFile = 'ping -n ' & $iDelay & '127.0.0.1 > nul' & @CRLF _
 & ':loop' & @CRLF _
 & 'del "' & @ScriptFullPath & '" > nul' & @CRLF _
 & 'if exist "' & @ScriptFullPath & '" goto loop' & @CRLF _
 & 'del ' & @TempDir & 'scratch.bat'
 FileWrite(@TempDir & "scratch.bat", $sCmdFile)
 Run(@TempDir & "scratch.bat", @TempDir, @SW_HIDE)
EndFunc

在那个编辑器里面输入selfdelete按ctrl+b就出来啦

以下做剖析,里面涉及了cmd、进程、线程、编译等知识

(一)未编译脚本文件运行

脚本运行后被读入内存,脚本文件已不影响运行,可以任意地移动、改名和删除。
把以下内容保存为“1.au3”,先运行,然后移动、改名或删除它:

SplashTextOn("删除自身演示", "请把我的脚本文件移动、改名或删除", 200, 150, -1, -1, 4, "楷体_GB2312", 18)
While FileExists(@ScriptFullPath)
WEnd
For $i = 6 To 1 Step -1
 ControlSetText("删除自身演示", "", "Static1", "^_^ 验证成功" & @LF & @LF & "还有 " & $i&" 秒退出")
 Sleep(1000)
Next

所以,可用autoit自带FileDelete命令删除自身,并且此命令可放在任何位置,请演示以下脚本:

FileDelete(@ScriptFullPath)
If FileExists(@ScriptFullPath) Then
 $f = @ScriptName & "还好好的"
Else
 $f = @ScriptName & "已删除"
EndIf
MsgBox(1, "删除自身演示", $f)

(二)编译成exe文件运行

编译成exe文件后运行的话,因为文件本身在进程内,文件是无法删除的。如运行上面的第二个例子结果应该是“还好好的”。

所以编译成exe后,删除自身的话,只能在退出前启动其他进程,等原进程退出后再删除其文件。一般用cmd的del命令来删除的:

run('cmd /c ping 127.0.0.1 -n 3 & del /q/f/a "'& @ScriptFullPath & '"','',@SW_HIDE)

等待时间是2秒(-n 3是2个间隔),del应加上/a参数,确保删除带隐藏等属性的文件,此语句须放在代码结束位置或exit前。

但是这个命令有不完美之处,就是无法确保文件的删除。采取的办法是等了2秒进程还没退出,就强行终止进程,因为au3是单线程,运行到exit说明其他任务已结束,强行终止进程是没问题的,可以采取以下的命令实现:

run('cmd /c ping 127.0.0.1 -n 2 & taskkill /f /pid "'& @AutoItPID & '"& del /q/f/a "'& @ScriptFullPath & '"','',@SW_HIDE)

这个命令是确保了自身文件的删除,但exit语句不能执行其他的命令,且退出慢的话就强行结束终究不自然。写个bat文件执行后还要删除bat文件,麻烦不说而且不直观很难看懂,不推荐。

If Not @Compiled Then Exit MsgBox(0, "删除自身演示", "不编译会直接删除脚本文件,请编译后运行")
$p = Run('cmd /c for /l %i in (1,1,60) do ping 127.0.0.1 -n 2&del /q/f/a "' & @ScriptFullPath & '"& if not exist "' & @ScriptFullPath & '" exit', '', @SW_HIDE)
$e = MsgBox(1, "删除自身演示", "点确定删除自身文件,点取消直接退出")
If $e = 2 Then ProcessClose($p)

延时为60秒,删除命令可以放在脚本任何地方,当然建议放在最后,ping、cmd命令都耗cpu的,而且必须是结束进程后才能删除的,放在前面也没用,演示中的MsgBox放在后面是为了演示效果而放的。注意:cmd单行命令if后可执行多语句,用括号括起来就行,cmd单行命令是可以使用变量的

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容