traviss has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I have searched and searched to no avail... not surprising, I'm doing some kinda weird stuff.
I'm using Win32::OLE for this. Basically, what I want is the document object (IHTMLDocument2 Interface, http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/document2/document2.asp) but I need to get it from frames. I can get it fine from NON-frames.
First, here's the error. BTW, I only see this on some PCs, not all. I have 4 that are working and 3 not.
Uncaught exception from user code: OLE exception from "<Unknown Source>": Invalid access to memory location. Win32::OLE(0.1702) error 0x80020009: "Exception occurred" in METHOD/PROPERTYGET "document" at C:\Scripts\this.pl line 69 at C +:/Perl/site/lib/Win32/OLE/Lite.pm line 216 Win32::OLE::Tie::FETCH('Win32::OLE::Tie=HASH(0x1c0e754)', 'docu +ment') called at C:\Scripts\this.pl line 69

And now a code snippet: (everything before this is reused a lot, and works fine... and is broken up into multiple modules that will mean nothing unless I post the modules)
my $IEDoc = $IEWin->{Document}; my $frames = $IEDoc->{frames}; my %frameshash; for (my $i = 0; $i < $frames->{length}; $i++) { $frameshash{$frames->{$i}->{name}} = $frames->{$i}; } foreach my $key ( keys( %frameshash ) ) { print "\n".$key."\n"; print $frameshash{$key}->{document}->{body}->{innerHTML}."\n"; }
The line, specifically, that is crapping out is the 2nd to last, where I attempt to print innerHTML. The reason being, I CANNOT access the document portion. Any help would be appreciated, thanks!

Replies are listed 'Best First'.
Re: Error trying to get the document object from a frame
by InfiniteSilence (Curate) on Sep 14, 2005 at 23:20 UTC
    I think you need to post a bit more of your code. I am guessing that you are generating the Internet Explorer object like this:

    #!/usr/bin/perl -w use strict; use Win32::OLE; my $IEWin = Win32::OLE->new('InternetExplorer.Application'); $IEWin->{Visible} = 1; $IEWin->Navigate2('file:///c:/temp/jsFrameset.htm'); my $IEDoc = $IEWin->{Document}; my $frames = $IEDoc->{frames}; ...
    But with this code I get an error much sooner...the frames collection cannot be retrieved from the Document object reference. This is really weird, because I can call all sorts of other things defined there:

    DB<1> x $IEDoc->{URL} 0 'file://C:\\Temp\\jsFrameset.htm' DB<2> x $IEDoc->{fileSize} 0 118 DB<3> x $IEDoc->{fileModifiedDate} 0 '09/02/2005' DB<4>
    But the frames collection eludes me. BTW, why do you want to do this? I ask because there may be a way to do it without this automation code at all.

    Celebrate Intellectual Diversity

      Hi, thanks for the reply! Your guess is pretty much spot on.
      This is not an exact code snippet, since this is spread out through other modules, but it is exactly what's happening, and this time, is fully working code:
      #!/usr/bin/perl -w use strict; use warnings; use diagnostics; use Win32::OLE qw(in with EVENTS); my $URL = 'http://www.pageresource.com/html/frameex5.htm'; my $IEWin = ''; my $IEObject = undef; my $Class = 'InternetExplorer.Application'; $IEWin = Win32::OLE->new +( $Class ) || die "Can not obtain a $Class object\n"; $IEWin->{visible} = 1; $IEWin->Navigate($URL); my $wait = 300; until ( $IEWin->{Busy} != 1 || $wait <= 0 ) { $wait--; sleep 1; } my $IEDoc = $IEWin->{Document}; my $frames = $IEDoc->{frames}; my %frameshash; for (my $i = 0; $i < $frames->{length}; $i++) { $frameshash{$frames->{$i}->{name}} = $frames->{$i}; } foreach my $key ( keys( %frameshash ) ) { print "\n".$key."\n"; print $frameshash{$key}->{document}->{body}->{innerHTML}."\n"; }

      And yes, it IS weird. With good consistancy, once in a frame we can access everything but 'document' and 'frames'. The frames element I don't care about (since I'm already in the lower most frame) but document is fairly important :)
      Why do this? For automation consistancy. We (note I've changed from "I" to "we" :p ) have a number of perl scripts and modules for automation. Not everything is necessarily for web pages. The method we're using isn't important, but the end result is. We need the document object so we can go automation crazy on it.
      Like I said earlier, the really strange part is this works perfectly fine on 4 computers, but not at all on 3 computers. This is a mix of (Windows) OSs and IE versions, and we just can't nail down any consistancy.
      Aha, my dear Watson...your problem (it seems) is the timeout. Here I will comment it out completely:

      my $wait = 300; #until ( $IEWin->{Busy} != 1 || $wait <= 0 ) #{ # $wait--; # sleep 1; #}

      perl iestuff.pl Win32::OLE(0.1701) error 0x80020009: "Exception occurred" in METHOD/PROPERTYGET "Document" at iestuff.pl line 22 Use of uninitialized value in numeric lt (<) at iestuff.pl line 26 (#1 +) ....yadda yadda..

      Now I'll put it back in:

      left_frame <CENTER>This is page1.htm from the example. <BR><BR>Click the link bel +ow to change both frames. <BR><A href="javascript:change2()">Change 2 + Frames</A> <P> <HR> ...yadda...

      Note that on different machines you will probably have to INCREASE that timeout. Looks like some objects take longer in IE to properly load. You might consider delving deeper into the IE object model to query the actual status of certain objects before proceeding with the code rather than guessing at the correct timeout.

      Try and increase that timeout and reply if it works.

      Celebrate Intellectual Diversity