[英]How to automate - download a file and save it in internet explorer browser using C# .NET?
[英]Press save button of “File download dialog” of internet explorer via c#
我正在研究Internet Explorer自動化,其中一部分涉及從asp 2.0上托管的站點下載文件並使用基於表單的身份驗證,因此為了創建端到端自動化,我使用了瀏覽器自動化。
我能夠到達我可以點擊一個帶有瀏覽器“文件下載”對話框的URL的步驟,然后我試圖利用SendKeys點擊保存按鈕,但無濟於事不工作
下面是我使用FindWindow方法獲取文件下載對話框的hWnd指針的代碼,然后使用setActiveWindow使其成為活動窗口,以便SendKeys命令對其起作用,然后使用SendKeys我嘗試發送Alt +但它沒有用。 我觀察到,Tab,Escape和Enter工作,但是Enter on Save按鈕不起作用。
[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中的值更改為“Untitled - Notepad”來訪問記事本。
我是否需要做一些不同的事情,因為它是一個對話框,現在是一個窗口? 我正在使用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");
為清楚起見,我正在添加對話框的屏幕。
alt text http://www.freeimagehosting.net/uploads/4f23586401.png
這適用於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);
}
}
嘗試以下似乎對我有用的:
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");
我建議你檢查每個功能的回報。
我在StackOverflow上找到了大部分內容: 如何在C#中使用webbrowser時處理消息框? 我為我修改了它
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);
}
}
好吧,你必須找到下載對話框標題的窗口。 而且你必須找到帶有下載按鈕標題的窗口/然后發送到該窗口點擊消息
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的東西;)
我在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
請告訴它是否適合你。
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");
如果我沒有錯,那實際上是誤報; 看似故障安全的默認行為似乎是關閉對話框。 相反,可以單擊取消按鈕是積極的,但是嘗試單擊打開或保存將在該上下文中生成相同的不需要的響應...
看來這是一個我們只需要處理的對話框,除非別人可以感激地另外確認一下?
沒有任何代碼建議工作,我最終使用AutoIt腳本關閉打印對話框,代碼如下:
Local $hWnd = WinWait("[CLASS:#32770]", "Print", 20)
WinActivate($hWnd)
WinWaitActive("[CLASS:#32770]", "Print", 10)
Sleep(100)
Send("{ENTER}")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.