Perl for Windows

Perl for Windows supports most of the core set of Unix features, as well as a number of extensions for Win32 features. If you've installed the ActiveState version of Perl for Windows, you'll get the Win32 modules as part of that package. If you compile Perl for Windows yourself, you'll need to get the libwin32 package yourself from CPAN (see http://www.perl.com/CPAN-local/modules/by-module/Win32/ for the latest version). Otherwise, the functionality is the same.

Note

Earlier versions of Perl for Windows were much less coordinated as far as which modules and features were available in which package. If you're using a version of Perl earlier than 5.6.1 (or ActiveState's Perl earlier than Build 631), you should upgrade to make sure you have the newest and best version.


Compatibility with Unix

With a few notable exceptions, most Unix-like Perl features will work on Windows, although how they are used is different. The biggest notable exception is fork and its related functions, which was not supported at all before version 5.6.1 of Perl. Version 5.6.1 provided a support for fork under Windows on an experimental basis. For more information, see the perlfork man page. You can run another program from inside a Perl script using system, exec, backquotes, of one of the Win 32 extensions (more about those later).

The system function, exec, and backquotes work on Perl for Windows. The “shell” for these commands is cmd.exe for Windows NT, or command.com for Windows 95. Commands and argument lists that you give to these commands must follow Windows conventions, including pathnames and file globbing.

Keep in mind, of course, that if you're porting a Unix script to Windows, and that Unix script uses Unix utilities in system or backquotes, that you'll need to find the Windows equivalents of those same utilities; simply having support for system and backquotes is not enough.

Note

The Cygwin project provides probably the most complete set of Unix tools for Windows. It includes Windows versions of most familiar shell commands, along with the bash shell itself. You can find out more about Cygwin, and download the installation program at http://sources.redhat.com/cygwin/.


Functions that relate to specific Unix features (such as those listed in Table 18.1) are unlikely to work on Perl for Windows. Other functions that do not work are specialized functions I haven't bothered to mention in this book relate to interprocess communication or low-level networking. In general, most of the common Perl functions you'll use will be available in Perl for Windows. You can find a complete list of unimplemented functions in the FAQ for Perl for Win32 at http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/faq/Windows/ActivePerl-Winfaq5.html (look in the section on “Implementation Quirks”).

Built-in Win32 Subroutines

The extensions to Perl for managing Windows features come in two parts: a set of built-in Win32 subroutines, and a number of additional Win32 modules for more sophisticated techniques (such as Win32::Registry or Win32::Process). The Win32 subroutines provide easy access to system information, as well as a number of smaller utility routines. If you are running Perl for Windows, you don't need to import any of the Win32 modules to use these subroutines. Table 18.2 contains a list of several of the Win32 subroutines available in Perl for Windows.

For more information on any of these subroutines, you might want to check the Win32 man page. I also found Philippe Le Berre's pages at http://www.le-berre.com/ to be especially helpful.

Table 18.2. Built-in Win32 Subroutines
Subroutine What it Does
Win32::DomainName Returns the Microsoft Network domain.
Win32::FormatMessage Takes the error returned by GetLastError errorcode and turns it into a descriptive string.
Win32::FsType The filesystem type (FAT or NTFS).
Win32::GetCwd Gets the current directory.
Win32::GetLastError If the last Win32 subroutine failed, this subroutine will give you the reason why (format the result of this with FormatMessage).
Win32::GetNextAvailDrive Gets the drive letter of the next available drive, for example, “E:”.
Win32::GetOSVersion Returns an array representing the OS version and number: ($string, $major, $minor, $build, $id), where the $string is an arbitrary string, $major and $minor are version numbers, $build is the build number, and $is is 0 for a generic Win32, 1 for Windows 95, or 2 for Windows NT.
Win32::GetShortPathName Given a long filename (“thisisareallylongfilename.textfile”), returns the 8.3 version (THISI~1.TXT).
Win32::GetTickCount The number of ticks (milliseconds) that have elapsed since Windows was started.
Win32::IsWin95 True if you're on Windows 95.
Win32::IsWinNT True if you're on Windows NT.
Win32::LoginName The username of the user running the script.
Win32::NodeName The Microsoft Network node name for the current machine.
Win32::SetCwd newdir Changes the current directory.
Win32::Sleep milliseconds Sleep for the given number of milliseconds.
Win32::Spawn Spawn a new process (see the following section, “Win32 Processes”).

Win32::MsgBox

The basic Win32 subroutines give you access to basic Windows features and system information from inside Perl. Installing the libwin32 modules (or using ActiveState's version of Perl for Windows) gives you access to the Win32 modules, with which you can access a lot more of the advanced Windows features. One nifty feature in the Win32 modules is the Win32::MsgBox subroutine, which can be used to pop-up rudimentary modal dialog boxes from inside your Perl scripts. Win32::MsgBox takes up to three arguments: the text to put in the dialog itself, a code representing the icon in the dialog and some combination of buttons, and the test to put in the title bar of the dialog. For example, the following code will show the dialog on the left side of Figure 18.1:

Win32::MsgBox("I can't do that!");

Figure 18.1. Dialogs.


This one shows a dialog with two buttons, OK and Cancel, and a Question icon (as shown on the right side of Figure 18.1):

Win32::MsgBox("Are you sure you want to delete that?", 33);

The second argument represents the codes for the number of buttons and the type of icon. Table 18.3 shows the choices for number of buttons.

Table 18.3. Button Codes
Code Result
0 OK
1 OK and Cancel
2 Abort, Retry, Ignore
3 Yes, No, and Cancel
4 Yes and No
5 Retry and Cancel

Table 18.4 shows the choices for the icon.

Table 18.4. Icon Codes
Code Result
16 Hand
32 Question (?)
48 Exclamation point (!)
64 Asterisk (*)

To get the second argument for Win32::MsgBox, just pick a choice from each table and add the numbers together. So an exclamation icon (48) with Yes and No buttons (4) would result in a code of 52.

The return value of Win32::MsgBox is based on the buttons you used in the dialog and what the user actually clicked. Table 18.5 shows the possible return values.

Table 18.5. Button Codes
Code Button Clicked
1 OK
2 Cancel
3 Abort
4 Retry
5 Ignore
6 Yes
7 No

Win32 Processes

If you don't feel comfortable using the experimental version of the fork subroutine for Windows provided in Perl 5.6.1, or you're using an earlier version of Perl, you won't be able to write programs that fork new processes while running. However, you can start new processes that run separate programs (the equivalent for a fork followed by an exec). The easiest way to do this is to use either system or backquotes, or to halt the current script with an exec. An alternative way is the use either Win32::Spawn or the Win32::Process module.

Win32::Spawn is part of the basic Win32 subroutines, and enables you to start up another process in a really simple way. The Win32::Process module, on the other hand, is more recent, more robust, uses proper module conventions, but is somewhat more difficult to understand.

To create a new process with Win32::Spawn, you'll need three arguments: the full pathname to the command to run in the new process, the arguments to that command (including the command name again), and a variable to hold the process ID of the new process. Here's an example that starts up Notepad on Windows NT with a temporary file in "C: empfile.txt". It also traps errors:

my $command = "c:\windows\notepad.exe ";
my $args = "notepad.exe c:\tempfile";
my $pid = 0;

Win32::Spawn($command, $args, $pid) || &error();
print "Spawned!  The new PID is $pid.";

sub error {
    my $errmsg = Win32::FormatMessage(Win32::GetLastError());
    die "Error: $errmsg
";
}

One annoying side effect of Win32::Spawn is that the new process—in this case, Notepad—comes up minimized, so it appears as if nothing is happening. The original Perl script also continues executing (or, in this case, finishes executing) as the new process is running.

The Win32::Process module handles processes in a much more sensible way. However, it's more complex, and it's set up to be object oriented, which means some slightly different syntax (but you learned the basics on Day 13, “Scope, Modules, and Importing Code,” so you should be okay).

Creating a Win32::Process object is vaguely similar to using Win32::Spawn. You'll still need a command and a list or arguments, but you'll also need some other stuff. To create a Win32::Process object, first make sure you import Win32::Process:

use Win32::Process;

Then call the Create method to create your new process object (you'll need a variable to hold it):

#!c:/perl/bin/perl

my $command = "c:\windows\notepad.exe ";
my $args = "notepad.exe c:\tempfile";
my $proc; # process object

Win32::Process::Create($process,
     $command,
     $args,
     0,
     DETACHED_PROCESS,
     '.') || die &error();

(I've left off the definition for the error subroutine here to save space.)

The arguments to Win32::Process are

  • A variable to hold a reference to the new process object.

  • The command to run.

  • The arguments to that command.

  • Whether handles are inherited (if you don't know what that means, just use 0).

  • One of several options. DETACHED_PROCESS is the most popular, although CREATE_NEW_CONSOLE might also be useful. All the options are listed in the Win32::Process man page.

  • The temporary directory for this process.

In this case, when the new process is created, Notepad will start up maximized and edit the file in C: empfile. But the original Perl script will still continue executing.

To make the parent process wait for the child to finish executing, use the Wait method (note the capital W; this isn't the same as Perl's wait function). You'll have to call this as an object-oriented method, with the process object first:

$proc->Wait(INFINITE);

In this case, the parent process will wait indefinitely until the child finishes. You can also give Wait an argument of some number of milliseconds to wait before continuing.

In addition to Wait, the Win32::Process module also includes these methods:

  • Kill, to kill the new process

  • Suspend, to temporarily stop the process

  • Resume, to start a suspended process

  • GetPriorityClass and SetPriorityClass, to look up or change the process's priority

  • GetExitCode, to find out why a process exited

You can get more information about Win32::Process from the documentation that comes with the Win32 modules, or from the online documentation at http://aspn.activestate.com/ASPN/Reference/.

Working with the Win32 Registry

The Windows Registry is a warehouse of information about your system, its configuration, and the programs installed on it. The Win32::Registry module, an object-oriented module, allows you to read from, modify, and add values to the Windows Registry from inside a Perl script.

Note

If you're unfamiliar with the Windows Registry, chances are good you should not be playing with it from inside Perl. You can make your system unusable by messing with the Registry and changing things that are not intended to be changed. You can use the Windows program regedit to examine and modify the Windows Registry.


The Windows Registry consists of a number of trees of keys and values. At the topmost level, the Registry contains several subtrees, including HKEY_LOCAL_MACHINE for information about the configuration of the local machine, or HKEY_CURRENT_USER for information about the currently logged-in user. Depending on whether you're running Windows NT or Windows 95, you'll have a different set of subtrees. Inside each subtree are a number of sets of keys and values, like hashes, only nested (a key can map to a whole other hash tree).

When you import the Win32::Registry module (with use Win32::Registry), you get a registry key object for each of the topmost subtrees, for example $HEKY_LOCAL_MACHINE. Using the various Win32::Registry methods, you can open, traverse, and manage any part of the Windows Registry.

Unfortunately, to get the most use out of the Win32::Registry module, you need to know something of references to handle the nested-hash nature of the Registry keys. For now, then, Table 18.6 shows several of the Win32::Registry methods and their arguments; after going on to the lesson on references these will be more meaningful.

To start working with any part of the Registry, you must first use Open with of the major subkey objects, like this (don't forget to use Win32::Registry at the top of your script):

use Win32::Registry;
my $reg = "SOFTWARE";
my ($regobj, @keys);
$HKEY_LOCAL_MACHINE->Open($reg,$regobj)|| die "Can't open registry
";

Then, you can call the various Registry methods on that new Registry object:

$regobj->GetKeys(@keys);
$regobj->Close();

Table 18.6. Win32::Registry Methods
Method What it Does
Close Closes the currently open key.
Create keyname,keyref Creates a new key with the name keyname. keyref will contain a reference to the new key.
DeleteKey keyname Deletes the key keyname.
DeleteValue valname Deletes the value valname.
GetKeys listref Returns a list of the keys in the current key. listref is a reference to a list.
GetValues hashref Returns a hash of the keys and values in the current key. The keys in this hash are nested lists. hashref is a reference to a hash.
Open obj, objref Opens a key. obj is the key to open, objref is a reference to the object that will hold that key.
Save filename Saves the currently open key to filename
SetValue Change the value of keyname to value.
keyname,REG_SZ,value The second argument must be REG_SZ.
Load keyname, filename Imports the keys and values in filename into keyname.

For more information on Win32::Registry, the documentation that comes with the Win32 modules is helpful. You might also want to check out Phillipe Le Berre's How To Guide at http://www.le-berre.com/perl/main.htm, which has lots of examples and notes on using Win32::Registry.

Other Win32 Modules

The Win32 modules, shipped with Active State's Perl and gathered in the libwin32 bundle, contain lots and lots of modules for handling various aspects of Windows operations—by only describing Win32::Process and Win32::Registry I've only touched the surface. And in addition to those “standard” Win32 modules, more and more is being written and included on CPAN. If you do lots of work with Windows, and intend to do more work with Perl on that platform, look into these modules for many more features to work with. Table 18.7 contains a summary of the standard Win32 modules; see CPAN for even more.

Table 18.7. Win32 Modules
Module What it Does
Win32::AuthenticateUser Enables you to authenticate Windows users using domains.
Win32::ChangeNotify Provides access to Windows change-notification objects.
Win32::Clipboard Enables you to interact with the Windows clipboard.
Win32::Console Functions for Windows console and character mode.
Win32::Event Provides access to Win32 event objects.
Win32::EventLog Provides access to the Windows event log.
Win32::File Manages file attributes.
Win32::FileSecurity Manages NTFS file security.
Win32::Internet Wrapper for WININET.DLL.
Win32::IPC Inter-Process Communication: allows you to synchronize and communicate between Process, ChangeNotify, Semaphore, and Mutex.
Win32::Mutex Provides access to Windows Mutex objects.
Win32::NetAdmin Administers users and groups (Windows NT only).
Win32::NetResource Administers system resources (printers, servers, and so on) (Windows NT only).
Win32::ODBC Provides access to ODBC databases from Perl.
Win32::OLE Provides access to OLE automation.
Win32::PerfLib Provides access to the Windows Performance Counter.
Win32::Pipe Enables you to use named pipes from Perl.
Win32::Process Creates and manages Windows processes
Win32::Registry Works with the Windows registry.
Win32::Semaphore Provides access to Windows Semaphore objects.
Win32::Service Enables you to administer services.
Win32::Sound Provides access to Windows sounds.
Win32::TieRegistry Enables you to access the registry via tied hashes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.231.125