找回密码
 加入
搜索
查看: 296|回复: 9

[AU3基础] [已解决]怎么获取外部程序返回值?

[复制链接]
发表于 2023-8-31 12:36:54 | 显示全部楼层 |阅读模式
本帖最后由 msold5 于 2023-9-2 09:31 编辑

看到一个好软件PrimoCache:http://bbs.wuyou.net/forum.php?mod=viewthread&tid=432774 .这个程序使用内存来动态智能缓存程序,
我用过较长时间老版本,使用起来硬盘速度提升蛮不错的,其软件下载链接:https://www.lanzoub.com/b0btzvdej  码:ttjc
以前的静默安装参数失效,但这个贴子里的批处理也无法静默安装,想写一个AU3程序来实现无人参与的安装工作,其中遇到一个问题:在安装中批处理有一部分如下:
:cert
echo.
echo --- 导入驱动测试签名证书为受信证书 ---
certutil.exe -f -addstore Root TestCertificate.cer >nul
certutil.exe -f -addstore TrustedPublisher TestCertificate.cer >nul
echo certutil%errorlevel%
if %errorlevel% equ 0 (
  echo 证书导入成功。
) else (
  echo 证书导入失败。
)

我改成AU3来写后,找不到获取返回值的方法,貌似@error、@exitCode都一直是0,到QQ群里问了说需要使用StdErr方法来获取,但好像命令行和不需要CMD参与的又不一样?
由于在群里不便于刷屏贴那么多内容,所以到论坛发贴说明情况,用什么方法才能取得返回值呢?
需要得到返回值的地方还有好几个:
        卸载:fcsetup.exe -u "%INSTALLLOCATION%drv\rxfcv.inf" 257
        安装:fcsetup.exe -i "%INSTALLLOCATION%drv\rxfcv.inf" 257
        安装:fcsetup.exe -m
        对比文件:fc /b drv\%SYS% "%SystemRoot%\System32\drivers\%SYS%",下面两句以本行为例
$iPID = Run('fc.exe "C:\Program Files\PrimoCache\drv\rxfcv.cat" "D:\PrimoCache.Mui.4.3\drv7\rxfcv.cat"' )
MsgBox($MB_SYSTEMMODAL, @exitCode, @error)
可以用上面两行对比文件为例指导?如果方便,可以下载PrimoCache看看安装批处理指点一下

发表于 2023-8-31 17:21:27 | 显示全部楼层
看看 StdoutRead 帮助文档示例~
 楼主| 发表于 2023-8-31 17:35:17 | 显示全部楼层
本帖最后由 msold5 于 2023-8-31 17:40 编辑
afan 发表于 2023-8-31 17:21
看看 StdoutRead 帮助文档示例~

看了示例,看上去是用@error来得到程序的返回值,请问是直接用@error就可以得到,不是必须使用StdoutRead或者其他功能吧? 但好像我用于fc比较文件时无法取得返回值,也就没办法判断两个文件是否相同。


AU3帮助文件中的示例:
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3> ; 仅 _ArrayDisplay() 需要.

; 递归显示目录的文件列表.
Example()

Func Example()
    Local $sFilePath = @ScriptDir ; 搜索当前脚本目录.
    Local $sFilter = "*.*" ; 搜索当前目录的所有文件. 关于有效的通配符列表,使用"通配符"搜索帮助文档.

    ; 如果文件路径不是一个目录, 则从 Example() 函数返回.
    If Not StringInStr(FileGetAttrib($sFilePath), "D") Then
        Return SetError(1, 0, 0)
    EndIf

    ; 删除尾随反斜杠,并追加一个单一的尾部反斜杠.
    $sFilePath = StringRegExpReplace($sFilePath, "[\\/]+\z", "") & ""

    #cs
        DIR 命令行参数
        /B - 简单输出
        /A-D - 搜索所有文件, 排除文件夹.
        /S - 搜索子文件夹.
    #ce
    Local $iPID = Run(@ComSpec & ' /C DIR "' & $sFilePath & $sFilter & '" /B /A-D /S', $sFilePath, @SW_HIDE, $STDOUT_CHILD)
    ; 如果你要搜索的文件包含 Unicode 字符, 则使用 /U 命令行参数.

    ; 使用 Run() 返回的 PID 等待直到该进程关闭.
    ProcessWaitClose($iPID)

    ; 读 Run() 返回 PID 的 Stdin 流. 也可以在 while 循环中完成. 参考 StderrRead() 示例.
    Local $sOutput = StdoutRead($iPID)

    ; 以 @CRLF (换行符) 作为拆分符, 使用 StringSplit() 拆分 StdoutRead() 的输出到一个数组. 剥离所有回车符 (@CRLF).
    Local $aArray = StringSplit(StringTrimRight(StringStripCR($sOutput), StringLen(@CRLF)), @CRLF)
    If @error Then
        MsgBox($MB_SYSTEMMODAL, "", "在当前脚本目录中查找所有文件时出错.")
    Else
        ; 显示结果.
        _ArrayDisplay($aArray)
    EndIf
EndFunc   ;==>Example

发表于 2023-8-31 17:49:58 | 显示全部楼层
msold5 发表于 2023-8-31 17:35
看了示例,看上去是用@error来得到程序的返回值,请问是直接用@error就可以得到,不是必须使用StdoutRead ...

当然没有 @Error,类似这样的
Local $iPID = Run('fc.exe "C:\Program Files\PrimoCache\drv\rxfcv.cat" "D:\PrimoCache.Mui.4.3\drv7\rxfcv.cat"', '', 0, 0x8)
ProcessWaitClose($iPID)
Local $sOutput = StdoutRead($iPID)
MsgBox(0, '', $sOutput)
 楼主| 发表于 2023-8-31 19:02:35 | 显示全部楼层
本帖最后由 msold5 于 2023-9-2 09:32 编辑
afan 发表于 2023-8-31 17:49
当然没有 @Error,类似这样的

不是要程序显示的内容,是要程序的退出码(返回码)
比如在命令行窗口中使用fc比较两个文件的时候,如果两个文件相同,返回值为0,而两个文件不相同时,返回值为1,可以在批处理中表达为:
fc    file1   file2
echo %errorlevel%
此时,如果file1=file2,则显示0,否则显示1,现在就想在AU3里面得到这个0或者1
发表于 2023-8-31 19:08:54 | 显示全部楼层
那就 RunWait 不就行了
MsgBox(0, '', RunWait('fc.exe "C:\Program Files\PrimoCache\drv\rxfcv.cat" "D:\PrimoCache.Mui.4.3\drv7\rxfcv.cat"'))

评分

参与人数 1金钱 +20 收起 理由
msold5 + 20 赞一个!

查看全部评分

发表于 2023-8-31 20:30:41 | 显示全部楼层
这种多命令的建议直接用 echo %errorlevel%>result1.txt输出结果
然后再用au3读取文件进行对比

评分

参与人数 1金钱 +20 收起 理由
msold5 + 20 赞一个!

查看全部评分

发表于 2023-8-31 20:39:17 | 显示全部楼层
本帖最后由 zghwelcome 于 2023-8-31 20:45 编辑





_GetError_Demo1()
_GetError_Demo2()
_GetError_Demo3()

Func _GetError_Demo1();// excute command
        Local $iPID = Run(@ComSpec & ' /k @echo off & (dir /b/ad d:\abcdefg && echo,error=0)||echo,error=1 ', @SystemDir, @SW_HIDE, 0x8)
        ProcessWaitClose($iPID)
        Local $sRet = BinaryToString(StdoutRead($iPID, 1, 1), 1)
        MsgBox(0, 0, $sRet)
EndFunc   ;==>_GetError_Demo1


Func _GetError_Demo2();//Run Bat
        Local $iPID = Run(@ComSpec & ' /k @echo off&call "' & @ScriptDir & '\Run.bat" ', @SystemDir, @SW_HIDE, 0x8)
        ProcessWaitClose($iPID)
        Local $sRet = BinaryToString(StdoutRead($iPID, 1, 1), 1)
        MsgBox(0, 0, $sRet)
EndFunc   ;==>_GetError_Demo2



Func _GetError_Demo3();//fc.exe
        Local $iPID = Run(@ComSpec & ' /k @echo off& fc.exe "' & @ScriptDir & '\1.txt" "' & @ScriptDir & '\2.txt" 0<&1', @SystemDir, @SW_HIDE, 0x8)
        ProcessWaitClose($iPID)
        Local $sRet = BinaryToString(StdoutRead($iPID, 1, 1), 1)
        MsgBox(0, 0, $sRet)
EndFunc   ;==>_GetError_Demo3



Run.bat
@echo off
dir /b/ad d:\
echo,error=%errorlevel%

评分

参与人数 1金钱 +20 收起 理由
msold5 + 20 很给力!

查看全部评分

 楼主| 发表于 2023-9-1 12:25:50 | 显示全部楼层
3131210 发表于 2023-8-31 20:30
这种多命令的建议直接用 echo %errorlevel%>result1.txt输出结果
然后再用au3读取文件进行对比

谢谢你的建议,方法也不错,重点只是我自己想掌握这种方法。
转为AU3的原意有两个,一是批处理本身无法点击没办法做到无人参与安装;二是AU3比批处理快,批处理方式速度慢一些。
都已经在使用AU3了,就希望能只使用AU3而不再使用批处理了
 楼主| 发表于 2023-9-1 12:28:21 | 显示全部楼层

谢谢指点,我慢慢测试消化一下。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-2 10:58 , Processed in 0.087951 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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