Advanced COM

Now, going back to the InternetExplorer.Application that we located in the registry earlier, we can take a look at how we can script IE using PHP. Remember that this is all on the server-side, being run locally - we're not scripting client machines here, as that is not possible in this way.

There are also a few other neat things that can be done with WSH, and this next script combines advanced WSH topics with the InternetExplorer.Application component. Do not worry about it is length; it is mostly demonstrating the various properties that can be set.

<?php
    $shell = new COM("WScript.Shell");
    $shell->popup("Now launching IE...", 30, "Executing COM code", 64);

    $browser = new COM("InternetExplorer.Application");
    $browser->navigate("about:blank");

    $network = new COM("WScript.Network");
    $sys = $shell->environment('SYSTEM');
    $CPU = $sys->item('PROCESSOR_IDENTIFIER');

    $browser->Visible = true;
    $browser->Width = 700;
    $browser->height = 380;
    $browser->resizable = false;
    $browser->document->title = "Hello, PHP!";
    $browser->document->body->innerhtml = <<<EOT 
    <html>
    <body>
    <h1 id="title">COM and PHP</h1>
    <p id="maintext">
    This is a test of COM and PHP.<br /><br />
    We can instantiate lots of different objects with COM, and read in their variables as if they were normal PHP objects.<br /><br />
    For example, you are currently logged on as {$network->username} on computer {$network->computername}, a $CPU.<br /><br /></p>
    <input type="text" id="mytxt" size="80"/>
    </body>
    </html> EOT;
    $browser->document->all->title->style->csstext = "font: 26px Verdana; color: blue";
    $browser->document->all->maintext->style->csstext = "font: 12px Verdana; color: #333333";
    $browser->document->all->mytxt->focus();

    $shell->appactivate("Internet Explorer");
    $shell->SendKeys("We have complete control over the IE window");

    $shell = null;
    $browser = null;
    $network = null;
?>

That script can be broken down into several bite-size chunks to make it easier to understand. As you can see, this is much more advanced than just running Notepad, but let's go back through the script and explain how it works:

$shell = new COM("WScript.Shell");
$shell->popup("Now launching IE...", 30, "Executing COM code", 64);

The first two lines instantiate the same WScript.Shell component as before, but this time the popup() function is called. This brings up a message box containing the text specified in parameter one, with the title specified in parameter three. Parameter two is the number of seconds the box will stay on screen for, and parameter four is the type of box to show - an integer value that is the same as the numbers used in the main Win32 API.

Again, covering the various values of the fourth parameter is out of the remit of this book, so I suggest you look it up - there is full documentation for the various parameters on the MSDN site again. Just this once, however, I will give you a head start:

Value

Description

0

Show OK button

1

Show OK and Cancel buttons

2

Show Abort, Retry, and Ignore buttons

3

Show Yes, No, and Cancel buttons

4

Show Yes and No buttons

5

Show Retry and Cancel buttons

16

Show critical error icon

32

Show question icon

48

Show exclamation icon

64

Show information icon

Popup() can return several values, to tell you what the user did:

Value

Description

-1

User did nothing; box timed out with parameter two

1

User clicked OK

2

User clicked Cancel

3

User clicked Abort

4

User clicked Retry

5

User clicked Ignore

6

User clicked Yes

7

User clicked No

$browser = new COM("InternetExplorer.Application");
$browser->navigate("about:blank");

In the code above, a new Internet Explorer application component is created, which is the all-encompassing component that handles IE. IE is itself made up of several other COM components, all of which are brought together in InternetExplorer.Application - if you have ever tried dropping the MSHTML web browser component into a VB/C++/Delphi project, then you are effectively just doing what InternetExplorer.Application does.

Navigate() is a function of InternetExplorer.Application, and instructs the component to browse to the location specified by the parameter passed to it. Again, Microsoft usually maintains complete documentation for their controls online - the Visual Basic reference is very easy to read, and can be applied directly to PHP. The Internet Explorer reference, at the time of writing, can be found at http://msdn.microsoft.com/workshop/browser/webbrowser/reflist_vb.asp.

In the example code, navigate() is called so that the browser will load about:blank, the default, blank Internet Explorer page. If you do not call navigate(), the IE browser will not load any HTML document - why this is bad will be explained soon.

$network = new COM("WScript.Network");
$sys = $shell->environment('SYSTEM');
$CPU = $sys->item('PROCESSOR_IDENTIFIER');

Here a new component is used, WScript.Network. This offers a variety of nuggets of information about the local network configuration, and also allows more complex operations such as mapping network drives. This is used later, but stored away in $network for now.

The other two lines used the environment() function of WScript.Shell to grab information about the system configuration. Note that the SYSTEM environment options may only work with NT-based operating systems, such as Windows NT, 2000, and XP. The environment() function returns computer information about the topic passed in parameter one - in the example, we grab the hardware information, and then use it to set $CPU to the current processor identifier. This is used later also.

$browser->Visible = true;
$browser->Width = 700;
$browser->Height = 380;
$browser->Resizable = false;

Here we set various parameters of the InternetExplorer.Application component - that code will set its width and height to particular values, stop it from being resized, and show it. If Visible is not set, the IE window will remain hidden - try moving the Visible command around to see the various effects it has on the way it appears.

$browser->document->title = "Hello, PHP!";
$browser->document->body->innerhtml = <<<EOT <html>
<body>
<h1 id="title">COM and PHP</h1>
<p id="maintext">
This is a test of COM and PHP.<br /><br />
We can instantiate lots of different objects with COM, and read in their variables as if they were normal PHP objects.<br /><br />
For example, you are currently logged on as {$network->username} on computer {$network->computername}, a $CPU.<br /><br /></p>
<input type="text" id="mytxt" size="80"/>
</body>
</html>
EOT;

The first line here sets the title of the document inside the IE component. Now, if you recall from earlier that we used navigate() to go to a blank page - this is why. If we hadn't navigated to a blank page, $browser->document would not exist, because by default IE has no document. By navigating to about:blank, we loaded the default empty document, which is why we can now set its title.

Continuing on, $browser->document->body is the main body content of the document - essentially what users see. The innerhtml property of that document is the actual textual content that works behind the scenes to display the content - this is where we can pump in our own HTML.

As the page is quite complex and also uses a few variables too, the example script uses heredoc syntax to set the HTML content to the given text. There are a few key points about the HTML:

  • Various elements have ID tags. These give us easy-to-find references in the document object model (DOM) later on

  • The $network variable set up earlier is now being used to print out the username and computer name currently being used. This is there simply to show off another COM component

  • The $CPU variable, also set up earlier, is in there too, again to demonstrate the possibilities with COM.

Other than those three, everything else is easy.

$browser->document->all->title->style->csstext = "font: 26px Verdana; color: blue";
$browser->document->all->maintext->style->csstext = "font: 12px Verdana; color: #333333";
$browser->document->all->mytxt->focus();

The first two function calls are really just icing on the HTML cake. As you can see, the control offered by IE extends deep - those two lines of code let us directly enter CSS code to use for the objects in the HTML document.

The third line sets the focus inside IE to the text box - this becomes important in a moment. Note that all three lines use the ID attribute defined in the HTML.

$shell->appactivate("Internet Explorer");
$shell->SendKeys("We have complete control over the IE window");

Here we call the appactivate() function of $shell, which takes the name of the window to activate, and brings it to the forefront. It uses a fuzzy search match based upon the window title, so "Internet Explorer" should find our newly opened IE window and bring it to the front. As we previously called mytxt->focus(), the appactivate() line has the effect of placing the system caret, where text will be typed if the user hits the keyboard, in the text box mytxt.

Following on from appactivate() is a call to SendKeys(), a function that mimics user input. SendKeys() takes the keys to "press" as its parameter, and "types" those keys in as if the user was doing so themselves. As the IE window is active, and the mytxt text box has focus inside there, SendKeys() will type its text into the text box.

$shell = null;
$browser = null;
$network = null;

Finally, we clear up all the references we created in order not to waste system resources. That finishes the script - it isn't so complicated after all, and should really give you a good taster of how much control COM gives you over a system.

If you managed to understand that script completely, you pretty much know all you need to work smoothly with COM. You can, of course, use your own custom COM components in place of the pre-built ones, and the syntax is the same.

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: The possibilities of COM >>

Previous chapter: Basic COM

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.