IE Automation Information Bar Blocking Download (1 Viewer)

gypsyjoe11

Registered User.
Local time
Today, 02:47
Joined
Feb 19, 2010
Messages
46
Hi Everyone,

I'm trying to make a program at work that opens up an IE object in it's own window and navigates to a certain page and then downloads a file.

What I have so far is a program that:

1. Opens IE to the login page

2. Opens up a hidden Excel file with a timer to handle Java pop up confirmation boxes (IE freezes all running threads from the calling application before the pop-up comes up)

3. Logs in and presses ok on the javascript confirmation popup box

4. Presses the Javascript and imagebox items to navigate to the correct sub menus

5. Clicks on the javascript link that creates the CSV file for download.

But then the IE information bar comes up saying that it has disabled the download.

I don't have permission to disable the IE notification toolbar. I could use the mouse stream and inject a mouse click at the correct position using sendInput API. However, I this would cause problems when users are using different programs at the same time.

I'm trying to do this the correct way using the IE object. Does anyone have any ideas?

thanks,

Joe
 

darbid

Registered User.
Local time
Today, 08:47
Joined
Jun 26, 2008
Messages
1,428
I am impressed that my suggestion to use a Timer from another Office program worked.

5. Clicks on the javascript link that creates the CSV file for download.

But then the IE information bar comes up saying that it has disabled the download.

I don't have permission to disable the IE notification toolbar.

This bit is the new bit right?

Can you send some screen images. 1. The kind of Link you are clicking. 2. This IE Information Bar 3. What comes up when you manually click on it.

(on second thoughts is this IE bar the BAR that says Script is running on the website do you agree to let it run?)
 

gypsyjoe11

Registered User.
Local time
Today, 02:47
Joined
Feb 19, 2010
Messages
46
Yes Darbid it works like a charm. Thanks to you :)

It is much simpler than getting approval to run an .exe file.

I'm doing all of this from Excel, but the VBA is almost 100% the same as Access

The screenshot shows the information bar that comes up when my program clicks on the anchor. When I click on it myself (real person) the information bar doesn't come up and I get the normal File Download box.

Below is the results from the immediate window for the anchor element

Code:
debug.Print popupFrame.getElementsByTagName("A")(3).outerhtml
 
<A href="javascript: DownloadAction(document.main1, '#xxxxxx');">CSV Text File</A>
 
popupFrame.getElementsByTagName("A")(3).Click

One route I could go is to stop user input with the system BlockInput API

Code:
Private Declare Function BlockInput Lib "USER32.dll" (ByVal fBlockIt As Long) As Long
 
BlockInput True
 
'do stuff
 
BlockInput False

Then make sure the window is in the foreground and maximize it (in case the user was doing something else)

Code:
Private Declare Function apiShowWindow Lib "User32" Alias "ShowWindow" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetActiveWindow Lib "USER32.dll" (ByVal hWnd As Long) As Long
 
Global Const SW_MAXIMIZE = 3
Global Const SW_SHOWNORMAL = 1
Global Const SW_SHOWMINIMIZED = 2
 
SetActiveWindow ieObj.hWnd
apiShowWindow ieObj.hWnd, SW_MAXIMIZE

Then use getClientRects to get the position of the link to click on.
Below is an example from the immediate window with the program stopped in debugger mode

Code:
debug.Print popupFrame.getElementsByTagName("A")(3).getClientRects.item(0).left
 339 
debug.Print popupFrame.getElementsByTagName("A")(3).getClientRects.item(0).top
 133

I can then use the sendInput API to put a mouse click at that position into the keyboard buffer.

The attached zipfile is a great example of sendInput. If you unzip the .bas file and import it into an Excel module. Then rename the "Private Sub Main()" to "Public Sub Main()" you can run it in the immediate window with "Main". It opens up notepad, paint and some others and does stuff in them. If you move your mouse while it's in paint it messes up what it draws because your mouse movements also get put into the same buffer. However after using "blockInput" in the "DrawNline()" routine it ignores the user movements and draws it perfectly.

Finally I can use your timmer routine to click on the "open" in the dialog that comes up.

All of the above is a possible way to solve this problem and I've tested each component individually. The thing I wanted to see about before I did this was if there was a better way.

I can't see the information bar in the internet's document anywhere so it must only be accesable with the internet application itself. I looked at ieObj.ExecWB that you would use to save the webpage itself but I couldn't find any commands that dealt with the information bar.

Do you know of a better way than my idea above? Do you have any ideas why when VBA clicks on the anchor the info bar comes up but when I click on it it doesn't?

Thanks alot for your help,

Joe


--------------------------------------------
FYI - below is the best way I've found to avoid the program clicking on stuff before it's finished loading

Basically the idea is to keep searching until something specific to the item you want is on the screen with either innerHTML, outerHTML, innerText or outerText

I use this same logic before I get anything from the page and it works great.

I've found that if I do the below the user can do other things while the program is running without it loosing it's place.

Code:
'enter date for "Greater than Status Date of:"
    On Error Resume Next
    Do While InStr(popupFrame.documentElement.innerHTML, "InputKeys_COMP_DT") = 0
    Loop
    On Error GoTo 0
    popupFrame.all("InputKeys_COMP_DT").Value = "3/4/2010"

Before I grab values from an excel sheet I also use

Code:
Do: Loop Until xlObj.Ready
 

Attachments

  • screenshot1.JPG
    screenshot1.JPG
    78.7 KB · Views: 228
  • SendInput_1630098152003.zip
    4.7 KB · Views: 164

darbid

Registered User.
Local time
Today, 08:47
Joined
Jun 26, 2008
Messages
1,428
The screenshot shows the information bar that comes up when my program clicks on the anchor. When I click on it myself (real person) the information bar doesn't come up and I get the normal File Download box.

The only hope I have for you is that you can manually click it and it is different. My first thoughts are to try to see what the diferences are between you clicking on it manually and you coding the "click"

Then look at the beforenavigate and document complete events and have a look at what URLs are passed, is there a pattern?

Or find the JavaScript function "DownloadAction" and see if you can mimic this function directly, VBA can call functions so you could see what happens if you call it.

If you can get a url that downloads the file then you could use HTTP to download the file to a stream or something like that and then you would have the file.



Code:
'enter date for "Greater than Status Date of:"
    On Error Resume Next
    Do While InStr(popupFrame.documentElement.innerHTML, "InputKeys_COMP_DT") = 0
    Loop
    On Error GoTo 0
    popupFrame.all("InputKeys_COMP_DT").Value = "3/4/2010"
Before I grab values from an excel sheet I also use

Code:
Do: Loop Until xlObj.Ready

You should put a DoEvents in that loop otherwise the CPU will go wild.

By the way
is this you :)

http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/beb6fa0e-fbc8-49df-9f2e-30f85d941fad
 

gypsyjoe11

Registered User.
Local time
Today, 02:47
Joined
Feb 19, 2010
Messages
46
By the way
is this you :)

No it's not me. I recognize it from my research into my problem and it's similar.

Or find the JavaScript function "DownloadAction" and see if you can mimic this function directly, VBA can call functions so you could see what happens if you call it.

How would you go about running the javascript directly. Can you give me an example? I've tried myself without success.

The only hope I have for you is that you can manually click it and it is different. My first thoughts are to try to see what the diferences are between you clicking on it manually and you coding the "click"

Then look at the beforenavigate and document complete events and have a look at what URLs are passed, is there a pattern?

Can you give me an example of how to get info on these events?

You should put a DoEvents in that loop otherwise the CPU will go wild.

It works without it, but it's a good idea. Just because it works without it now, I can't assume that it will forever.

If you can get a url that downloads the file then you could use HTTP to download the file to a stream or something like that and then you would have the file.

This I'm not sure how to do since there is not a link for it on the page. The javascript opens it up.

Another possibility that I haven't really looked into is making XML server requests and passing cookies around with milk.

Code:
Dim XMLHTTP As Object
Set XMLHTTP = CreateObject("MSXML2.serverXMLHttp")

http://answers.google.com/answers/threadview/id/770960.html
 

darbid

Registered User.
Local time
Today, 08:47
Joined
Jun 26, 2008
Messages
1,428
because you are working on an intranet site you are again on your own.

1. Download the file - I have never done it for a file so I would suggest google it like I would. HTTP is one way and you will find lots of examples on that. This might be another way http://www.vb-helper.com/howto_read_url_without_inet.html

2. Executing that javascript function. What you have to understand is that clicking the HTML and executing the function might not be the same thing. But you can try - You need to look at "execScript"

myHTMLDoc.parentWindow.execScript("functionName(" & variable & "," & _
variable & ",'" & variable & "')", "Jscript")

3. BeforeNavigate2 and Document complete these are 2 events of the Webbrowser.
Because you are using IE and not the Webbrowser Control you are going to have to set up a listener.

You currently have "Dim myWebBrowser as Webbrowser" or something like this. You need to take this out and put it at the top with "Public WithEvents myWebBrowser as Webbrowser". When you do this then you should now have in the VBEditor dropdown list "myWebbrowser" and then when this is choosen in the right hand one all the events.

Code:
Private Sub myWebbrowser_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
The interesting thing to get is the pDisp stuff but also the Postdata

Code:
Private Sub wb_ipas_Main_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Code:
   Dim TestString As String
Dim testa As Integer

    If Len(PostData) <> 0 Then
        Dim MyVar As Variant
    
        MyVar = PostData
        If VarType(MyVar) = (vbArray Or vbByte) Then
            Dim Bytes() As Byte
            Bytes = MyVar
            TestString = ""
            For testa = 1 To 500
              If Bytes(testa) = 0 Then Exit For
              TestString = TestString + Chr(Bytes(testa))
            Next testa
            
        Debug.Print "POST DATA - " & URL & " Post-" & TestString & " Flag-" & flags & " Header-" & Headers & " Target-" & TargetFrameName
         
        End If
    End If
These events are going to fire a number of times when clicking, depending on what is happening. If you follow the URL and posts you might see that when you go to download this file it "POST" or "GET" information. This too can be down with HTTP directly.
 

gypsyjoe11

Registered User.
Local time
Today, 02:47
Joined
Feb 19, 2010
Messages
46
2. Executing that javascript function

This works but has the same problem with bringing up the information bar.

Is there a way to access the events without putting IE inside a form? I don't want to have to re-write the whole thing to account for it being inside another window.

Right now I'm creating a new object

Code:
Dim ieObj As WebBrowser
    Set ieObj = CreateObject("InternetExplorer.Application")

I tried making a userform and then putting a webrowser in it and then calling my normal method changing it to

Code:
Set ieObj = UserForm1.WebBrowser1

but then the APIs for findWindow and all the others crash.

If there was a way to access the IE events without a form then it would be ideal.
 

darbid

Registered User.
Local time
Today, 08:47
Joined
Jun 26, 2008
Messages
1,428
By the way.

That loop above that I commented on with a Doevents.

What happens if the internet site never loads for whatever reason? It happens.

I would also suggest you put a counter in there to exit the loop and throw an error message.

Also I have noticed that if you use the webbrowser control it does not have the warnings about running scripts :) (I know you do not want to use it but here is another reason to.) I am on a heavily Administered computer and all the security settings of IE are greyed out. I cannot change anything. But the Webbrowser control allows me to do things.
 

Users who are viewing this thread

Top Bottom