1
votes

I'm using Win32::OLE under Perl to steer Internet Explorer. When I navigate to a remote URL, everything works as you would expect - I wait while $IE->{Busy} == 1, then I can query {ReadyState}, etc.

But when I do the exact same thing with a local file, then right after {Busy} is no longer true, I can get one {ReadyState} query in before OLE seems to lose contact with the IE instance, after which nothing works. In one configuration I managed to get Win32::OLE->QueryObjectType to tell me that "The object invoked has disconnected from its clients" - but I haven't been able to get that to happen again, and it seems to be a very catchall function to start with (Google results seem all over the map and essentially look like "something went wrong with a pointer somewhere").

I'm not even sure how to look any closer at what's going on under the hood. Any ideas? My vague intuition is that IE is creating a new object in there somewhere and this is not getting attached to Perl's OLE object or ... something. It could be that I can use OLE events to capture something along the way.

edit: The code is essentially as minimalistic as humanly possible:


    $Win32::OLE::Warn = 0; 
    my $IEbrowser = Win32::OLE->new('InternetExplorer.Application'); 
    $IEbrowser->navigate("file:///c:/projects/wftk/IEMech/Win32-IE-Mechanize/t/formbasics.html");
    #$IEbrowser->navigate("http://www.vivtek.com");     
    while (($IEbrowser->{Busy} == 1)){ 
        sleep(0.1); 
    }

    print "There you go!\n"; 
    print $IEbrowser->{ReadyState} . "\n";
    sleep(1);
    $IEbrowser->{Visible} = 1;
    print $IEbrowser->{ReadyState} . "\n";

There is essentially no other way to get IE to go to a file than this; a quick scan of IEAutomation shows me that it does exactly the same thing, which is unsurprising.

Anyway, after retrieving the local file (which, as you will see, is one of the test files for Win32::IE::Mechanize), the first call to {ReadyState} returns a zero, then after sleeping another second, both of the next two calls fail. If I instead retrieve the home page of my own site, it works fine, returning a ReadyState of 3 on the first call and 4 on the second, as expected.

This is driving me crazy. I am at an utter loss. I'm on 64-bit Windows 7 running IE 10.0.9200.16721, although I can't imagine why that could possibly make a difference.

Update: Aha, turns out that as of IE8, IE "sometimes" opens a new process when navigating to a new page, and that this has something to do with their trust model.

Essentially, to make this simple navigation work, I will have to catch that event and build a new OLE object from it - basically IE is creating new IE that does the navigation, and the old OLE object that Perl is tracking with Win32::OLE closes silently. The browser frame is unaffected.

There's a Registry key that can force all IE navigation to stay within a single frame, but I don't really want to mess with that.

Oh, Microsoft, must you always overcomplicate everything?

MSDN link:
MSDN article touching on this - this is why I left the Windows programming world in the first place.

1

1 Answers

0
votes

Nothing comes to mind for this problem, maybe posting the code your trying would help. I've controlled local pages like this using Win32::IEAutomation which uses Win32::OLE without any issue, maybe it utilizes Win32::OLE in a different way than you are.