[已解决]怎么获取外部程序返回值?
本帖最后由 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看看安装批处理指点一下
看看 StdoutRead 帮助文档示例~
本帖最后由 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
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) 本帖最后由 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 那就 RunWait 不就行了
MsgBox(0, '', RunWait('fc.exe "C:\Program Files\PrimoCache\drv\rxfcv.cat" "D:\PrimoCache.Mui.4.3\drv7\rxfcv.cat"')) 这种多命令的建议直接用 echo %errorlevel%>result1.txt输出结果
然后再用au3读取文件进行对比 本帖最后由 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%
3131210 发表于 2023-8-31 20:30
这种多命令的建议直接用 echo %errorlevel%>result1.txt输出结果
然后再用au3读取文件进行对比
谢谢你的建议,方法也不错,重点只是我自己想掌握这种方法。
转为AU3的原意有两个,一是批处理本身无法点击没办法做到无人参与安装;二是AU3比批处理快,批处理方式速度慢一些。
都已经在使用AU3了,就希望能只使用AU3而不再使用批处理了 zghwelcome 发表于 2023-8-31 20:39
Run.bat
谢谢指点,我慢慢测试消化一下。
页:
[1]