Thursday, January 29, 2009

COM/.NET Interop in Zero PHP

Zero doesn't currently support the COM/.NET extension in PHP. 

No matter though, there is a handy open source project called JACOB that bridges between Java and COM/.NET. In fact, there is an easier way to do this using a Groovy library called Scriptom. This is really just a friendly wrapper around JACOB to provide a better syntax for calling methods and accessing properties. 

The aim in this example is to list the processes on a Windows machine - here are the steps to do it in PHP. I'm using the latest Zero download of Sebring and Eclipse PDT as the IDE.

1. Download Scriptom and put the JAR and DLL in the Zero lib directory:

2. Run a resolve step in Eclipse so that the JAR file is added to the class path.

3. Add the following extension to php.ini (if not already there):
extension=com.ibm.p8.engine.xapi.groovy.GroovyExtensionLibrary

4. Copy and paste this code into a PHP script in the public folder:

<?php
define("wbemFlagForwardOnly", 32);

java_import("com.jacob.com.ComThread");
ComThread::InitMTA(true);
groovy_import("org.codehaus.groovy.scriptom.Scriptom");
$locator = new ActiveXObject("WbemScripting.SWbemLocator");
$services = $locator->ConnectServer('.');

$processes = $services->ExecQuery(
  'SELECT * FROM Win32_Process',
  'WQL', wbemFlagForwardOnly);

$total = 0;

// Iterate through the COM collection
foreach ($processes as $current) {
  if (Scriptom::isNull($current->CreationDate) == FALSE) {
$date = new ActiveXObject("WbemScripting.SWbemDateTime");
$date->Value = $current->CreationDate;
$creation = $date->GetVarDate(TRUE);
$command = $current->CommandLine;
$command = (Scriptom::isNull($command) ? "None" : $command);
echo "Process found [".$current->Name.
        " - ".$command."]"; $total++;
  }
}

ComThread::Release();
echo "Found $total processes in all";
?>

Before you say it, yes I agree, the code is really yuck but that's COM for you. 

5. Run the application and point a browser at your script:

If you are curious about what all these crazy objects are, there is lots more information on the Microsoft web site. The example is using Windows Management Instrumentation (WMI) to enumerate the processes.

The calls to ComThread::InitMTA() and Release() are important to make sure Zero doesn't hang. COM has some weird stuff in it to do with apartments and threading.

No comments:

Post a Comment