いくつかのVB6.exeファイルを呼び出すレガシーVBScript(vbs)ファイルの実行を自動化するC#アプリケーションを開発しています。.exeファイルにはメッセージボックスのポップアップがあり、VBScriptプロセスを無人で実行できるようにするために「応答」する必要があります。応答はEnterキーである必要があります。.exeファイルのソースがなく、それらが何をするのか正確にはわかりません。私はこれでどんな助けでも大いに感謝します...
6 に答える
AutoItが役立つかもしれません。
AutoIt v3は、WindowsGUIと一般的なスクリプトを自動化するために設計されたフリーウェアのBASICのようなスクリプト言語です。他の言語(VBScriptやSendKeysなど)では不可能または信頼できない方法でタスクを自動化するために、シミュレートされたキーストローク、マウスの動き、およびウィンドウ/コントロール操作の組み合わせを使用します。
AutoItプログラミング言語のみを使用して何かを開発することも、独自のアプリケーションからそれを駆動することもできます。私のチームはこれを使用しており、成功しています。
wsh SendKeys()関数を使用できます。ただし、メッセージボックスがアクティブになっていることを確認する必要があるため、SendKeys呼び出しの直前にAppActivate()を呼び出す必要もあります。
これでもバグがありますが、これを実行するスクリプトをいくつか作成しました。メッセージボックスがいつ表示されるかを予測できる限り、[Enter]キーを送信して応答できます。
外部ユーティリティを必要とせずに、C#でこれを行うことができます。秘訣は、メッセージボックスダイアログを検索して[OK]ボタンをクリックすることです。それを複数回行うには、そのようなダイアログを検索してクリックし続けるタイマーが必要です。プロジェクトに新しいクラスを追加し、次のコードを貼り付けます。
using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class MessageBoxClicker : IDisposable {
private Timer mTimer;
public MessageBoxClicker() {
mTimer = new Timer();
mTimer.Interval = 50;
mTimer.Enabled = true;
mTimer.Tick += new EventHandler(findDialog);
}
private void findDialog(object sender, EventArgs e) {
// Enumerate windows to find the message box
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero);
GC.KeepAlive(callback);
}
private bool checkWindow(IntPtr hWnd, IntPtr lp) {
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770") return true;
// Got it, send the BN_CLICKED message for the OK button
SendMessage(hWnd, WM_COMMAND, (IntPtr)IDC_OK, IntPtr.Zero);
// Done
return false;
}
public void Dispose() {
mTimer.Enabled = false;
}
// P/Invoke declarations
private const int WM_COMMAND = 0x111;
private const int IDC_OK = 2;
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hWnd, int item);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
使用例:
private void button1_Click(object sender, EventArgs e) {
using (new MessageBoxClicker()) {
MessageBox.Show("gonzo");
}
}
使用して見たいかもしれませんが、
SetWinEventHook PInvoke
ダイアログがいつ作成されているかを検出します。フックをグローバルまたは特定のプロセスに指定できます。フラグを設定して、WINEVENT_OUTOFCONTEXT
フックしているプロセスでコードが実際に実行されないようにすることができます。探しているイベントはEVENT_SYSTEM_DIALOGSTART
.
(イベント フックから) ダイアログの hwnd を取得したら、SendMesssage
withWM_COMMAND
またはWM_SYSCOMMAND
を使用してそれを取り除くことができます。
これを機能させるために過去 2 日間を費やした後、私は最終的にあきらめ、別のアプローチを決定しました。外部プロセスに送信されているデータを調査し、メッセージ ボックスのポップアップの原因となっている条件をスクリーニングしています。回答をくださった皆様、ありがとうございました!
sendkey メソッドを使用して、キーボード キーの値を渡し、実行を続行します。