你好:

     感谢你访问我的 Blog ,本博客只提供博主的技术经验分享,你可以在此做简单的留言和评论,我会抽空回复你;若是要深入交流探讨,请联系QQ:47853253或者加QQ群:12012081


 

au3删除自身的探讨

 au3删除自身的探讨

看了虫子樱桃兄写的“au3自删除的归纳”一帖,研究了一下发现里面有很多玄妙,里面涉及了cmd、进程、线程、编译等知识,下面讲一下我的见解。

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

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

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

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

  1. FileDelete(@ScriptFullPath)
  2. If FileExists(@ScriptFullPath) Then
  3.         $f = @ScriptName & "还好好的"
  4. Else
  5.         $f = @ScriptName & "已删除"
  6. EndIf
  7. MsgBox(1, "删除自身演示", $f)
复制代码

(二)编译成exe文件运行

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

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

  1. 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说明其他任务已结束,强行终止进程是没问题的,可以采取以下的命令实现:

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

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

其实也是cmd一行命令也就可以解决,如何实现呢?请大家动下脑筋再看隐藏内容:

本帖隐藏的内容需要回复才可以浏览

  1. If Not @Compiled Then Exit MsgBox(0, "删除自身演示", "不编译会直接删除脚本文件,请编译后运行")
  2. $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)
  3. $e = MsgBox(1, "删除自身演示", "点确定删除自身文件,点取消直接退出")
  4. If $e = 2 Then ProcessClose($p)
复制代码
延时为60秒,删除命令可以放在脚本任何地方,当然建议放在最后,ping、cmd命令都耗cpu的,而且必须是结束进程后才能删除的,放在前面也没用,演示中的MsgBox放在后面是为了演示效果而放的。

注意:cmd单行命令if后可执行多语句,用括号括起来就行,cmd单行命令是可以使用变量的,具体请参阅:
调用cmd(dos)命令详解





终极大法:

cmd延时存在很大的缺陷,不合适放在脚本前端。如果放在脚本退出点,有的脚本退出点很多,每个退出点都放一条删除命令很麻烦,更何况一些非正常原因终止,尚未执行删除命令进程就结束了,达不到删除自身的目的。

下面这个办法可以完美解决这个问题,同样请大家先思考一下再看答案,提示一下延时利用au3实现,前提还是不通过创建文件来实现。

本帖隐藏的内容需要回复才可以浏览

  1. If Not @Compiled Then Exit MsgBox(0, "删除自身演示", '不编译会直接删除"AutoIt3.exe"文件,请编译后运行')
  2. $p = Run(@AutoItExe & ' /AutoIt3ExecuteLine  "Local $s=ProcessWaitClose(' & @AutoItPID & '), $a=Run(''cmd /c taskkill /f /pid '' & @AutoItPID & ''& del /q/f/a ""'' & @ScriptFullPath & ''""'','''',@SW_HIDE)"')
  3. $e = MsgBox(1, "删除自身演示", "点确定删除自身文件,点取消直接退出")
  4. If $e = 2 Then ProcessClose($p)
复制代码
请参考:用au3命令行实现简单多进程


文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
评论: 0 | 引用: 0 | 查看次数: 84
发表评论
你没有权限发表留言!