![]() |
Platforms, Frameworks & Libraries »
COM / COM+ »
Beginners
License: The Code Project Open License (CPOL)
Create an ATL COM DLL and Invoke It through PHPBy Boris ODemonstrates creating a simple ATL COM DLL and invoking it through PHP. |
Javascript, CSS, HTML, XHTML, ASP, ASP.NET, WebForms, Ajax
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||
On occasion you might need to gain greater access from PHP to the underlying operating system. This article demonstrates basic steps of one technique for the mentioned purpose by creating an ATL COM DLL, registering it, and finally invoking it through PHP hosted in the Windows environment running the Apache web server.
In the following steps we will create an ATL COM DLL with a class and two member methods, one that will retrieve the approximate percentage of physical memory in use, and the second one that will restart the host computer.
Visual Studio .NET will now generate the project and we are ready to proceed.
Our new class has now been added and you might notice the system has also generated
an Interface class for us, in this case named IMyClass. As the next step we will add our
two member methods by following the steps below:
GetMemoryLoad for the method nameVARIANT* for the parameter type
The new member method has now been added and as the next step we will add code to it as the next step:
STDMETHODIMP CMyClass::GetMemoryLoad(VARIANT* vtMemoryLoad)
{
// Create an instance of the MEMORYSTATUSEX structure
MEMORYSTATUSEX memstatex;
// Specify the length of the structure
memstatex.dwLength = sizeof(memstatex);
// Call the GlobalMemoryStatusEx function and pass to it
// a reference to our MEMORYSTATUSEX instance
::GlobalMemoryStatusEx(&memstatex);
// Set the ulVal (unsigned long value) of the VARIANT parameter
// passed by reference to the function with the dwMemoryLoad
// value of the MEMORYSTATUEX instance which specifies the
// approximate percentage of the physical memory currently
// in use.
vtMemoryLoad->ulVal = memstatex.dwMemoryLoad;
return S_OK;
}
We will now repeat steps 1-9 in order to add the second function as part of this demo.
RestartHost for the method nameVARIANT* for the parameter typeAdd the following code to the new function:
STDMETHODIMP CMyClass::RestartHost(VARIANT* vtLastError)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
// In order to be able to restart the local computer we need the
// SE_SHUTDOWN_NAME privilege, in the following steps we will
// retrieve the privileges of the current process and enable
// the SE_SHUTDOWN_NAME privilege
if(::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
::LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
// If the adjusting of the privilege succeeded
if(::GetLastError() == ERROR_SUCCESS) {
// Initiate the system restart, note the fourth argument will
// force the shutdown of all applications, when testing please
// ensure that you have no unsaved data as it might be lost.
// The fifth argument will restart the computer.
::InitiateSystemShutdown(NULL, _T("ATL COM DLL/PHP Demo"), 0, TRUE, TRUE);
}
}
// Set the ulVal (unsigned long value) of the VARIANT parameter
// to the value returned by GetLastError as this might be useful in
// troubleshooting.
vtLastError->ulVal = ::GetLastError();
return S_OK;
}
As the next step we will compile the DLL. By default a project remains in Debug mode and after a successful compilation and thorough testing we can switch it to the Release mode before deploying the DLL. We will do so immediately for the purpose of this demo:
This concludes the process of creating our sample ATL COM DLL.
Now that we have created the ATL COM DLL the next step will be to register it so that it is available for use by other applications through the COM interface.
REGSVR32 utility:
REGSVR32 "C:\WINDOWS\system32\ATLDemo.dll"This concludes registering our sample ATL COM DLL and making it available for use by COM aware applications.
In this section of the article we will write a PHP page that will invoke our newly created ATL COM DLL and make use of it. Please note that at this point it is assumed that you have an Apache web server running in the Windows environment. In this demo the Apache web server is run as an executable under an account that has full administrator privileges. Security settings might present an obstacle depending on your configuration of the web server, e.g. if you are running the Apache web server as a service under an account with insufficient privileges to be able to create a COM objects you would have adjust the privileges for that account. The same applies to running IIS instead of Apache however as this is a simple concept article the security settings will not be discussed in detail.
PHP for Windows in its core features the ability to invoke COM object. For details please see http://us.php.net/com.
Our first step will be to identify the Prog ID for our class in order to be able to
instantiate the instance of the class; the easiest technique will be by accessing the
registry and learning the value:
REGEDITHKEY_CLASSES_ROOT locate the name of the DLLATLDemo.MyClassNext, we will write the PHP code that will create an instance of the class, immediately display the approximate percentage of the available physical memory and offer the ability to restart the host computer.
<?php
// Create an instance of our COM object
$obj = new COM("ATLDemo.MyClass");
// Create an instance of the VARIANT structure,
// initial value 0,
// VT_UI4 (data type, see VARIANT data structure for details)
$vtMemoryLoad = new VARIANT(0, VT_UI4);
// Retrieve the current memory load
$obj->GetMemoryLoad($vtMemoryLoad);
print '<p>Physical memory in use : '.$vtMemoryLoad.'%</p>';
// If the "Restart Host" button was pressed
if($_POST['btnRestart']) {
// VARIANT to restore the value returned by the GetLastError() function
$vtLastError = new VARIANT(0, VT_UI4);
// Initiate host restart
$obj->RestartHost($vtLastError);
print '<p>Initiated host restart...</p>';
print '<p>Last Error Code: '.$vtLastError.'</p>';
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="submit" value="Restart Host" name="btnRestart" id="btnRestart" />
</form>
Thank you very much for reading this article. I hope the article or at least some aspects of it might be useful to you. Constructive criticism is appreciated and will be taken into consideration.
| You must Sign In to use this message board. | |||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 27 Oct 2008 Editor: |
Copyright 2008 by Boris O Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |