Windows Scripting
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
Go Back   ASP Free ForumsSystem AdministrationWindows Scripting

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread ASP Free Forums Sponsor:
  #1  
Old August 26th, 2009, 04:33 AM
javaman javaman is offline
Contributing User
ASP Free Newbie (0 - 499 posts)
 
Join Date: Jul 2007
Posts: 33 javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 9 h 27 m 59 sec
Reputation Power: 5
WSH - Accessing DHTML elements from outside

I'm trying to create a script that will wait till Internet Explorer starts. Then it will access its windows and be able to, lets say, get rid of certain pictures that I don't want.
Using WMI, I think I can get the handle of a new process. I don't know if that will help me. Furthermore, if I have the hWnd of an IE window can I access the HTML inside it somehow using the Shell.Application?

Reply With Quote
  #2  
Old August 30th, 2009, 10:56 AM
Nilpo's Avatar
Nilpo Nilpo is offline
ASP Free Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2006
Location: Salem, OH
Posts: 1,880 Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)  Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1
Time spent in forums: 1 Week 2 Days 8 h 47 m 8 sec
Reputation Power: 967
Send a message via ICQ to Nilpo Send a message via AIM to Nilpo Send a message via MSN to Nilpo Send a message via Yahoo to Nilpo Send a message via Google Talk to Nilpo Send a message via Skype to Nilpo Send a message via XFire to Nilpo
Facebook MySpace Orkut
Let me just say that this is an awesome question although complicated in nature. Luckily, the Windows Guru has a solution just for you.

Let's approach this in two parts:
  1. The script should wait until Internet Explorer starts.
  2. Then it should grab the instance of Internet Explorer and provide access to its Document Object Model (DOM).

Creating an event-driven WMI script to watch for a new process:

WMI provides a little known facet that allows you to write event-driven scripts that react to the occurrence of a specified event rather than executing linearly as soon as the script is launched. Let's look at how to watch for the creation of an instance of the Iexplore.exe process which indicates that Internet Explorer has been launched.

To begin, you'll need to have a basic understanding of how events work in WMI. Your script will create an event consumer. This is basically a listener that waits for notification that a specific event has occurred. WMI will trigger event notifications for a few basic event types. This is beyond the scope of this post so I will only refer to the specific event we'll be using. For more information on WMI event scripting, please read my article series here on ASP Free that explains this in more detail.

Event Scripting with WMI

More Event Scripting with WMI

WMI has an intrinsic event called __InstanceCreationEvent that is triggered whenever a new instance is added to the WMI namespace. As you may well know, WMI's Win32_Process class houses instances of currently running processes. So each time a new process is launched, a new instance of the Win32_Process class is added to WMI's namespace resulting in an __InstanceCreationEvent trigger. By monitoring this event, a script can be notified any time a specific process is started.
vb Code:
Original - vb Code
  1. strComputer = "."
  2. Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Your script will start off in a familiar fashion by connecting to an instance of the WMI Service. VBScript's GetObject connects using the winmgmts: moniker, the WMI Service returns an SWbemServices Object. This is the object that allows you to interact with the Windows Management Instrumentation Service on your computer. Traditionally, we would then use the ExecQuery method to return some kind of data collection from WMI. However, this is where our script takes a little turn. We're not interesting in polling WMI for data; we're looking to monitor its events through an event consumer. To do that we'll need to use the SWbemServices Object's ExecNotificationQuery method instead.
vb Code:
Original - vb Code
  1. Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
  2.     ("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE " _
  3.         & "Targetinstance ISA 'Win32_Process' and " _
  4.             & "TargetInstance.Name='Iexplore.exe'")
The ExecNotificationQuery method returns an SWbemEventSource Object which acts as an event consumer. This object acts like a collection that is updated with each new instance of the event we're monitoring. It provides a NextEvent method that will wait for an event to occur and then return an instance of that event as an SWbemObject. In short is means that it returns the class instance that we're monitoring. In this case, it will return the Win32_Process class instance for the newly created process. It should be understood that it doesn't return this instance directly. Rather, it points to it. The SWbemObject has a TargetInstance property that references the instance we're looking for. So where we would normally have a Win32_Process object, we'll now have that object by means of the TargetInstance property.
vb Code:
Original - vb Code
  1. Do While True
  2.     Set objEventObject = colMonitoredEvents.NextEvent()
  3.     strOut = objEventObject.Path_.Class & vbCrLf _
  4.         & "Process Name: " & objEventObject.TargetInstance.Name & vbCrLf _
  5.         & "Process ID: " & objEventObject.TargetInstance.ProcessId & vbCrLf _
  6.         & "Time: " & Now
  7.     WScript.Echo strOut
  8.     Exit Do
  9. Loop
Because this event consumer will continually listen for new events, the WMI script will run indefinitely (or until the WMI Service is stopped). So to continually grab new instances of the event as they occur, we'll wrap our code in an infinite loop using the Do While True syntax. (In this example code, I've explicitly added Exit Do to end the script after the first event is handled. You'll likely want to remove this from your own application.)

In the sample code above, I've demonstrated how you can use this WMI event script. Run the code and then open Internet Explorer. As soon as the program starts, WMI fires the event and the script begins to work displaying a message box with some information about the target process. As you can see, you can retrieve the Hwnd (window handle) for the new instance of Internet Explorer as per your question. You probably won't need it though as you'll soon see.

Okay, let's put this script to work now. You're going to remove everything inside of the Do loop above and place any functioning code you need in its place. Let's address the second part of your question and then I'll show you how you can put the two together.

Capturing instances of Internet Explorer:

Ordinarily you would capture a running process using VBScript's GetObject method. However, it's a bit restrictive in that it doesn't allow you to specify between multiple instances of the same application. In fact, it will usually result in an error if you try. Luckily, the Shell Automation Object provides us with an alternative. It's Windows method returns a ShellWindows Object that represents a collection of Explorer Shell windows. Due to Internet Explorer's close integration with the Explorer Shell, instances of Internet Explorer are also treated as Shell Windows. Each object in the ShellWindows Object collection is an Internet Explorer Object whose Document property gets an instance of the active document's automation object. Nicely enough, this is functionally equivalent to the Document object you would access from a script within the browser.

WMI triggers an event as soon as the process is created. This doesn't imply that the program is running or even functional yet. It's very important that you monitor the Internet Explorer Object's Busy property and do not attempt to access the object before it is fully initialized.
vb Code:
Original - vb Code
  1. Set objShell = CreateObject("Shell.Application")
  2. Set colIEWindows = objShell.Windows
  3. For Each objIEWindow In colIEWindows
  4.     Do While objIEWindow.Busy
  5.         WScript.Sleep 200
  6.     Loop
  7.    
  8.     Set objIE = objIEWindow.Document
  9.    
  10.     If Not objIE Is Nothing Then
  11.         Do Until objIE.ReadyState = "complete"
  12.             WScript.Sleep 200
  13.         Loop
  14.         WScript.Echo objIE.Title
  15.     End If
  16. Next
This example demonstrates the complete code for accessing the currently running instance of Internet Explorer and waiting for it to initialize completely. It then waits for navigation to complete and displays a message box containing the active document's title.

Notice that I've enclose the latter portion of the script in an If statement that checks that the Document object exists. This is a precautionary measure that will prevent your scripts from breaking under certain circumstances. The Document property WILL NOT return an object if Internet Explorer's script securities are set too high!

Now that you've seen both parts of this script, let's see what the whole thing would look like together.
vb Code:
Original - vb Code
  1. ' Connect to WMI
  2. strComputer = "."
  3. Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
  4.  
  5. ' Create an Event Consumer
  6. Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
  7.     ("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
  8.         & "Targetinstance ISA 'Win32_Process' and " _
  9.             & "TargetInstance.Name='Iexplore.exe'")
  10.  
  11. Do While True
  12.     ' Wait for an event to occur
  13.     Set objEventObject = colMonitoredEvents.NextEvent()
  14.     ' Discard the unnecessary event object
  15.     Set objEventObject = Nothing
  16.    
  17.     ' Connect to the Shell Automation Object
  18.     Set objShell = CreateObject("Shell.Application")
  19.     ' Retrieve instances of Internet Explorer
  20.     Set colIEWindows = objShell.Windows
  21.    
  22.     For Each objIEWindow In colIEWindows
  23.         ' Wait for Internet Explorer to initialize
  24.         Do While objIEWindow.Busy
  25.             WScript.Sleep 200
  26.         Loop
  27.        
  28.         ' Retrieve the Active Document Automation Object
  29.         Set objIE = objIEWindow.Document
  30.        
  31.         ' Fail-safe in case security is set too high
  32.         If Not objIE Is Nothing Then
  33.             ' Wait for any navigation to complete (and the DOM to initialize)
  34.             Do Until objIE.ReadyState = "complete"
  35.                 WScript.Sleep 200
  36.             Loop
  37.             ' Perform any necessary functions
  38.             WScript.Echo objIE.Title
  39.         End If
  40.     Next
  41.    
  42.     ' Perform a little cleanup since the script runs indefinitely.
  43.     ' No need clogging up memory with unnecessary objects.
  44.     Set objIE = Nothing
  45.     Set objIEWindow = Nothing
  46.     Set objShell = Nothing
  47.    
  48.         ' Optionally you can uncomment the next line if you only want
  49.         ' the script to process a single instance and then end.
  50.     'Exit Do
  51. Loop
Comments on this post
Shadow Wizard agrees: excellent stuff
mystic7 agrees: Excellent use of paragraphs and font formatting
__________________
Don't like me? Click it.

Scripting problems? Windows questions? Ask the Windows Guru!

Stay up to date with all of my latest content. Follow me on Twitter!

Help us help you! Post your exact error message with these easy tips!

Reply With Quote
  #3  
Old September 4th, 2009, 01:31 PM
javaman javaman is offline
Contributing User
ASP Free Newbie (0 - 499 posts)
 
Join Date: Jul 2007
Posts: 33 javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level)javaman User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 9 h 27 m 59 sec
Reputation Power: 5
Thank you very much. Actually being that there was no response for a long time, I looked all over the place and came up with pretty much that. In fact I used the .ExecNotificationQueryAsync and _OnObjectReady that you had once told me about.
I actually needed to recall my script through the run(cscript...) because I wanted to monitor IE for the _DocumentComplete event and I read that you cannot use Wscript.ConnectObject for IE if it wasn't loaded with the page. So I started a new script and created IE from fresh and copied the Top, Left, Height, Width, FullScreen, and of course documentUrl from the old IE into the new one.
One thing still needs clarafication however: In case I wanted to double check that the window I'm dealing with is the same as the process just begun, I would want to check TargetInstance.Handle to match IE.HWND. The thing is that actually no property returned by WMI matches the IE.HWND. What is going on?

Reply With Quote
  #4  
Old September 4th, 2009, 01:57 PM
Nilpo's Avatar
Nilpo Nilpo is offline
ASP Free Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2006
Location: Salem, OH
Posts: 1,880 Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)  Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1
Time spent in forums: 1 Week 2 Days 8 h 47 m 8 sec
Reputation Power: 967
Send a message via ICQ to Nilpo Send a message via AIM to Nilpo Send a message via MSN to Nilpo Send a message via Yahoo to Nilpo Send a message via Google Talk to Nilpo Send a message via Skype to Nilpo Send a message via XFire to Nilpo
Facebook MySpace Orkut
Quote:
Originally Posted by javaman
I actually needed to recall my script through the run(cscript...) because I wanted to monitor IE for the _DocumentComplete event and I read that you cannot use Wscript.ConnectObject for IE if it wasn't loaded with the page.
That's correct. The _DocumentComplete event is a DOM event and is not exposed by IE's COM interface.
Quote:
Originally Posted by javaman
One thing still needs clarafication however: In case I wanted to double check that the window I'm dealing with is the same as the process just begun, I would want to check TargetInstance.Handle to match IE.HWND. The thing is that actually no property returned by WMI matches the IE.HWND. What is going on?
I haven't seen the code you're using to clarify, but if you use the code I've shown above, they do match. I tested it.

Reply With Quote
  #5  
Old October 14th, 2009, 06:02 PM
notsure notsure is offline
Registered User
ASP Free Newbie (0 - 499 posts)
 
Join Date: Oct 2009
Posts: 1 notsure User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 5 m 7 sec
Reputation Power: 0
How are you guys running this code?

I tried it in both a .VBS file and a .WSF file and I kept getting the following error message:

Code:
Line: 34

Error: Object doesn't support this property or method: 'objIE.ReadyState'

Code: 800A01B6

Source: Microsoft VBScript runtime error

I am running IE6 on Windows 2000 with .NET 2.0.

Reply With Quote
  #6  
Old October 15th, 2009, 12:20 AM
Nilpo's Avatar
Nilpo Nilpo is offline
ASP Free Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2006
Location: Salem, OH
Posts: 1,880 Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)Nilpo User rank is General (90000 - 100000 Reputation Level)  Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1Folding Points: 214558 Folding Title: Super Ultimate Folder - Level 1
Time spent in forums: 1 Week 2 Days 8 h 47 m 8 sec
Reputation Power: 967
Send a message via ICQ to Nilpo Send a message via AIM to Nilpo Send a message via MSN to Nilpo Send a message via Yahoo to Nilpo Send a message via Google Talk to Nilpo Send a message via Skype to Nilpo Send a message via XFire to Nilpo
Facebook MySpace Orkut
The code was tested on Windows XP. It's possible that it may not be fully supported on Windows 2000 although I wasn't able to find that in the documentation. See if some error handling can get you around that portion of the code.
vb Code:
Original - vb Code
  1.             On Error Resume Next
  2.             Do Until objIE.ReadyState = "complete"
  3.                 WScript.Sleep 200
  4.             Loop
  5.             On Error Goto 0

Reply With Quote
Reply

Viewing: ASP Free ForumsSystem AdministrationWindows Scripting > WSH - Accessing DHTML elements from outside


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump





 Free IT White Papers!
 
How to Present Effectively Online
This white paper offers practical and actionable advice on the key steps that any presenter should consider as they plan and execute a Webinar or online meeting.

 
Open Source Security Myths
Open Source Software (OSS) is computer software whose source code is available to the general public with relaxed or non-existent intellectual property restrictions (or arrangement such as the public domain), and is usually developed with the input of many contributors.

 
Power and Cooling Capacity Management for Data Centers
This paper describes the principles for achieving power and cooling capacity management.

 
Scalable, Fault-Tolerant NAS for Oracle - The Next Generation
For several years NAS has been evolving as a storage alternative for Oracle databases, and for good reason: NAS is quite often the simplest, most cost-effective storage approach for Oracle. Learn about the benefits that HP's approach to scalable NAS brings to Oracle environments in this comprehensive white paper.

 
Understanding Web Application Security Challenges
This white paper discusses many common threats and preventive measures for Web application security, and explains what you can do to help protect your organization.

 

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 Hosted by Hostway
For more Enterprise Application Development news, visit eWeek