0

複数の 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 についてはまったくの初心者です。

4

2 に答える 2

1

AppActivate メソッドリファレンス:

アプリケーション ウィンドウをアクティブにします。

  • 構文:object.AppActivate title
  • 引数:
    • オブジェクト:WshShellオブジェクト。
    • title : アクティブ化するアプリケーションを指定します。これは、アプリケーションのタイトル(タイトル バーに表示される) またはアプリケーションのProcess IDを含む文字列です。

に指定された文字列が、 の目的のインスタンスobjShell.AppActivateタイトルまたはそのProcess IDであることを確認してください。Program.exe

SendKeys メソッドのリファレンスに加えて、 Sending Keystrokes to a Program をお読みください。この記事では、 任意のスクリプトの根本的な不足について説明します - タイミングの問題:

キーストロークをアプリケーションに送信することは、手順を自動化するための最適な方法ではないことに注意してください。企業内に自動化する必要のあるアプリケーションがあり、そのアプリケーションに COM ベースのオブジェクト モデルがない場合は、この手法を検討できます。ただし、その特定のアプリケーションを自動化するための他の方法が存在するかどうかを最初に調べる必要があります。

効果的SendKeysに使用できますが、このアプローチにはいくつかの潜在的な問題があります。

  • スクリプトは、キーストロークを送信するウィンドウを決定するのが難しい場合があります。
  • アプリケーションは GUI モードで実行されるため、ユーザーがアプリケーションを途中で閉じる可能性があります。残念ながら、これでスクリプトは終了せず、スクリプトがキーストロークを間違ったアプリケーションに送信してしまう可能性があります
  • スクリプトは、アプリケーションとの同期に問題がある可能性があります

スクリプトは GUI アプリケーションよりもはるかに高速に実行される傾向があるため、このタイミングの問題は特に厄介です。
…</p>

使用AppActivate

キーストロークをアプリケーションに送信する前に、アプリケーションが実行中であり、フォーカスがアプリケーションにある (つまり、アプリケーションがアクティブなウィンドウで実行されている) ことを最初に確認する必要があります。

スクリプトをループに入れて、戻り値が True になるまで定期的に AppActivate を呼び出すことができます。その時点で、アプリケーションがロードされ、キーストロークを受け入れる準備が整います。
…<BR>スクリプトが起動するアプリケーションを決定するとき、指定されたタイトルが画面上に表示されている各ウィンドウのタイトルと比較されます。完全に一致するものが存在しない場合、AppActivateメソッドは、タイトルが指定されたテキストで始まる最初のウィンドウにフォーカスを設定します。. それでもウィンドウが見つからない場合は、タイトル文字列がテキストで終わる最初のウィンドウにフォーカスが与えられます。タイトル バーの先頭および末尾のテキストとの部分一致によりAppActivate、現在開いているドキュメントの名前をタイトル バーに表示するメモ帳などのアプリケーションで が動作することが保証されます。(たとえば、最初に を起動したとき Notepad、ウィンドウのタイトルはUntitled - NotepadではなくNotepadです。)
…<BR>

(上記の引用は、私の強調したダイジェストです。ここで記事全体を引用するには長すぎます。)

編集します。

どのウィンドウが現在フォーカスされているかは実際にはわからないため、そのメソッドがキーストロークをアクティブなウィンドウの目に見えないサイトSendKeysに送信することを考えてみましょう。Run Method (Windows Script Host)の完全な構文を活用してください。ウィンドウ スタイルの意味は次のとおりです。objShell.Run sCmdLine, 1, False1

  • 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)十分でしょうか?確かにそうではありません: すべてのスクリプトは、最初のスクリプトが2 秒ごとに起動されるvbs前に 3 秒待機します!SendKeys

同等のバッチ スクリプト: Timeoutcommandは、指定された秒数だけコマンド プロセッサを一時停止します。
末尾1>NULは出力カウントダウンを非表示にします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秒でいいの?

于 2016-06-14T16:36:49.283 に答える
0

DOS BATCH の観点から、これは次のことに役立ちます。

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

VBS ファイルを処理するために必要な変更を加えることができます。

于 2016-06-14T15:37:23.630 に答える