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

[其他] 批处理远程调用appactivate失败的问题

诚心求助!本人最近在写远程批量关闭应用的脚本,由于该应用不可强杀,需要触发其关闭后输入密码,故调用了sendkeys去输入密码;然而用命令行触发应用关闭后,由于焦点的偏移,sendkeys无法将密码正确传输到应用中。后来我又使用了appactivate,在输入密码前将焦点转移到应用内,至此在本机上测试成功。然而当我尝试在别的机器上远程start该bat脚本时,发现跟在本机使用脚本不一样,焦点无法转移到应用内。

以下是我部署在远程机器上的,用来关闭该应用的bat脚本:
  1. @if (@CodeSection == @Batch) @then
  2. ::@echo off
  3. if "%1"=="h" goto begin
  4. :begin
  5. SET SendKeys=CScript //nologo //E:JScript "%~F0"
  6. set /a n=0
  7. for /f "delims=" %%a in ('tasklist^|findstr /i "应用名"') do set /a n+=1
  8.      if %n% gtr 0 goto kill_menu
  9.      if %n% equ 0 goto end
  10. :kill_menu
  11. for /f "tokens=2" %%i in ('tasklist ^| findstr 应用名')  do  echo %%i > pid.txt
  12. for /f %%a in (pid.txt) do (
  13.      if "%%~za" equ "0" (
  14.         GOTO end       ) else (
  15.         taskkill /pid %%a
  16.      )
  17. )
  18. echo CreateObject("WScript.Shell").Appactivate("应用名") > tmp.vbs
  19. start tmp.vbs
  20. ping 127.0.0.1 > nul
  21. %SendKeys% "password"
  22. %SendKeys% "{ENTER}"
  23. del tmp.vbs
  24. del pid.txt
  25. GOTO begin
  26. @end
  27. // JScript section
  28. var WshShell = WScript.CreateObject("WScript.Shell");
  29. WshShell.SendKeys(WScript.Arguments(0));0
复制代码
最后我是在别的机器上用plink去远程调用上面脚本的:
start "" plink -ssh -pw xxx xxx@192.168.1.13 ".\close.bat"

试试先置顶窗口 , 然后才 taskkill 看看吧

不过还是试试换成其他程序执行, 对比看看是不是同样的效果(最好是直接远程桌面里执行) ,说不定可能是程序问题

TOP

WshShell.AppActivate() 方法
激活指定窗口

WshShell.AppActivate(targe)

参数
targe
要激活的窗口的标题栏,或进程PID
类型:String/Long

标题栏字符串不区分大小写返回值

如果未找到与targe参数匹配的窗口,则返回False

如果找到与targe参数匹配的窗口,且窗口不是最小化状态,则返回True

如果找到与targe参数匹配的窗口,且窗口是最小化状态
则winxp返回True,而win7和win10返回False

类型:Boolean

说明

先查找完全匹配的标题栏
找不到就匹配标题栏左起或右起的字符串
但不会匹配标题栏中间的字符串

例如 targe = "abc"
可以匹配标题栏www.abc或abc.com
但不会匹配www.abc.com

如果找不到匹配的窗口,则不执行任何操作,不会改变当前的活动窗口
如果找到匹配的窗口,则激活窗口一次
但并不保证该窗口一直是活动窗口
所以如果要对激活的窗口进行操作,比如发送按键,可能会被其它激活的窗口打乱

如果找到多个匹配的窗口,则激活最上面的一个窗口

如果匹配的字符串全是数字,则会被认为是进程PID
例如 targe = "123456"
不能匹配标题栏“123456.txt - 记事本”

如果要匹配的是进程PID,也可以不加""
例如:要激活进程PID为2014的进程的窗口,以下2行都可以:
WshShell.AppActivate "2014"
WshShell.AppActivate 2014

如果匹配的窗口是最小化状态,则窗口不会被弹出,还是最小化在任务栏
但窗口会处于激活状态,此时按 Alt + F4 可以关闭该窗口

QQ 20147578

TOP

回复 8# xends


    https://demon.tw/copy-paste/vbs-sendmessage.html
这里是vbs用office调用api的示例,实际上就是vba
如果远程电脑上有office,可以参考下

否则到powershell区去问,怎么调用api
GetForegroundWindow 获取当前窗口
SetWindowPos 激活指定窗口
SendWindowMessage 给指定窗口发送消息,不需要是活动窗口

QQ 20147578

TOP

回复 4# buyiyang


    尝试了一下,还是不行,如果窗口本身不是置顶的情况下,只会在任务栏闪烁,而不会置顶对应程序

TOP

回复 6# czjt1234


    具体的思路可以说一下吗,目前的需求只有两个:1.在taskkill后将触发了关闭的程序置顶 2.对该程序输入指定字符并enter

TOP

回复 5# Five66


    好像不是,我通过窗口化远程桌面看到,脚本在运行的时候,任务栏在闪烁,只是没有办法将该程序置顶

TOP

SendKeys 就是个坑
用powershell吧,可以调用API

QQ 20147578

TOP

说不定是 Appactivate 窗口还原过程中又被其他程序遮挡了吧
试试多试几次 Appactivate

TOP

回复 2# xends


    激活窗口后在发送一个ENTER试试

TOP

回复 2# xends


   是不是权限不足?这行代码有管理员权限吗?
  1. CreateObject("WScript.Shell").Appactivate("应用名")
复制代码
bat小白,请多指教!谢谢!

TOP

目前发现,远程触发脚本的情况下,如果程序被最小化,只能在任务栏看到闪烁的标题,不能使其成为当前显示的窗体;而在本机上运行脚本,即使程序被最小化,也能置顶该程序。问题是,为什么远程触发跟本机运行出来的结果会有不同,又要怎样才能让远程触发也能置顶最小化了的程序呢

TOP

返回列表