5

私はInternetExplorerの自動化に取り組んでおり、その一部にはasp 2.0でホストされ、フォームベースの認証を使用するサイトからファイルをダウンロードすることが含まれるため、エンドツーエンドの自動化を作成するためにブラウザーの自動化を使用しました。

ブラウザの[ファイルのダウンロード]ダイアログが表示されるURLをクリックできるステップに到達できました。次に、SendKeysを使用して保存ボタンをクリックしようとしましたが、役に立ちませんでした。動作していません。

これは、FindWindowメソッドを使用してファイルダウンロードダイアログのhWndポインターを取得し、setActiveWindowを使用してアクティブウィンドウにして、SendKeysコマンドが機能するようにし、SendKeysを使用してAlt+を送信しようとしたコードです。 Sしかし、それは機能しませんでした。Tab、Escape、Enterは機能しますが、[保存時にEnter]ボタンが機能しないことを確認しました。

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetActiveWindow(IntPtr hWnd);

private void Form1_Load(object sender, EventArgs e)
{
    IntPtr hwnd = FindWindow(null, "File Download");
    IntPtr nullptr = (IntPtr)0;
    if (hwnd != nullptr)
    {
        SetActiveWindow(hwnd);
        SendKeys.SendWait("%S");
    }
}

同じコードを使用して、FindWindowの値を「無題-メモ帳」に変更することでメモ帳にアクセスできました。

ダイアログであり、ウィンドウであるため、別のことを行う必要がありますか?IE8を使用しています。

これは私が答えの後に試した代替コードです。

IntPtr hwnd = FindWindow(null, "File Download");
            IntPtr hokBtn = IntPtr.Zero;
            hokBtn = FindWindowEx(hwnd, hokBtn, "Button", IntPtr.Zero);
            hokBtn = FindWindowEx(hwnd, hokBtn, "Button", IntPtr.Zero);
            uint id = GetDlgCtrlID(hokBtn);
            SetActiveWindow(hwnd);
            IntPtr res = SendMessage(hokBtn, (int)0x00F5, 0, IntPtr.Zero);
            if (res.ToInt32() == 1)
                MessageBox.Show("success");

わかりやすくするために、ダイアログの画面を追加しています。

代替テキストhttp://www.freeimagehosting.net/uploads/4f23586401.png

4

7 に答える 7

2

私にとってはうまくいったと思われる次のことを試してください。

IntPtr hwnd = FindWindow(null, "File Download");
IntPtr hokBtn = FindWindowEx(hwnd, null, "Button", "Cancel");
uint id = GetDlgCtrlID(hokBtn);
SetActiveWindow(hwnd);
IntPtr res = SendMessage(hokBtn, (int)0x00F5, 0, IntPtr.Zero);
if (res.ToInt32() == 1)
    MessageBox.Show("success");

ただし、各関数からの戻り値を確認することをお勧めします。

于 2010-06-30T10:33:09.483 に答える
2

これは C++ で機能します。「保存」ボタンの名前は「保存」ではなく「&Save」であることに注意してください。

CString Title;
    Title=_T("File Download");
    HWND FEX =  ::FindWindowEx( NULL,NULL,NULL,Title);
    if (FEX != NULL)
    {

        //press the Save button on the dialog.
        HWND hokBtn = ::FindWindowEx(FEX, NULL, L"Button", L"&Save");
        if (hokBtn != NULL)
        {

            UINT id = ::GetDlgCtrlID(hokBtn);
            ::SetActiveWindow(hokBtn);
            ::PostMessage(hokBtn, WM_KEYDOWN, 0x20, 0);
            ::PostMessage(hokBtn, WM_KEYUP, 0x20, 0);
        }

}

于 2012-09-30T16:00:50.883 に答える
1

さて、ダウンロードダイアログのタイトルが付いたウィンドウを見つける必要があります。そして、ダウンロードボタンのタイトルが付いたウィンドウを見つけて、そのウィンドウにクリックメッセージを送信する必要があります

  BM_CLICK = 0x00F5

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle);

  [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern uint GetDlgCtrlID(IntPtr hWnd); 

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); 

    //hDialog  - handle of dialog window. idBtn - Id of button
     public static bool ClickButtonOnDialog(IntPtr hDialog, UInt32 idBtn)
    {
        IntPtr res = IntPtr.Zero;
        uint id;
        IntPtr hOkBtn = IntPtr.Zero;
        int attempt = 0;
        do
        {
            Thread.Sleep(300);
            //searching for button
            hOkBtn = User32.FindWindowEx(hDialog, hOkBtn, "Button", IntPtr.Zero);
            id = User32.GetDlgCtrlID(hOkBtn);
            attempt++;
        } while (id != idBtn && attempt < 20);
        if (!hOkBtn.Equals(IntPtr.Zero))
        {
            //click the button
            res = User32.SendMessage(hOkBtn, (int)WindowsMessages.BM_CLICK, 1,  IntPtr.Zero);
        }
        if (res.ToInt32() == 1)
            return true;
        return false;
    }

また、winspector (spy++ のアナログ) を使用できます。とても便利なユーティリティです。Windows について多くのことを発見できます;)

于 2010-06-08T19:31:48.510 に答える
1

私はこれのほとんどを StackOverflow で見つけました: How to handle Message Boxes while using webbrowser in C#? そして私はそれを私のために修正しました

using System.Runtime.InteropServices; //for the dll import (to press a key)

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

private async void downloadstuff()
{
await Task.Delay(40000);  //i need this delay, but you might not :)
{
    IntPtr hwnd = FindWindow("#32770", "File Download");  //this is the window it finds
    hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "&Save");  //this is the button to pres
    uint message = 0xf5;
    SendMessage(hwnd, message, IntPtr.Zero, IntPtr.Zero);
}
await Task.Delay(1000);
{
    IntPtr hwnd2 = FindWindow("#32770", "Save As");
    hwnd2 = FindWindowEx(hwnd2, IntPtr.Zero, "Button", "&Save");
    uint message2 = 0xf5;
    SendMessage(hwnd2, message2, IntPtr.Zero, IntPtr.Zero);
}
await Task.Delay(1000);                //i press it anyway, just in case :)
{   //this is the download complete box (if its checked it doesn't show up)
    IntPtr hwnd3 = FindWindow("#32770", "Download complete");
    hwnd3 = FindWindowEx(hwnd3, IntPtr.Zero, "Button", "Close");
    uint message3 = 0xf5;
    SendMessage(hwnd3, message3, IntPtr.Zero, IntPtr.Zero);
}
}
于 2014-08-15T18:29:31.967 に答える
1

Windows XP の Internet Explorer 6 でこれを行う方法を見つけました。

(すみません、VBAコード)

'ButtonHwnd is the pointer to the Save button
Private Declare Function SetCursorPos Lib "user32" (ByVal X As Integer, ByVal Y As Integer) As Long
Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Private Const MOUSEEVENTF_LEFTDOWN As Long = &H2
Private Const MOUSEEVENTF_LEFTUP As Long = &H4
Dim pos As RECT
' We get the button position
GetWindowRect ButtonHwnd, pos

' We simulate an entering of the cursor in the button. IE think this is a human :-).
' We need three steps: out, entering and in.
' Out
SetCursorPos (pos.Left - 10), (pos.Top - 10)
Sleep 100
' Entering
SetCursorPos pos.Left, pos.Top
Sleep 100
' In
SetCursorPos (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2

' We do clic with the left button. You can use SendInput instead
' With 400 miliseconds it works.
mouse_event MOUSEEVENTF_LEFTDOWN, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0
Sleep 400
mouse_event MOUSEEVENTF_LEFTUP, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0

それがあなたのために働くかどうか教えてください。

于 2011-02-23T07:53:59.070 に答える
0
IntPtr hwnd = FindWindow(null, "ファイルのダウンロード");
IntPtr hokBtn = FindWindowEx(hwnd, null, "Button", "Cancel");
uint id = GetDlgCtrlID(hokBtn);
SetActiveWindow(hwnd);
IntPtr res = SendMessage(hokBtn, (int)0x00F5, 0, IntPtr.Zero);
もし (res.ToInt32() == 1)
    MessageBox.Show("成功");

私が間違っていなければ、それは実際には誤検知でした。フェイルセーフのように見えるデフォルトの動作は、ダイアログボックスを閉じることです。むしろ、キャンセル ボタンをクリックできることは肯定的でしたが、[開く] または [保存] をクリックしようとすると、同じコンテキストで不要な応答が生成されます...

これは、他の誰かが感謝して別の方法で確認できない限り、対処する必要があるダイアログ ボックスのようですか?

于 2010-07-21T04:08:10.257 に答える
0

提案されたコードはどれも機能しませんでした。最終的に AutoIt スクリプトを使用して印刷ダイアログを閉じました。コードは次のとおりです。

Local $hWnd = WinWait("[CLASS:#32770]", "Print", 20)
WinActivate($hWnd)
WinWaitActive("[CLASS:#32770]", "Print", 10)
Sleep(100)
Send("{ENTER}")
于 2016-07-21T14:19:56.733 に答える