Board logo

标题: [文件操作] 自动检测cmd窗口内容 [打印本页]

作者: 踏沙行    时间: 2018-2-14 11:24     标题: 自动检测cmd窗口内容

【背景】
1.我们的服务器上有一个文件,名称为“2018年预算执行cmd.exe”,只有当它启动并正常运行时,业务系统才可以正常工作。
2.这个文件正常运行时,显示的是一个dos窗口,且窗口不断滚动,显示的内容是实时用户登录、业务办理数据等信息。

【故障】
当用户操作数据量较大,或该文件运行较长时,或其他原因……会导致窗口信息不再滚动,该窗口最后一行,显示为:“D:\2018年预算执行cmd.exe" (该文件的路径)。
同时,业务系统所有的操作,都没有响应。

【临时解决办法】
关闭这个cmd窗口,重新运行“2018年预算执行cmd.exe”,该窗口重新加载完毕后,系统可以正常操作。

【求助】
如何通过批处理,自动检测这个处理这个窗口,实现如下效果:
1、定期(如隔1个小时)检查这个cmd窗口。当窗口停止滚动,并且最后一行显示为:“D:\2018年预算执行cmd.exe"时,关闭该窗口
2、自动启动这个“D:\2018年预算执行cmd.exe"文件

最难的是第一点,不知道怎么实现,敬请指导,谢谢。
作者: ivor    时间: 2018-2-14 21:35

本帖最后由 ivor 于 2018-2-14 22:14 编辑

测试程序cmd.exe  ,按键精灵2014代码
有一点点BUG就是光标闪烁会造成判断误差,几率是50%,如果目标程序静止,多检测几次也可以触发重启代码,
update:增加For 循环,修复光标闪烁BUG
  1. //下面三个变量自行修改
  2. //************************
  3. //运行的文件路径
  4. filePath = "cmd.exe"
  5. //窗口类名
  6. windowClass = "ConsoleWindowClass"
  7. //循环时间间隔单位毫秒
  8. //5秒
  9. delayTime=5000
  10. //************************
  11. //下面这句是查找窗口类名("Notepad")或者标题(0),返回找到的句柄Hwnd
  12. Hwnd = Plugin.Window.Find(windowClass, 0)
  13. //窗口还原
  14. Call Plugin.Window.Restore(Hwnd)
  15. //下面这句是得到窗口句柄的客户区大小
  16. sRect = Window.GetClientRect(Hwnd)
  17. //MsgBox "得到窗口句柄的客户区大小为:"& sRect   
  18. //下面这句用于分割字符串,将横坐标和纵坐标分成两个字符串   
  19. dim MyArray   
  20. MyArray = Split(sRect, "|")   
  21. //下面这句将字符串转换成数值   
  22. L = Clng(MyArray(0)): T = Clng(MyArray(1))   
  23. R = Clng(MyArray(2)): B = Clng(MyArray(3))   
  24. Call Plugin.Pic.PrintScreen(L, T, R, B,"C:\consol.bmp")
  25. //区域找图
  26. Delay delayTime
  27. For 5
  28. iCoord = Plugin.Pic.FindPic(L-1, T-1, R+1, B+1, "C:\consol.bmp", 0, 0.9)
  29. Delay 200
  30. //失败返回:-1|-1
  31. //MsgBox iCoord
  32. If iCoord <> "-1|-1" Then
  33. //
  34. //此处代码为重启程序
  35. //
  36. //MsgBox "目标界面已静止,即将重启软件 " & Hwnd
  37. Call Plugin.Memory.TerminateProc(Hwnd)
  38. //程序的路径
  39. Call RunApp(filePath)
  40. Exit For
  41. End If
  42. Next
复制代码

作者: hlzj88    时间: 2018-2-14 21:50

本帖最后由 hlzj88 于 2018-2-14 23:36 编辑

楼上已给出答案。
作者: codegay    时间: 2018-2-15 00:35

虽然我说的是废话。但是楼主这程序的是BUG得修。
作者: codegay    时间: 2018-2-16 05:13

本帖最后由 codegay 于 2018-2-16 05:18 编辑

一个思路
可以直接把这个程序的标准输出重点向到一个文本里,然后循环检查文本中的最后一行。

如果可行,可以用mtee同时把标准输出重定向到文本中。
作者: codegay    时间: 2018-2-16 05:40

还有一个思路是写一个程序来启动你的程序,那么这个程序好像是可以读写你的程序的标准输入输出。
python subprocess好像是可以。

http://blog.51cto.com/steed/2043482

同理其它语言中应该也有类似的库。
作者: l00l00    时间: 2018-2-18 18:41

其实楼主这是进入一个误区了。那就是把简单的问题复杂化了。
给你一个思路,绝对绝对的解决问题:
不管2018年预算执行cmd.exe执行得怎么样,正常也好,卡住也罢,1小时让它结束,再重新启动一个新的
2018年预算执行cmd.exe 进程。
这个我想你应该会。
作者: 踏沙行    时间: 2018-2-22 08:37

回复 2# ivor
非常感谢热心的支持,不过不知道,能不能通过cmd通过vbs等脚本直接实现?
作者: 踏沙行    时间: 2018-2-22 08:38

回复 6# codegay

谢谢,没有学过py,不知道通过cmd或者vbs、JS能否直接实现?
作者: 踏沙行    时间: 2018-2-22 08:40

回复 7# l00l00

这也是一个办法,之前已经在用,但是感觉这样会有一个问题:
有时候出错的频率不低于一个小时 ,有时候几个小时才出错。
而这样统一设置1个小时,有些不够智能了。
可能我太理想化了吧。
作者: ivor    时间: 2018-2-22 09:10

  1. get-process 2018年预算执行cmd | select-object * | out-file psInfo.txt
复制代码
多检测几次看看是否能根据进程信息判断程序卡住了。
作者: 踏沙行    时间: 2018-2-23 12:03

回复 11# ivor

这行命令,是powershell命令吗?
作者: ivor    时间: 2018-2-23 13:24

回复 12# 踏沙行


   是的
作者: l00l00    时间: 2018-2-24 20:16

Bat脚本实现监控进程功能
脚本不间断监控notepad.exe进程是否执行,若停止,则自动重启该进程,程序如下:
1 @echo off
2  
3 set _task = notepad.exe
4 set _svr  = c:\windows\notepad.exe
5 set _des  = start.bat
6  
7 :checkService
8 for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_task%" ') do (
9     if %%n==%_task% (goto checkMessage) else goto restartService
10 )
11   
12 :restartService
13 echo %time%
14 echo ********程序开始启动********
15 echo 程序重新启动于 %time% ,请检查系统日志 >> restart_service.txt
16 echo start %_svr% > %_des%
17 echo exit >> %_des%
18 start %_des%
19 REM set /p=.<nul 不换行在屏幕输出....
20 set /p=.<nul
21 for /L %%i in (1 1 10) do set /p a=.<nul & ping.exe /n 2 127.0.0.1>nul
22 echo .
23 del %_des% /Q
24 echo ********程序启动完成********
25 goto checkService
26  
27  
28 :checkMessage
29 echo %time% 程序运行正常,5秒后继续检查..
30 ping localhost -n 5
31 goto checkService

以上脚本是引用的。供参考




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2