找回密码
 加入
搜索
查看: 1213|回复: 13

[AU3基础] OnAutoItExitRegister 这个命令的作用?“已解决”

[复制链接]
发表于 2022-5-11 10:11:37 | 显示全部楼层 |阅读模式
本帖最后由 xuzhouchuanxp 于 2022-5-12 14:44 编辑

;=============================================

#include <MsgBoxConstants.au3>

OnAutoItExitRegister("MyTestFunc")
OnAutoItExitRegister("MyTestFunc2")

Sleep(1000)

Func MyTestFunc()
    MsgBox($MB_SYSTEMMODAL, "退出结果 1", '退出消息来自 MyTestFunc()')
EndFunc   ;==>MyTestFunc

Func MyTestFunc2()
    MsgBox($MB_SYSTEMMODAL, "退出结果 2", '退出消息来自 MyTestFunc()')
EndFunc   ;==>MyTestFunc2;===============================================================上面是帮助里的事例,我没看懂这个OnAutoItExitRegister 命令函数是干嘛用的。请解释一下,谢谢。



发表于 2022-5-11 12:01:29 | 显示全部楼层
在任何时刻,在退出后,即执行此函数指定的UDF

有时候脚本有多个条件,多个分支条件下的Exit,此时只要OnAutoItExitRegister("MyTestFunc")

将在退出后执行“MyTestFunc”,常用做脚本的清理工作,比如callbackfree等等
发表于 2022-5-11 10:17:16 | 显示全部楼层
脚本在退出前执行函数
 楼主| 发表于 2022-5-11 11:05:34 | 显示全部楼层
把这个OnAutoItExitRegister("MyTestFunc")  换成   MyTestFunc()  不也是运行完退出程序吗?  那样写有什么特殊意义吗?
发表于 2022-5-12 11:37:57 | 显示全部楼层
xuzhouchuanxp 发表于 2022-5-11 11:05
把这个OnAutoItExitRegister("MyTestFunc")  换成   MyTestFunc()  不也是运行完退出程序吗?  那样写有什 ...

脚本自身的功能,你在退出脚本的时候,是可以关闭掉的,但是如果你调用了第三方的程序,比如数据库,系统DLL等文件,必须等脚本完全退出后,才能卸载的。此时就要用到这个函数。这个函数的功能,就是等脚本完全退出之后,再执行OnAutoItExitRegister这个函数,去做清理工作。你可以理解为OnAutoItExitRegister,是完全独立于你的脚本的,感觉像AU3的另外一个进程?
发表于 2022-5-12 12:44:02 | 显示全部楼层
本帖最后由 tubaba 于 2022-5-12 12:45 编辑
>"E:\Autoit_3.3.16.0\SciTE\..\AutoIt3.exe" "E:\Autoit_3.3.16.0\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "E:\NoScan\autoit_script\TEst\a.au3" /UserParams    
+>12:39:58 启动 AutoIt3Wrapper (21.316.1639.1) 来自:SciTE.exe (3.6.2.0)  键盘:E0010804  操作系统:WIN_10/2009  CPU架构:X64 操作系统架构:X64  环境(语言:0804)  代码页:936  utf8.自动.检查:3 # 检测ascii高位字符,如果未找到则将默认编码设置为UTF8并添加BOM..
+> SciTEDir => E:\Autoit_3.3.16.0\SciTE   UserDir => E:\Autoit_3.3.16.0\SciTE\AutoIt3Wrapper   SCITE_HOME => E:\Autoit_3.3.16.0\SciTE    SCITE_USERHOME => E:\Autoit_3.3.16.0\SciTE 
>正在执行 AU3Check (3.3.16.0)  来自:E:\Autoit_3.3.16.0  输入:E:\NoScan\autoit_script\TEst\a.au3
+>12:39:58 AU3Check 结束.rc:0
>正在运行:(3.3.16.0):E:\Autoit_3.3.16.0\autoit3.exe "E:\NoScan\autoit_script\TEst\a.au3"    
+>设置热键...--> 按 Ctrl+Alt+Break 重新启动或 Ctrl+BREAK 停止.
!> 以调试模式启动..
行: @error-@extended: 行语法
0001: 0-0: #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
0002: 0-0: #AutoIt3Wrapper_UseX64=n
0003: 0-0: #AutoIt3Wrapper_run_debug_mode=Y
0004: 0-0: #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
0005: 0-0: #include <MsgBoxConstants.au3>
0007: 0-0: OnAutoItExitRegister("MyTestFunc")
0008: 0-0: OnAutoItExitRegister("MyTestFunc2")
0010: 0-0: Sleep(1000)
0011: 0-0: Exit
0018: 0-0:         MsgBox($MB_SYSTEMMODAL, "Exit Results 2", "Exit Message from MyTestFunc()")
0019: 0-0: EndFunc   ;==>MyTestFunc2
0014: 0-0:         MsgBox($MB_SYSTEMMODAL, "Exit Results 1", "Exit Message from MyTestFunc()")
0015: 0-0: EndFunc   ;==>MyTestFunc
+>12:40:10 AutoIt3.exe 已结束.rc:0
+>12:40:11 AutoIt3Wrapper 完成.
>Exit code: 0    Time: 14.07



从这个流程可以看出,函数是在执行exit后,再执行"MyTestFunc2","MyTestFunc"

而且,最后注册的函数总是最先执行(与注册的顺序相反),有时,对于退出时执行函数有先后顺序这种需求的话,要特别注意这点

 楼主| 发表于 2022-5-12 13:13:49 | 显示全部楼层
这个真的好清晰,除了调试错误信息,我就从来没有仔细看过控制台message。非常感谢。
发表于 2022-5-13 10:29:44 | 显示全部楼层
xuzhouchuanxp 发表于 2022-5-11 11:05
把这个OnAutoItExitRegister("MyTestFunc")  换成   MyTestFunc()  不也是运行完退出程序吗?  那样写有什 ...

意义就在于,你能保证你的写的代码里面一个bug都没有吗?
万一在调用MyTestFunc() 的前一行,你的脚本就崩了,这个时候谁给你做清理工作啊

写了小demo,你自己体会一下


;~ 注册一个退出函数
OnAutoItExitRegister("MyTestFunc")


;~ 脚本运行过程中,可能会产生一些临时文件,
;~ 或者使用一些网络资源、数据库资源
;~ 例如:
FileWrite(@ScriptDir & '\test.txt', '随便写点什么')
ConsoleWrite('test.txt文件在吗? -> ' & FileExists(@ScriptDir & '\test.txt') & @CRLF)
;~ 现在有两秒的时间,快去看看,test.txt文件在不在
Sleep(2000)

;~ 运气不好的时候,或者有bug,脚本运行到一半的可能就崩了,
;~ 但是就算是崩了,也是要清理的啊
;~ 给我崩~~~
Local $a[1]
ConsoleWrite('@@ Debug: $a[1] = ' & $a[1] & @CRLF)

;~ 执行不到这一句的,因为上一句已经数组下标越界了
ConsoleWrite('@@ Debug: 执行不到这儿的' & @CRLF)

Func MyTestFunc()
;~     脚本退出的时候做一些清理工作
;~ 例如:删除临时文件,释放网络连接,释放数据库连接,甚至是说个byebye
    ConsoleWrite('@@ Debug: byebye~~~' & @CRLF)
    FileDelete(@ScriptDir & '\test.txt')
    ConsoleWrite('test.txt文件还在吗? -> ' & FileExists(@ScriptDir & '\test.txt') & @CRLF)
EndFunc   ;==>MyTestFunc




发表于 2022-5-13 10:33:12 | 显示全部楼层
本帖最后由 nhnhwsnh 于 2022-5-13 10:34 编辑
smooth 发表于 2022-5-12 11:37
脚本自身的功能,你在退出脚本的时候,是可以关闭掉的,但是如果你调用了第三方的程序,比如数据库,系统 ...

这个函数的意义并不是等脚本完全退出再释放资源,因为在它自动调用MyTestFunc的时候脚本并没有退出啊

而是无论如何都要走到MyTestFunc这里,这个无论如何包括脚本中途崩掉的情况,

主要就是为了防崩,不然手动释放不也行吗?
发表于 2022-5-13 11:38:38 | 显示全部楼层
这个主要是防意外的,比如将某文件重命名了,正常退出时需改回去,但程序意外崩溃了,那被改名的文件就晾在那不知所措了。因此,若有需求,在需要的地方注册 OnAutoItExitRegister() ,若正常退出可 OnAutoItExitUnRegister() 注销。
发表于 2022-5-13 15:13:25 | 显示全部楼层
nhnhwsnh 发表于 2022-5-13 10:33
这个函数的意义并不是等脚本完全退出再释放资源,因为在它自动调用MyTestFunc的时候脚本并没有退出啊

...

函数是一开始就注册好的,除此之外,脚本在退出之前的整个执行的过程中,并没有哪里是走到你说的:MyTestFunc这里。
发表于 2022-5-13 16:34:51 | 显示全部楼层
本帖最后由 nhnhwsnh 于 2022-5-13 17:16 编辑
smooth 发表于 2022-5-13 15:13
函数是一开始就注册好的,除此之外,脚本在退出之前的整个执行的过程中,并没有哪里是走到你说的:MyTest ...

简单点讲,OnAutoItExitUnRegister是注册了一个回调函数,回调的意思就是不是主动调用嘛,当然不是手动调用的,所以你没看到调用MyTestFunc,只是在满足一定条件的时候才触发的。OnAutoItExitUnRegister的触发条件就是解释器要退出。要退出的意思就是还没退出嘛!所以你说的完全退出,呵呵!

请看前面tubaba发的详细调试信息,
第19行执行exit,你理解的结束可能就是这个地方吧,但是这个地方au3解释器可并没有结束啊,
你可以这么理解:exit只是向au3解释器发送了一个程序需要退出的信号,但是解释器还要做一些收尾工作才会真的退出。

这些收尾工作就包括前面注册的退出函数,就是第20到23行
第24行au3解释器,才真的结束了。
如果你把20到23行理解为脚本已经退出了,那就不讨论了啊。


你前面的表述本来就不准确,“等脚本完全退出后,再执行前面注册的函数”,这怎么可能呢?
完全退出了,还在执行你写的代码?

你对这个函数的理解和表述真的不准确的,我在代码里面连接了mysql,我完全没必要非要在脚本完全退出才关闭数据库连接啊,我可以取完数据就关闭连接的。

正确的用法是:
第一步,连接数据库
第二步,确认连接正常
第三步,注册退出函数
第四步,取数据
第五步,关闭数据库连接
第六步,检查是否正确关闭了,
            如果正确关闭了就把前面注册的退出函数给取消了

在这个流程中如果第四到第五步中,代码崩掉了,才会使用注册的退出函数。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-22 16:30 , Processed in 0.102741 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表