In my September column, "Inside the New Perl Resource Kit," I reviewed O'Reilly & Associates' Perl Resource KitWin32 Edition and introduced you to PerlCOM and PerlCtrl, the two new component object model (COM)-based Perl technologies ActiveState Tool developed. I demonstrated how you can use PerlCOM to create instances of Perl in any programming environment that supports COM. This month, I'll introduce you to PerlCtrl.
With PerlCtrl, you can create COM automation servers in Perl. A COM automation server, or control, is a self-contained, reusable .dll file that exposes methods and properties that any COM controller can instantiate and use. The control can be a simple Perl script that provides a useful function you want to reuse in another development environment or a complete Perl module that provides many useful functions. PerlCtrl lets you define all aspects of the object's implementation, including the ProgID (the name you use to create the object), the exposed methods and properties, and whether users can change exposed properties.
Creating a control with PerlCtrl involves six steps. I'll walk you through each step and show you how to build a control that lets you write events in the Windows NT Application Log. Keep in mind that after you're done, you can use this control from any programming environment that supports COM, such as Visual Basic (VB), Visual Basic for Applications (VBA), Windows Scripting Host (WSH), Active Server Pages (ASP), and Delphi. Because WSH doesn't provide access to the NT event logs by default, you'll test your new control with a WSH VBScript routine.
Step 1: Create a Template
You need to create a template for the control's source code and type library. This step is quick and easy because PerlCtrl.exe provides the -t command-line switch that instructs PerlCtrl to create the template for you. The only task you need to do is redirect the output to a file by typing
C:\Perl\Source\Controls>perlctrl -t >SysLog.pl
Executing PerlCtrl.exe produces a new control template, SysLog.pl, which Listing 1, page 194, shows. In this generic template, you'll find a hash, %TypeLib, enclosed in Perl documentation tags (=POD and =cut). In step 3, you'll use the %TypeLib hash to define the control's name, properties, methods, and other elements. But first you need to write the source code that implements this object's behavior.
Step 2: Write the Code
In this step, you need to add the Perl source code for your control to the template you just created (SysLog.pl in this case). As callout A in Listing 2, page 195, shows, you place the SysLog.pl source code in the template before the =POD delimiter of the %TypeLib hash.
The code begins by defining a new package, SysLog. Because you must define all code PerlCtrl exposes within a Perl package, you need to use Perl's package keyword followed by the package's name (i.e., SysLog). A Perl package is simply a named, modular unit of functionality constructed in a way that you can easily reuse it. For example, the hundreds of reusable Perl modules available on the Comprehensive Perl Archive Network (CPAN) are packages. (For more information about CPAN, go to http://www.perl.com/CPAN.)
After defining the package name, you must define the object's properties and methods. Properties define the state of the object; methods define the object's behavior. For example, consider a user object in which name might be a property and ChangePassword might be a method. Properties describe the current view of the object, and methods make changes or perform actions on the object in some way.
The control in the SysLog.pl source code in Listing 2 contains five scalar variables ($Host, $Source, $Id, $Type, and $Description) and one subroutine (Write) that make up the object's properties and method, respectively. The code initializes several of the scalar variables with a default value. Initialization provides a default value for the property in case the user chooses not to explicitly set the value. The Write subroutine is the object's only method. It performs the action of writing the default or user-defined event in the NT Application Log.
You can create an unlimited number of properties and methods. Also keep in mind that you do not need to expose all properties and methods.
Step 3: Define and Expose the Object's Methods and Properties
The most delicate step in the process is editing the %TypeLib hash. You use the %TypeLib hash to express the aspects of your implementation that you want to expose to the outside world. What makes this step so delicate is that the %TypeLib hash is a complex data structure. Fortunately, you need to be concerned about only these few implementation aspects:
- PackageName, the name of the package
- ControlName, a friendly, possibly more descriptive name for the control
- ControlVer, the control's version number
- ProgID, the name you use to create instances of the object in other programming environments
- DefaultMethod, the control's default method
- Methods, a hash for each method the control exposes that contains keys describing the method's return type, total number of parameters, number of optional parameters, and parameter type
- Properties, a hash for each property the control exposes that contains keys describing the property type and whether users can change the property
Listing 2 contains the edited %TypeLib hash. 'SysLog' is the PackageName, 'SysLog Control' is the ControlName, 1 is the ControlVer, 'SysLog' is the ProgID, and 'Write' is the DefaultMethod. Callout B in Listing 2 shows the Write method that the control will use. Notice that you must define the variable types as variants in the Properties section that follows the Write method. In COM and Object Linking and Embedding (OLE) automation, variants are the data types. Variants provide the mechanism for weakly typed programming environments (e.g., ASP, Perl, VBA, and WSH) to appropriately translate data. Table 1 lists the variant data types.
Step 4: Build the .dll File
After you've finished defining and developing your control, you can build it. To invoke the build process, you run PerlCtrl.exe, passing it the control's source and TypeLib filename by typing
The build process first checks the syntax of the source file. If everything is OK, PerlCtrl creates the .dll file, as the following console messages indicate:
SysLog.pl syntax OK
Creating PerlCtrl SysLog.dll...all done.
Step 5: Register the .dll File
As is the case with most ActiveX controls, you must register your control before you can use it. You can use NT's regsvr32.exe utility to complete this task. Run regsvr32.exe, passing it the name of the .dll file to register by typing
You can get additional help on how to use this utility by running the command without arguments. If the registration succeeds, a message box displays the message DLLRegisterServer in SysLog.dll succeeded.
Step 6: Use the Control
The final step is to use the control. Listing 3, page 196, contains a short WSH VBScript example that uses the SysLog control.
The example script begins by declaring two variables, oSysLog and sProps. Next, the script creates a new SysLog object using CreateObject, which specifies the ProgID you defined in the %TypeLib hash. After creating the object, the script retrieves the object's default properties and displays them using VBScript's MsgBox function. The script then changes the properties and displays them a second time. Finally, the script invokes the object's Write method to enter information in the NT Application Log. When the script is done with the object, it uses VBScript's Nothing keyword to release the object.
Room for Improvement
PerlCtrl's online Help points out several limitations, including the ability to expose only one object per .dll file, the lack of support for automation events, and the lack of AutoComplete support in the VB development environment. According to ActiveState, a future release will address these limitations.
I encountered another obstacle that could potentially limit PerlCtrl's use. In my tests, I was unable to use PerlCtrl components on those machines I didn't install Perl on. I hope that ActiveState will address this limitation in its next version.
I also encourage ActiveState to provide a wizard that people can use to fill in the %TypeLib hash. A wizard would not only minimize programmer error, but also put the PerlCtrl development environment on par with other visual development systems. Providing that ActiveState addresses these limitations, I think PerlCtrl has the potential to elevate Perl to the level of reusable COM-based component software.
New Scripting Newsletter
Windows NT Magazine is launching Win32 Scripting Journal, a 16-page scripting and task-automation newsletter for Windows NT and Win95 system administrators. For more information, visit the Web site at http://www.winntmag.com/ newsletter/scripting.