找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: wzehu

[文件操作] 如何用 BAT VBS 静默运行 EXE,自动关闭 EXE 已知确认类弹窗

[复制链接]
 楼主| 发表于 2026-5-5 21:53:18 | 显示全部楼层
czjt1234 发表于 2026-5-5 17:21
经测试,CleanZ.exe运行后会在%temp%生成一个随机文件名后缀名为###
但此文件内容不会改变,因此不能靠这个 ...

以前,我多是XP桌面右键 清理武器 运行 CleanZ.exe。
知道它会留一个ComputerZ.set。没关心时机。
你看得真准,就是在弹出 清理完毕后1秒钟留下一个ComputerZ.set。
抓住这个时间点,把扫描时间多留一点应该能解决。。。
我再试试。。。
发表于 2026-5-5 22:14:13 | 显示全部楼层
wzehu 发表于 2026-5-5 21:53
以前,我多是XP桌面右键 清理武器 运行 CleanZ.exe。
知道它会留一个ComputerZ.set。没关心时机。
你看得 ...

有了动态变化的文件标识,便可间接捕获子窗口,看一下第一个子窗口出现之后是否已有 computerZ.set 生成,如是,即可准确捕获两个子窗口了...
 楼主| 发表于 2026-5-5 22:16:08 | 显示全部楼层
yakeyun 发表于 2026-5-5 15:43
可以自己根据使用环境收集路径加入清理脚本执行,占用路径可以通过TreeSize扫描后定位路径位置。
https://ww ...

以前的一键清理.cmd 没有你这段代码牛。。。

清理软件有好多,如CCleaner.exe,软媒清理大师等。
我玩PE 时看到了落雪梨花清理,大家口碑蛮好。
其实落雪梨花清理就是CleanZ.exe,清理武器V1.3
如是在网上找到了 清理武器V1.53 ,没有再高版本了。

我收藏啦。。。
 楼主| 发表于 2026-5-5 22:16:08 | 显示全部楼层
yakeyun 发表于 2026-5-5 15:43
可以自己根据使用环境收集路径加入清理脚本执行,占用路径可以通过TreeSize扫描后定位路径位置。
https://ww ...

以前的一键清理.cmd 没有你这段代码牛。。。

清理软件有好多,如CCleaner.exe,软媒清理大师等。
我玩PE 时看到了落雪梨花清理,大家口碑蛮好。
其实落雪梨花清理就是CleanZ.exe,清理武器V1.3
如是在网上找到了 清理武器V1.53 ,没有再高版本了。

我收藏啦。。。
 楼主| 发表于 2026-5-5 22:26:57 | 显示全部楼层
aloha20200628 发表于 2026-5-5 22:14
有了动态变化的文件标识,便可间接捕获子窗口,看一下第一个子窗口出现之后是否已有 computerZ.set 生成 ...

为何我只点一次回复,就会出现重复?我又重复回贴了。。
意见反馈\下我发过:错误反馈  发新帖和回复时,存在重复发帖、重复回复的误操作。
:'(:'( :'(
 楼主| 发表于 2026-5-5 23:05:16 | 显示全部楼层
77七 发表于 2026-5-5 16:48
楼主需要的是适配任意系统任意软件,还是XP系统上任意软件?或者是任意系统,CleanZ软件?
请在1楼明确。 ...



我要的是:
  一、在XP SP3 上 静默运行 CleanZ软件
  二、学习各种抓取系统、软件类窗口弹窗的代码
 楼主| 发表于 2026-5-6 21:45:40 | 显示全部楼层
czjt1234 发表于 2026-5-5 17:21
经测试,CleanZ.exe运行后会在%temp%生成一个随机文件名后缀名为###
但此文件内容不会改变,因此不能靠这个 ...

While WshShell.AppActivate("清理武器")=False:WScript.Sleep 200:Wend
Do While Not WshShell.AppActivate("清理武器"):WScript.Sleep 200oop

像这类通过循环抓取窗口标题【清理武器】的方式,根本识别不到有效窗口。
原因是:CleanZ 主界面 和 清理完成弹窗,窗口标题都同名叫【清理武器】。
就算弹窗置顶在主界面上方,手动直接回车能正常触发动作,
但脚本靠匹配标题激活窗口的写法,实测完全失效、没用。

希望有更好的方式,或方法。。
 楼主| 发表于 2026-5-6 21:45:40 | 显示全部楼层
czjt1234 发表于 2026-5-5 17:21
经测试,CleanZ.exe运行后会在%temp%生成一个随机文件名后缀名为###
但此文件内容不会改变,因此不能靠这个 ...

While WshShell.AppActivate("清理武器")=False:WScript.Sleep 200:Wend
Do While Not WshShell.AppActivate("清理武器"):WScript.Sleep 200oop

像这类通过循环抓取窗口标题【清理武器】的方式,根本识别不到有效窗口。
原因是:CleanZ 主界面 和 清理完成弹窗,窗口标题都同名叫【清理武器】。
就算弹窗置顶在主界面上方,手动直接回车能正常触发动作,
但脚本靠匹配标题激活窗口的写法,实测完全失效、没用。

希望有更好的方式,或方法。。
发表于 6 天前 | 显示全部楼层
本帖最后由 aloha20200628 于 2026-5-8 12:24 编辑
wzehu 发表于 2026-5-6 21:45
While WshShell.AppActivate("清理武器")=False:WScript.Sleep 200:Wend
Do While Not WshShell.AppActiv ...


没有XP系统复验和调试只能借助13楼的第一手线索推算(仅供参考),优先测试computerZ.set文件的创建时间和完成时间,13楼已发现后者可用于捕获第二个弹窗,现在只须验证第一个弹窗出现且在未予确认前是否创建该文件?如是,解法就比较简单,否则就要改试用第二个弹窗前后的内存变化差值来捕获,此法需要在两个极端清理场景下(少量扫描和大量扫描)测试取值(用任务管理器查看cleanZ.exe进程内存栏),稍显麻烦,但逻辑上可行。楼主可作些功课...
发表于 6 天前 | 显示全部楼层
  1. Dim oWshShell, oFSO, s

  2. Set oWshShell = CreateObject("WScript.Shell")
  3. Set oFSO = CreateObject("Scripting.FileSystemObject")
  4. oWshShell.Run "CleanZ.exe"
  5. While oWshShell.AppActivate("清理武器") = False
  6.     WScript.Sleep 200
  7. Wend
  8. oWshShell.SendKeys "{ENTER}"    '开始扫描
  9. Do
  10.     s = oWshShell.Run("cmd.exe /c for /f ""tokens=5 delims= "" %i in ('tasklist.exe ^|find.exe /i ""CleanZ.exe""') do exit /b %i", 0, True)
  11.     'MsgBox s
  12.     If s > 3 Then Exit Do
  13.     WScript.Sleep 200
  14. Loop
  15. While oWshShell.AppActivate("清理武器") = False
  16.     WScript.Sleep 200
  17. Wend
  18. oWshShell.SendKeys "{ENTER}"    '开始清理
  19. While oFSO.FileExists("ComputerZ.set") = False
  20.     WScript.Sleep 200
  21. Wend
  22. While oWshShell.AppActivate("清理武器") = False
  23.     WScript.Sleep 200
  24. Wend
  25. oWshShell.SendKeys "%{F4}"
  26. WScript.Sleep 200
  27. oWshShell.SendKeys "%{F4}"    '退出程序
  28. oFSO.DeleteFile "ComputerZ.set", True
复制代码
winxpsp3测试通过
最后不使用tasjkill结束程序,否则%temp%里面会残留一个.###文件
 楼主| 发表于 6 天前 | 显示全部楼层
本帖最后由 wzehu 于 2026-5-8 23:28 编辑
czjt1234 发表于 2026-5-8 16:17
winxpsp3测试通过
最后不使用tasjkill结束程序,否则%temp%里面会残留一个.###文件 ...



这样能跑.  只是有时清理不完全...


  1. Set fso = CreateObject("Scripting.FileSystemObject")
  2. Set WsShell = CreateObject("WScript.Shell")
  3. Path = fso.GetParentFolderName(WScript.ScriptFullName)
  4. filePath =  Path & "\ComputerZ.set"
  5. WsShell.Run Path & "\CleanZ.exe"
  6.    WScript.Sleep 200
  7.         ''''While WsShell.AppActivate("清理武器")=False:WScript.Sleep 300 :Wend
  8. WsShell.SendKeys "{ENTER}"
  9. WScript.Sleep 1000
  10.         ''''While WsShell.AppActivate("清理武器")=False:WScript.Sleep 300 :Wend
  11. WScript.Sleep 1000
  12. WsShell.SendKeys "{ENTER}"
  13. Do While Not fso.FileExists(filePath)
  14.    WScript.Sleep 300
  15.    Loop
  16.    WScript.Sleep 300
  17.    fso.DeleteFile filePath, True
  18.    WsShell.SendKeys "{ENTER}"
  19. WsShell.Run "taskkill /f /im CleanZ.exe", 0
  20. WScript.Quit
复制代码



代码验证时,必须用:XP 下 删除文件进回收站代码 自动完成 后  查看回收站空,满状态


发表于 5 天前 | 显示全部楼层

暂时没有XP环境了,需要测试一下(自动清理.JS)

本帖最后由 cutebe 于 2026-5-9 13:15 编辑

以下已测试环境 Win7/Win10
  1. //执行宏调用ExecuteExcel4Macro
  2. var 表应用 = new ActiveXObject("Excel.Application");        //创建表格程序对象
  3. var 表程序 = 表应用.Application;        //设置对象变量,以减少引用对象的书写长度

  4. 自动运行清理武器测试();

  5. 表应用.Quit();        //结束应用
  6. WScript.Quit();        //结束脚本


  7. //-----函数-----//
  8. function 自动运行清理武器测试(){
  9.         var 清理程序文件="D:\\自动清理\\CleanZ.exe";        //软件路径
  10.         var 文件环境 = new ActiveXObject("Scripting.FileSystemObject");
  11.         if(!文件环境.FileExists(清理程序文件)){WScript.Echo("文件不存在。");return;}

  12.         var 标题="清理武器 V1.3 www.zwuqi.com",类="TFormCleanZ";        //软件窗口信息
  13.         var 窗口句柄=0;
  14.         while(!窗口句柄){
  15.                 打开程序(清理程序文件);        //===打开程序===//
  16.                 延时(500);
  17.                 窗口句柄=查找窗口(标题,类);        //===找到软件窗口===//
  18.         }
  19.         if(窗口句柄){
  20.                 //WScript.Echo("窗口句柄:"+窗口句柄);
  21.                 //显示窗口信息(窗口句柄);        //===句柄标题类===//
  22.                 var 扫描按钮文字="扫描",按钮类="TButton";
  23.                 var 扫描按钮句柄=下一个子窗口(窗口句柄,0,扫描按钮文字,按钮类);
  24.                 投送点击按钮消息(扫描按钮句柄);
  25.         }
  26.         var 毫秒=500,关闭=0x10;
  27.         while(1){
  28.                 延时(毫秒);
  29.                 var 对话框句柄=查找对话框窗口("清理武器");
  30.                 if(对话框句柄){
  31.                         var 浏览器未关=清理武器对话框检测("清理武器","正在运行中,无法",关闭);
  32.                         if(浏览器未关){毫秒=300;/*WScript.Echo("关闭了浏览器提示对话框。");*/}
  33.                         var 清理确认=清理武器对话框检测("清理武器","要立即清理这些项目","确定");
  34.                         if(清理确认){毫秒=200;/*WScript.Echo("清理确认对话框:确定开始清理!");*/}
  35.                         var 完成清理=清理武器对话框检测("清理武器","清理完毕","确定");
  36.                         if(完成清理){/*WScript.Echo("确认完成清理对话框。");*/}
  37.                 }
  38.                 窗口句柄=查找窗口(标题,类);
  39.                 if(完成清理 || (!窗口句柄)){break;}
  40.                 //对话框句柄=0;
  41.         }
  42.         窗口句柄=查找窗口(标题,类);        //===找到软件窗口===//
  43.         if(窗口句柄){
  44.                 //WScript.Echo("窗口句柄:"+窗口句柄);
  45.                 var 退出按钮文字="退出",按钮类="TButton";
  46.                 var 退出按钮句柄=下一个子窗口(窗口句柄,0,退出按钮文字,按钮类);
  47.                 投送点击按钮消息(退出按钮句柄);
  48.                 投送关闭窗口消息(窗口句柄);
  49.         }
  50. }

  51. function 清理武器对话框检测(标题,部分提示内容,按钮动作){        //显示窗口及子窗口信息
  52.         var 对话框句柄=查找对话框窗口(标题);
  53.         //WScript.Echo("对话框句柄:"+对话框句柄);
  54.         if(!对话框句柄){/*WScript.Echo(标题+"对话框未找到!");*/return 0;}
  55.         var 子窗口基本信息=找子窗口基本信息(对话框句柄,0,0);
  56.         //WScript.Echo("子窗口基本信息("+子窗口基本信息.length+"):"+子窗口基本信息);
  57.         var 子窗口数=子窗口基本信息.length;
  58.         for(var i=0;i<子窗口数;i++){
  59.                 if(子窗口基本信息[i][1]==按钮动作 && 子窗口基本信息[i][2]=='Button'){
  60.                         var 确定按钮句柄=子窗口基本信息[i][0];
  61.                 }else{if(子窗口基本信息[i][1].indexOf(部分提示内容)!=-1 && 子窗口基本信息[i][2]=='Static'){
  62.                         var 确认提示句柄=子窗口基本信息[i][0];
  63.                 }}
  64.         }
  65.         while(确认提示句柄 && 对话框句柄){
  66.                 if(按钮动作==0x10){投送关闭窗口消息(对话框句柄);}        //关闭对话框
  67.                 else{投送点击按钮消息(确定按钮句柄);}        //发送点击按钮消息(确定按钮);
  68.                 对话框句柄=查找对话框窗口(标题);
  69.         }
  70.         if(!对话框句柄 && 确认提示句柄){return 1;}
  71. }
  72. function 打开程序(文件路径){
  73.         var 进程句柄=表程序.ExecuteExcel4Macro('CALL("Shell32","ShellExecuteA","JJFFJJJ",0,"open","'+文件路径+'",0,0,1)');
  74.         //if(进程句柄>32){WScript.Echo("程序运行成功。");}else{WScript.Echo("程序打开失败!");}
  75. }
  76. function 延时(毫秒){
  77.         表程序.ExecuteExcel4Macro('CALL("kernel32","Sleep","JJ",'+毫秒+')');
  78. }
  79. function 查找窗口(标题,类){        //返回句柄
  80.         var 窗口句柄;
  81.         if(!标题){        //标题为0
  82.                 if(!类){窗口句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowA","JJJ",0,0)');}        //类为0       
  83.                 else{窗口句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowA","JFJ","'+类+'",0)');}
  84.         }else{
  85.                 if(!类){窗口句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowA","JJF",0,"'+标题+'")');}        //类为0       
  86.                 else{窗口句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowA","JFF","'+类+'","'+标题+'")');}
  87.         }
  88.         return 窗口句柄;
  89. }
  90. function 下一个子窗口(父句柄,上个子句柄,标题,类){
  91.         var 子句柄;
  92.         if(标题==0){        //标题为0               
  93.                 if(类==0){子句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowExA","JJJJJ",'+父句柄+','+上个子句柄+',0,0)');        //类为0
  94.                 }else{子句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowExA","JJJFJ",'+父句柄+','+上个子句柄+',"'+类+'",0)');}
  95.         }else{        //有标题
  96.                 if(类==0){子句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowExA","JJJJF",'+父句柄+','+上个子句柄+',0,"'+标题+'")');
  97.                 }else{子句柄=表程序.ExecuteExcel4Macro('CALL("User32","FindWindowExA","JJJFF",'+父句柄+','+上个子句柄+',"'+类+'","'+标题+'")');}
  98.         }
  99.         return 子句柄;
  100. }
  101. function 投送点击按钮消息(按钮句柄){
  102.         var 点击=0xF5;
  103.         表程序.ExecuteExcel4Macro('CALL("User32","PostMessageA","JJJJJ",'+按钮句柄+','+点击+',0,0)');
  104. }
  105. function 投送关闭窗口消息(窗口句柄){
  106.         var 关闭=0x10;
  107.         表程序.ExecuteExcel4Macro('CALL("User32","PostMessageA","JJJJJ",'+窗口句柄+','+关闭+',0,0)');
  108. }
  109. function 查找对话框窗口(标题){
  110.         var 对话框句柄=查找窗口(标题,"#32770");        //对话框类#32770
  111.         return 对话框句柄;
  112. }
  113. function 找子窗口基本信息(父句柄,标题,类){        //显示句柄、标题、类
  114.         var 第一个子句柄=下一个子窗口(父句柄,0,标题,类);
  115.         var 子句柄=第一个子句柄,子窗口基本信息=[];
  116.         while(子句柄){
  117.                 var 子标题=获取窗口标题(子句柄);
  118.                 var 子类名=获取类名(子句柄);
  119.                 子窗口基本信息.push([子句柄,子标题,子类名]);
  120.                 子句柄=下一个子窗口(父句柄,子句柄,标题,类);
  121.         }
  122.         return 子窗口基本信息;
  123. }
  124. function 获取窗口标题(窗口句柄){
  125.         var 窗口标题长度=表程序.ExecuteExcel4Macro('CALL("User32","GetWindowTextLengthA","JJ",'+窗口句柄+')');
  126.         var 缓冲区大小=窗口标题长度+1,窗口标题="";
  127.         var 内存地址 = 表程序.ExecuteExcel4Macro('CALL("Kernel32", "VirtualAlloc", "JJJJJ", 0, '+缓冲区大小+', '+0x3000+', 4)');        //申请内存
  128.         var 标题长度=表程序.ExecuteExcel4Macro('CALL("User32", "GetWindowTextA", "JJJJ", '+窗口句柄+','+内存地址+','+窗口标题长度+1+')');
  129.         if(标题长度){窗口标题=内存读取字符串(内存地址);}
  130.         表程序.ExecuteExcel4Macro('CALL("Kernel32", "VirtualFree", "JJJJ", '+内存地址+', 0, '+0x8000+')');        //释放内存
  131.         return 窗口标题;
  132. }
  133. function 获取类名(窗口句柄){
  134.         var 缓冲区大小=256,类名="";        //类名最长255
  135.         var 内存地址=表程序.ExecuteExcel4Macro('CALL("Kernel32","VirtualAlloc","JJJJJ",0,'+缓冲区大小+','+0x3000+',4)');        //申请内存
  136.         var 类名长度=表程序.ExecuteExcel4Macro('CALL("User32","GetClassNameA","JJJJ",'+窗口句柄+','+内存地址+','+缓冲区大小+')');
  137.         if(类名长度){类名=内存读取字符串(内存地址);}
  138.         表程序.ExecuteExcel4Macro('CALL("Kernel32","VirtualFree","JJJJ",'+内存地址+',0,'+0x8000+')');        //释放内存
  139.         return 类名;
  140. }
  141. function 内存读取字符串(内存地址){        //返回字符串
  142.         var 段长度=127;
  143.         var 总字节=表程序.ExecuteExcel4Macro('CALL("Kernel32","lstrlenA","JJ",'+内存地址+')');        //内存文本字节数
  144.         var 偏移字节=0,文本字符串=分段文本='';
  145.         while(偏移字节<总字节){        //返回字符串F。        //返回超255字节时,也需要分段操作
  146.                 分段文本=表程序.ExecuteExcel4Macro('CALL("Kernel32","lstrcpynW","FFJJ","",'+(内存地址+偏移字节)+','+段长度+')');
  147.                 偏移字节+=分段文本.replace(/[^\x00-\xff]/g,'xx').length;        //计算字符串字节数
  148.                 文本字符串+=分段文本;
  149.         }
  150.         return 文本字符串;
  151. }
复制代码

评分

参与人数 1技术 +1 收起 理由
czjt1234 + 1 感谢分享

查看全部评分

发表于 5 天前 | 显示全部楼层
cutebe 发表于 2026-5-9 10:43
以下已测试环境 Win10

请问  表应用  表程序  有什么区别,没看出来啊
一直纳闷这个Application有什么用
发表于 5 天前 | 显示全部楼层
本帖最后由 cutebe 于 2026-5-9 14:36 编辑
czjt1234 发表于 2026-5-9 11:32
请问  表应用  表程序  有什么区别,没看出来啊
一直纳闷这个Application有什么用 ...

表应用 重命名为 表环境

组件名:"Excel.Application"。表格COM组件在注册表中有体现。
第一行 表环境 是连接组件的一个 组件引用对象;        //其下有许多 子对象,如:.Application
第二行 表程序 是一个 子对象;        //其下有许多 方法,如:.ExecuteExcel4Macro
第三行 .ExecuteExcel4Macro 是一个方法。

  1. var 表环境 = new ActiveXObject("Excel.Application");        //创建表格程序的环境对象
  2. var 表程序 = 表环境.Application;                        //执行具体方法的对象
  3. 表程序.ExecuteExcel4Macro('CALL("kernel32","Sleep","JJ",'+毫秒+')');        //延时示例
复制代码


发表于 5 天前 | 显示全部楼层
cutebe 发表于 2026-5-9 10:43
以下已测试环境 Win7/Win10

js在winxp中测成功

但是我删除第三行,再把 表程序 全部替换为 表应用,一样运行成功
那个ExecuteExcel4Macro在表程序和表应用也都支持
没看出这2个有啥区别

在vbs中TypeName()读取这2个的返回值,对象类型也一样,都是Application

同样,Shell.Application对象的Application属性,和Shell.Application也没试出有啥区别
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-5-14 22:34

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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