Using the Windows COM in PHP


Occasionally, when developing a desktop application or service in PHP, you’ll need to delegate tasks to components of Windows. This is where COM comes in. Luckily, PHP has had working COM support for several years.

What is COM?

The best description of COM, in this context, comes from the PHP documentation:

“COM is an acronym for Component Object Model; it is an object orientated layer (and associated services) on top of DCE RPC (an open standard) and defines a common calling convention that enables code written in any language to call and interoperate with code written in any other language (provided those languages are COM aware). Not only can the code be written in any language, but it need not even be part of the same executable; the code can be loaded from a DLL, be found in another process running on the same machine, or, with DCOM (Distributed COM), be found in another process on a remote machine, all without your code even needing to know where a component resides.”

For the purposes of this post, I’d simplify that to the following:

COM defines a means of manipulating Windows applications and services which is independent of any programming language. As well, it provides a means to expose an interface to other applications to allow them to manipulate your application or service.

What Can I Do?

COM is especially useful for dealing with Microsoft-developed applications such as the Windows Registry, Internet Explorer, Office applications, and so on. Without COM, it is nearly impossible to elegantly interface with these applications in any meaningful way.

In this post, I’ll detail a few use-cases, with some example code, and provide some tools that will make developing your own applications easier.

Important Resources

OLE/COM Object Explorer:

OLE/COM Object Explorer provides detailed information about every “Object Class”, “Application ID”, “Type Library” and “Interface” exposed by COM on the Windows system. It is essential for COM application development.

MSDN Library:

MSDN Library provides (somewhat poor) documentation for a number of important COM objects, such as InternetExplorer, Word, etc. It’s not essential that you use this, but it can augment your understanding that you would otherwise gain from inspecting the Object signature.

com_print_typeinfo:

The com_print_typeinfo function in PHP will output a skeleton class of a COM Object, which can provide some useful information regarding the signature of that Object. This is the primary way that you will want to inspect COM Objects.

Wikipedia’s COM Article:

This article does a decent job of explaining some of the fundamentals of dealing with COM. Specifically, the Technical Details section is of particular help.

Terminology

COM is very-much-so designed in Object-Oriented style, so the terminology is all fairly straightforward if you are familiar with PHP’s OOP style.

Class

Each application is referred to as a class. This is similar to a Class in PHP, where the Object is an instance of a particular Class. It is a wrapper of sorts for all of the various methods that are exposed.

Interface

An interface defines what methods a particular class implements. Knowing which interfaces a class implements, you can know which methods are available and how they’re invoked.

Type Library

A type library defines a set of interfaces which a class implements.

GUID / Application ID

A GUID is a unique identifier that can be used to refer to an application or interface, rather than by object or interface name.

Useful Application Classes

InternetExplorer.Application

This COM Object provides an interface to Internet Explorer, which can be used to spawn a browser window, cause it to navigate, and trigger any number of events that the browser provides, such as printing.

Previously, I’ve used Internet Explorer as a quick and dirty rendering engine for report generation and printing. I’ll detail that process in one of the examples.

WScript.Shell

This COM Object provides an interface to a number of integral mid-level functions in Windows, such as registry access, shortcut creation and accessing system folders.

I’ll detail how to get and set registry values in one of the examples.

Excel.Application

This COM Object provides an interface to Microsoft Excel, which can be used to create Excel spreadsheets without having to rely on a third-party library.

The Basics in PHP

Before we get to any examples, let’s cover some of the basics of working with COM in PHP.

In the vast majority of situations, all you will need to do to access a COM Object is instantiate the COM class, with the name of the COM Object Class as the single parameter. Doing so should create an overloaded object with all of the methods of the Class.

If you would like to see what methods are exposed by the object, you can simply use com_print_typeinfo as mentioned earlier. This will output a signature for the class.

Lastly, you may wish to “sink” an events interface for the application you’re interfacing with. What this means is that you can create a class with methods that will be called when certain events occur (are dispatched) in the application. For instance, you may wish to sink the “ProgressChange” event in Internet Explorer’s DWebBrowserEvents2 interface, which will call your specified class method every time a download’s progress changes.

Examples (finally)

Here are a few examples of things you can do with COM.

Rendering and Printing a Report Using Internet Explorer

Could not embed GitHub Gist 1352618: Not Found

Change Your Windows Wallpaper Using the Registry

Could not embed GitHub Gist 1352618: Not Found

          
  1. #1 by Dhaval on January 30, 2013 - 10:35 pm

    Hi Justin,

    Thanks for a good information about COM. I’m a PHP programmer with 2+ yrs of experience. Now a days I need to use this class for practicing over the server but I do have linux server. Am I able to to do this on my server? My server is having PHP 5.2.17 and I tried it on local too which is having PHP 5.3.5 but its not running.

    Can you please tell me how to run it on Live and Local,do I need to do any settings in configuration or anything?

    Thanks,
    Dhaval

    • #2 by Justin Martin on January 30, 2013 - 10:38 pm

      Hi Dhaval,

      COM is specific to the Windows platform. It doesn’t really exist in Linux. You might be able to get it going in Wine on Linux, but it definitely does not exist in PHP on Linux generally.

      Thanks,
      Justin

      • #3 by Dhaval on January 31, 2013 - 2:30 am

        Hi Justin,

        Thanks for the reply. I want to access DLL file using PHP so can you suggest me any other way to do it or is there any other object / class or anything else to do it?

        Thanks,
        Dhaval

  2. #4 by Dhaval on February 1, 2013 - 1:24 am

    Hi Justin,

    I tried to run your above script to change the wallpaper but its giving me below Error:

    Fatal error: Uncaught exception ‘com_exception’ with message ‘Source: WshShell.RegReadDescription: Unable to open registry key “HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper” for reading.’ in D:\xampp\htdocs\test\desktop_programming\changewallpaper.php:3 Stack trace: #0 D:\xampp\htdocs\test\desktop_programming\changewallpaper.php(3): com->RegRead(‘HKEY_CURRENT_US…’) #1 {main} thrown in D:\xampp\htdocs\test\desktop_programming\changewallpaper.php on line 3

    Can you tell me what is it about? Also I need to access DLL file, COM is the way but I don’t know if there is any configuration need to be done so please let me know the way, it’ll be really appreciable.

    Thanks,
    Dhaval

  3. #5 by Soeren on April 5, 2013 - 12:50 am

    Hi Justin,

    I followed your tutorials regarding COM tests and they work fine.
    Now i try to modify the report in order to get some data of an excel file and report them.
    -> works fine.

    Do you know if it is possible to work with password protected excel files ?

    now my script looks like:


    $excel_app = new COM(“Excel.application”) or Die (“Did not connect”);
    $Workbook = $excel_app->Workbooks->Open(“$filename”) or Die(“Did not open $filename $Workbook”);
    $Worksheet = $Workbook->Worksheets($sheet1);
    $Worksheet->activate;
    ….

    is there a way to enter a password in the COM ?

    many thanks for your tutorials and help!

  4. #6 by Raj on July 11, 2013 - 5:51 am

    Hi,
    Nice post.

    I have an issue with consuming Ranger ocx (sbullet.com cheque scanner api) with PHP.
    I am looking to initiate Ranger Scanner with php com, but failed to do so.
    Can you please provide information on this?

    Thanks

  5. #7 by Dario on September 17, 2013 - 7:46 am

    Hi Justin,

    I’m trying to open a Access report through a PHP COM object, but i donĀ“t know if it is possible?

    I also tried the code to print all methods, but nothing (com_print_typeinfo)… server gives to me error timeout!

    Do you know what i’m doing wrong?

    Thanks for your attention!

    Best regards

(will not be published)
*