【发布时间】:2019-08-19 23:01:13
【问题描述】:
我正在尝试自动从网页获取文件。它会打开带有 3 个常用选项(打开、保存和取消)的“保存下载”窗口。我正在尝试单击“保存”按钮,但无法使其正常工作。我什至尝试从 Spy++ 获取 &Save 句柄并在执行 ClickButton 之前插入句柄指针,以确保我有正确的句柄指针,但仍然没有。
除了SendMessage(WindowHandle, BM_CLICK, 0, IntPtr.Zero)之外,一切正常
Sub ClickButton(ByVal WindowHandle As IntPtr)
'SendMessageW(WindowHandle, WM_ACTIVATE, New IntPtr(WA_ACTIVE), IntPtr.Zero) I've tried several flavors of this ClickButton and no effect!
'SendMessageW(WindowHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero)
SendMessage(WindowHandle, BM_CLICK, 0, IntPtr.Zero)
End Sub
Sub LookForAndCloseIEPopup()
'get a handle to any popup window associated with the main form (as is a popup window
'displayed by the Web browser control)...
Dim ptrDialogWindow As IntPtr = GetWindow(xAsIntPtr, GW_ENABLEDPOPUP)
Dim text2 = GetWindowText(xAsIntPtr)
If text2.Contains("File Download") Then
'xAsIntPtr = hWnd
'LookForAndCloseIEPopup() '(GetWindowText(hwnd, text, Int16.MaxValue))
End If
Debug.Print(GetWindowText(ptrDialogWindow) & "TEXT:=" & Text2 & vbCrLf)
'if the popup window is one displayed by the browser, then send the close message to the window...
If text2.Contains("File Download") Then ClosePopup(ptrDialogWindow)
End Sub
Sub ClosePopup(ByVal WindowHandle As IntPtr)
Dim clsChildHandles As ArrayList = GetChildWindowHandles(WindowHandle)
Dim teststr As String
Dim prthandleint As Long
'look through all of the child handles of the window for an "OK" button (this method
'can also be used to gather more specific information about the dialog itself, such as
'the message being displayed)...
For Each ptrHandle As IntPtr In clsChildHandles
'if the OK button is found, click it...
teststr = GetWindowText(ptrHandle)
prthandleint = ptrHandle
'ptrHandle = &H002A0B7E !!! I even tried putting the &Save handle which I got from Spy++ with the same result!
Debug.Print(GetWindowText(ptrHandle) & " = Child TEXT: len=" & teststr.Length & "handle = " & prthandleint & vbCrLf)
If teststr.Contains("&Save") Then
ClickButton(ptrHandle) 'This part works fine as I get here
Exit For
Else
Debug.Print(GetWindowText(ptrHandle) & " = Child TEXT: len=" & vbCrLf)
End If
Next
End Sub
Const WM_GETTEXT As Long = &HD
Const WM_GETTEXTLENGTH As Long = &HE
Const GW_ENABLEDPOPUP As Long = 6
Const BM_CLICK As Long = &HF5&
Const GW_CHILD As Long = 5
Const GW_HWNDNEXT As Long = 2
Const WM_ACTIVATE As Integer = &H6
Const WA_ACTIVE As Integer = &H1
'function to retrieve the popup window associated with the form, as well as to find the child windows of the popup...
Private Declare Auto Function GetWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
<DllImport("user32.dll", EntryPoint:="SendMessageW")>
Private Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
'sendmessage overload that is used to send messages to the button on the dialog window...
Private Declare Auto Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As Integer, ByRef lParam As IntPtr) As IntPtr
'sendmessage overloads used to retrieve the window text...
Private Declare Auto Function SendMessageA Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
<DllImport("User32.dll", CharSet:=CharSet.Auto, EntryPoint:="SendMessage")> Public Shared Function SendMessageString(ByVal hwnd As IntPtr,
ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr
End Function
Function GetChildWindowHandles(ByVal ParentWindowHandle As IntPtr) As ArrayList
Dim b As Boolean
Dim ptrChild As IntPtr
Dim clsRet As New ArrayList
'ParentWindowHandle = IntPtr(xAsIntPtr)
'get first child handle...
ptrChild = GetChildWindowHandle(xAsIntPtr)
Do Until ptrChild.Equals(IntPtr.Zero)
'add to collection of handles...
clsRet.Add(ptrChild)
'get next child...
ptrChild = GetNextWindowHandle(ptrChild)
Loop
'return...
Return clsRet
End Function
Function GetChildWindowHandle(ByVal ParentWindowHandle As IntPtr) As IntPtr
Return GetWindow(ParentWindowHandle, GW_CHILD)
End Function
Function GetNextWindowHandle(ByVal CurrentWindowhandle As IntPtr) As IntPtr
Return GetWindow(CurrentWindowhandle, GW_HWNDNEXT)
End Function
'this function returns the text of the window, used so that we can confirm that we have the right dialog window...
Function GetWindowText(ByVal WindowHandle As IntPtr) As String
Dim ptrRet As IntPtr
Dim ptrLength As IntPtr
'get length for buffer...
ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)
'create buffer for return value...
Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)
'get window text...
ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)
'get return value...
Return sb.ToString
End Function
在调试输出窗口中,我看到&Save 的值被捕获,并且代码按预期工作,直到ClickButton 尝试执行但没有响应的部分。
【问题讨论】:
-
你能用 HttpClient/WebRequest/WebClient 下载这个资源吗?
-
如果您知道文件 URL,那么您可以使用这个非常简单的代码通过 VB.NET 代码下载文件。 My.Computer.Network.DownloadFile("abc/demo_img.png", "C:\Users\abc\Desktop\247.png") 参考:docs.microsoft.com/en-us/dotnet/visual-basic/developing-apps/…
-
当我点击'export to excel'然后我得到通常的保存下载弹出框和三个按钮!打开保存并取消!
-
此站点没有可用的网络服务!
-
不要点击
export to excel,而是获取底层链接并将其指向的资源保存到文件中,使用提到的类之一(在这种情况下通常是WebClient)。如果您可以发布您所指的 html 页面的 Uri,那么建议不同的方法可能会更容易。
标签: html vb.net internet-explorer