Python或批处理文件打开多个vbs文件(vbs文件打开一个程序+文件)

时间:2016-06-14 14:06:58

标签: python batch-file vbscript multiple-instances nppexec

我有多个VBS文件(每个文件打开一个不同的文件,相同的程序),我想打开它们而不必点击所有这些文件。如果我使用我创建的python脚本并使用Notepad ++中的NPPExec执行,我可以让它们在没有问题的情况下打开。我希望文件打开的方式(使用前面提到的方法)是打开程序+文件 - >点击一些键盘敲击 - >重复。我遇到的问题是,当我双击python文件时,它只会打开程序+第一个文件 - >做键盘敲击,然后对于以下文件,它只会打开程序。我很确定这个问题是由于当VBS脚本通过击键时没有正确的焦点窗口引起的,它们没有在正确的窗口上执行。我有一个批处理文件,我也尝试过,我遇到了同样的问题。

打开程序+文件的VBS文件 - >击键 我试过没有运气的App.Activate

Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Run """C:\Program Files (x86)\Program\Program.exe""" & """C:\temp_folder\file.ext"""
objShell.AppActivate """C:\Program Files (x86)\Program\Program.exe"""
WScript.Sleep 3000
objShell.SendKeys "{TAB}"
objShell.SendKeys "{TAB}"
objShell.SendKeys "{UP}"
objShell.SendKeys "{TAB}"
objShell.SendKeys "{DOWN}"
objShell.SendKeys "{ENTER}"

用于打开多个VBS文件的Python代码 以我想要的方式工作,但仅限于从Notepad ++和NPPExec运行 双击python脚本无法正常工作

import os
import time
import subprocess
alfs = []
for file in os.listdir(os.getcwd()):
    if file.endswith(".ext"):
        alfs.append(file)

for f, item in enumerate(alfs):
    subprocess.call('cmd /c %s'%alfs[f])    
    time.sleep(2)

打开多个VBS文件的批处理文件 我通过双击运行批处理文件,结果类似于Python双击方法。

for /r "." %%a in (*.vbs) do %%~fa

我主要拼凑我发现的代码,让它按照我想要的方式工作。我对Python的了解相当不错,但我对VBS和Batch来说是全新的。

2 个答案:

答案 0 :(得分:1)

AppActivate Method参考:

  

激活应用程序窗口。

     
      
  • 语法:object.AppActivate title
  •   
  • 参数:      
        
    • object WshShell object。
    •   
    • title :指定要激活的应用程序。这可以是包含应用程序的标题的字符串(如图所示)   标题栏)或应用程序的进程ID
    •   
  •   

确保提供给objShell.AppActivate的字符串是Program.exe所需实例的标题,或者进程ID

SendKeys Method引用外,请阅读Sending Keystrokes to a Program。本文解释 任何脚本的基本不足 - 时间问题:

  

您应该知道向应用程序发送击键不是   自动化程序的最佳方法。如果你有   在您的企业中需要自动执行的应用程序,它没有   基于COM的对象模型,您可能会考虑这种技术。然而,   您应首先检查是否存在其他方法以进行自动化   那个特殊的应用程序。

     

尽管SendKeys可以有效使用,但仍有几种潜力   这种方法的问题:

     
      
  • 脚本可能难以确定将击键发送到哪个窗口。
  •   
  • 由于应用程序在GUI模式下运行,因此用户可能会过早关闭应用程序。不幸的是,这不会终止   脚本和脚本最终可能会发错键   应用即可。
  •   
  • 脚本可能无法与应用程序同步
  •   
     

这个计时问题特别麻烦,仅仅是因为脚本   往往比GUI应用程序运行得快得多。
...

使用AppActivate

  

在向用户发送击键之前,您必须首先确保   应用程序正在运行,重点是在   应用程序(即,应用程序在活动中运行   窗口)。
... ...您可以定期将脚本放在循环中   调用AppActivate直到返回值为True。那时,   应用程序已加载并准备接受击键。
...
当   脚本正在确定要激活的应用程序,给定的   标题与屏幕上可见的每个窗口的标题进行比较。 如果   没有完全匹配,AppActivate方法将焦点设置为   第一个窗口,标题以给定文本开头。如果是一个窗口   仍无法找到,标题字符串以其结尾的第一个窗口   文本是重点。与领导和部分匹配   标题栏的尾随文本确保AppActivate可以使用   应用程序,如记事本,显示当前的名称   在标题栏上打开文档。 (例如,当你第一次开始   Notepad,窗口标题为Untitled - Notepad,而不是Notepad。)   
...

(以上引文只是我的重点摘要:在这里引用整篇文章的时间太长了。)

修改

让我们正面朝上SendKeys方法将键击发送到活动窗口看不见,因为实际上我们从未知道哪个窗口是目前专注。利用Run Method (Windows Script Host)完整语法objShell.Run sCmdLine, 1, False,其中窗口样式1含义为

  
      
  • 1 激活并显示一个窗口。如果窗口最小化或最大化,系统会将其恢复为原始大小   位置。应用程序在显示时指定此标志   这是第一次进入窗口。
  •   

使用下一个示例脚本进行测试(为了更好地理解而进行了评论):

option explicit
On Error GoTo 0

Dim objShell, sProgram, sTxtFile, sTxtPath, sCmdLine, sTxtExists
Set objShell = WScript.CreateObject( "WScript.Shell" )

sProgram = "C:\Windows\System32\notepad.exe" 
sTxtFile = Replace( Wscript.ScriptName, ".vbs", ".txt", 1, -1, vbTextCompare)
sTxtPath = CreateObject("Scripting.FileSystemObject").BuildPath( _
             objShell.ExpandEnvironmentStrings("%temp%"), sTxtFile)
sTxtExists = CreateObject("Scripting.FileSystemObject").FileExists(sTxtPath)

    ' delete file merely for testing and debugging to ensure that 
    '             `NOTEPAD` will ask whether create nonexistent file
If sTxtExists Then CreateObject("Scripting.FileSystemObject").DeleteFile( sTxtPath)
WScript.Sleep 500                       ' wait for deleting

sCmdLine = """" & sProgram & """ """ & sTxtPath & """"
objShell.Run sCmdLine, 1, False
              '  this `1` activates currently launched notepad
              '           and its possible initial dialogue takes focus
WScript.Sleep 1000      ' hence, `AppActivate` is not necessary

                                  ' alternative to `DeleteFile( sTxtPath)`
' If NOT sTxtExists Then          ' answer initial dialogue only if necessary  
    objShell.SendKeys "{TAB}"
    WScript.Sleep 100
    objShell.SendKeys "{TAB}"
    WScript.Sleep 100
    objShell.SendKeys "{TAB}"
    WScript.Sleep 100
    objShell.SendKeys "{ENTER}"
    WScript.Sleep 100
' End If
objShell.SendKeys Cstr(Now)
WScript.Sleep 100

但是,启动器中还有另一个计时焦点问题。 Python time.sleep(2)会满足吗?当然不是:每个vbs脚本在第一个SendKeys之前等待3秒,但下一个脚本每2秒启动一次!

等效的批处理脚本:Timeout command暂停命令处理器指定的秒数。
尾随1>NUL hides output倒计时Waiting for X seconds, press CTRL+C to quit ...

for /r "." %%a in (*.vbs) do (
    C:\Windows\System32\wscript.exe "%%~fa"
    timeout /T 5 /NOBREAK 1>NUL
)

5秒就足够了吗?

答案 1 :(得分:0)

从DOS BATCH的角度来看,这可以帮助你:

FOR %%G IN (file1.txt file2.txt file3.txt) DO start notepad.exe %%G

您可以进行必要的修改以处理VBS文件。