Win32::Process::Info - Provide process information for Windows 32 systems. |
Win32::Process::Info - Provide process information for Windows 32 systems.
use Win32::Process::Info; $pi = Win32::Process::Info->new (); $pi->Set (elapsed_in_seconds => 0); # In clunks, not seconds. @pids = $pi->ListPids (); # Get all known PIDs @info = $pi->GetProcInfo (); # Get the max %subs = $pi->Subprocesses (); # Figure out subprocess relationships. @info = grep { defined $_->{Name} && $_->{Name} =~ m/perl/ } $pi->GetProcInfo (); # All processes with 'perl' in name.
This package covers a multitude of sins - as many as Microsoft has invented ways to get process info and I have resources and gumption to code. The key to this mess is the 'variant' argument to the 'new' method (q.v.).
The WMI variant has various problems, known or suspected to be inherited from Win32::OLE. See BUGS for the gory details. The worst of these is that if you use fork(), you must disallow WMI completely by loading this module as follows:
use Win32::Process::Info qw{NT};
This method of controlling things must be considered experimental until I can confirm it causes no unexpected insurmountable problems. If I am forced to change it, the change will be flagged prominently in the documentation.
This change is somewhat incompatible with 1.006 and earlier because it
requires the import()
method to be called in the correct place with the
correct arguments. If you require Win32::Process::Info
, you must
explicitly call Win32::Process::Info->import().
See the import()
documentation below for the details.
YOU HAVE BEEN WARNED!
The main purpose of the Win32::Process::Info package is to get whatever information is convenient (for the author!) about one or more Windows 32 processes. GetProcInfo is therefore the most-important method in the package. See it for more information.
The process IDs made available are those returned by the variant in use. See the documentation to the individual variants for details, especially if you are a Cygwin user.
Unless explicitly stated otherwise, modules, variables, and so on are considered private. That is, the author reserves the right to make arbitrary changes in the way they work, without telling anyone. For methods, variables, and so on which are considered public, the author will make an effort keep them stable, and failing that to call attention to changes.
The following methods should be considered public:
The following variants are currently supported:
NT - Uses the NT-native mechanism. Good on any NT, including Windows 2000. This variant does not support connecting to another machine, so the 'machine' argument must be an empty string (or undef, if you prefer).
PT - Uses Dan Urist's Proc::ProcessTable, making it possible (paradoxically) to use this module on other operating systems than Windows. Only those Proc::ProcessTable::Process fields which seem to correspond to WMI items are returned. Caveat: the PT variant is to be considered experimental, and may be changed or retracted in future releases.
WMI - Uses the Windows Management Implementation. Good on Win2K, ME, and possibly others, depending on their vintage and whether WMI has been retrofitted.
The initial default variant comes from environment variable PERL_WIN32_PROCESS_INFO_VARIANT. If this is not found, it will be 'WMI,NT,PT', which means to try WMI first, NT if WMI fails, and PT as a last resort. This can be changed using Win32::Process::Info->Set (variant => whatever).
The hash argument is a hash reference to additional arguments, if any. The hash reference can actually appear anywhere in the argument list, though positional arguments are illegal after the hash reference.
The following hash keys are supported:
variant => corresponds to the 'variant' argument (all) assert_debug_priv => assert debug if available (all) This only has effect under WMI. The NT variant always asserts debug. You want to be careful doing this under WMI if you're fetching the process owner information, since the script can be badly behaved (i.e. die horribly) for those processes whose ExecutablePath is only available with the debug privilege turned on. host => corresponds to the 'machine' argument (WMI) user => username to perform operation under (WMI) password => password corresponding to the given username (WMI)
ALL hash keys are optional. SOME hash keys are only supported under certain variants. These are indicated in parentheses after the description of the key. It is an error to specify a key that the variant in use does not support.
This method can also be called as a class method (that is, as Win32::Process::Info->Get ()) to return default attributes values.
The relevant attribute names are:
elapsed_as_seconds is TRUE to convert elapsed user and kernel times to seconds. If FALSE, they are returned in clunks (that is, hundreds of nanoseconds). The default is TRUE.
variant is the variant of the Process::Info code in use, and should be zero or more of 'WMI' or 'NT', separated by commas. 'WMI' selects the Windows Management Implementation, and 'NT' selects the Windows NT native interface.
machine is the name of the machine connected to. This is not available as a class attribute.
This method can also be called as a class method (that is, as Win32::Process::Info->Set ()) to change default attribute values.
The relevant attribute names are the same as for Get. However:
variant is read-only at the instance level. That is, Win32::Process::Info->Set (variant => 'NT') is OK, but $pi->Set (variant => 'NT') will raise an exception. If you set variant to an empty string (the default), the next ``new'' will iterate over all possibilities (or the contents of environment variable PERL_WIN32_PROCESS_INFO_VARIANT if present), and set variant to the first one that actually works.
machine is not available as a class attribute, and is read-only as an instance attribute. It is not useful for discovering your machine name - if you instantiated the object without specifying a machine name, you will get nothing useful back.
What keys are available depends on the variant in use. You can hope to get at least the following keys for a ``normal'' process (i.e. not the idle process, which is PID 0, nor the system, which is some small indeterminate PID) to which you have access:
CreationDate ExecutablePath KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name (generally the name of the executable file) ProcessId UserModeTime
You may find other keys available as well, depending on which operating system you're using, and which variant of Process::Info you're using.
This method also optionally takes as its first argument a reference to a hash of option values. The only supported key is:
no_user_info => 1 Do not return keys Owner and OwnerSid, even if available. These tend to be time-consuming, and can cause problems under the WMI variant.
This method must be called at least once, in a BEGIN block, or no
variants will be legal to use. Usually it does not need to be
explicitly called by the user, since it is called implicitly when you
use Win32::Process::Info;
. If you require Win32::Process::Info;
you will have to call this method explicitly.
If this method is called more than once, the second and subsequent calls will have no effect on what variants are available. The reason for this will be made clear (I hope!) under USE IN OTHER MODULES, below.
The only time a user of this module needs to do anything different versus version 1.006 and previous of this module is if this module is being loaded in such a way that this method is not implicitly called. This can happen two ways:
use Win32::Process::Info ();
explicitly bypasses the implicit call of this method. Don't do that.
require Win32::Process::Info;
also does not call this method. If you must load this module using require rather than use, follow the require with
Win32::Process::Info->import ();
passing any necessary arguments.
If no argument is passed, you get all processes in the system.
If called in scalar context you get a reference to the hash.
This method works off the ParentProcessId attribute. Not all variants support this. If the variant you're using doesn't support this attribute, you get back an empty hash. Specifically:
NT -> unsupported PT -> supported WMI -> supported
Unlike the data returned from Subprocesses(), the data here are not flattened; so if you specify one or more process IDs as arguments, you will get back at most the number of process IDs you specified; fewer if some of the specified processes do not exist.
Note well that a given process can occur more than once in the output. If you call SubProcInfo without arguments, the @info array will contain every process in the system, even those which are also in some other process' {subProcesses} array.
Also unlike Subprocesses(), you will get an exception if you use this method with a variant that does not support the ParentProcessId key.
My_Pid()
$$
. But Cygwin has its own idea of what
the process ID is, which may differ from Windows. Worse than that, under
Cygwin the NT and WMI variants return Windows PIDs, while PT appears to
return Cygwin PIDs.
This method can also be called as a normal method, or even as a subroutine.
Other modules that use this module are also subject to the effects of
the collision between Win32::OLE and the emulated fork call, and to the
requirements of the import()
method. I will not address subclassing,
since I am not sure how well this module subclasses (the variants are
implemented as subclasses of this module).
Modules that simply make use of this module (the 'has-a' relationship) should work as before, provided they 'use Win32::Process::Info'. Note that the phrase 'as before' is literal, and means (among other things), that you can't use the emulated fork.
If you as the author of a module that uses Win32::Process::Info wish to allow emulated forks, you have a number of options.
The easiest way to go is
use Win32::Process::Info qw{NT};
if this provides enough information for your module.
If you would prefer the extra information provided by WMI but can operate in a degraded mode if needed, you can do something like
use Win32::Process::Info (); sub import { my $pkg = shift; $pkg->SUPER::import (@_); # Optional (see below) Win32::Process::Info->import (@_); }
The call to $pkg->SUPER::import is needed only if your package is a subclass of Exporter.
Note to users of modules that require this module:
If the above 'rules' are violated, the symptoms will be either that you cannot instantiate an object (because there are no legal variants) or that you cannot use fork (because the WMI variant was enabled by default). The workaround for you is to
use Win32::Process::Info;
before you 'use' the problematic module. If the problem is coexistence with fork, you will of course need to
use Win32::Process::Info qw{NT};
This is why only the first import()
sets the possible variants.
This package is sensitive to a number of environment variables. Note that these are normally consulted only when the package is initialized (i.e. when it's ``used'' or ``required'').
PERL_WIN32_PROCESS_INFO_VARIANT
If present, specifies which variant(s)
are tried, in which
order. The default behavior is equivalent to specifying
'WMI,NT'. This environment variable is consulted when you
``use Win32::Process::Info;''. If you want to change it in
your Perl code you should use the static Set () method.
PERL_WIN32_PROCESS_INFO_WMI_DEBUG
If present and containing a value Perl recognizes as true, causes the WMI variant to assert the ``Debug'' privilege. This has the advantage of returning more full paths, but the disadvantage of tending to cause Perl to die when trying to get the owner information on the newly-accessible processes.
PERL_WIN32_PROCESS_INFO_WMI_PARIAH
If present, should contain a semicolon-delimited list of process names for which the package should not attempt to get owner information. '*' is a special case meaning 'all'. You will probably need to use this if you assert PERL_WIN32_PROCESS_INFO_WMI_DEBUG.
It should be obvious that this library must run under some flavor of Windows.
This library uses the following libraries:
Carp Time::Local Proc::ProcessTable (if using the PT variant) Win32::API (if using the NT-native variant) Win32API::Registry (if using the NT-native variant) Win32::ODBC (if using the WMI variant)
As of ActivePerl 630, none of this uses any packages that are not included with ActivePerl. Carp and Time::Local have been in the core since at least 5.004. Your mileage may, of course, vary.
The WMI variant leaks memory - badly for 1.001 and earlier. After 1.001 it only leaks badly if you retrieve the process owner information. If you're trying to write a daemon, the NT variant is recommended. If you're stuck with WMI, set the no_user_info flag when you call GetProcInfo. This won't stop the leaks, but it minimizes them, at the cost of not returning the username or SID.
If you intend to use fork (), your script will die horribly unless you load this module as
use Win32::Process::Info qw{NT};
The problem is that fork()
and Win32::OLE (used by the WMI variant) do
not play at all nicely together. This appears to be an acknowledged
problem with Win32::OLE, which is brought on simply by loading the
module. See import()
above for the gory details.
The use of the NT and WMI variants under non-Microsoft systems is
unsupported. ReactOS 0.3.3 is known to lock up when GetProcInfo()
is
called; since this works on the Microsoft OSes, I am inclined to
attribute this to the acknowledged alpha-ness of ReactOS. I have no idea
what happens under Wine. Caveat user.
Bugs can be reported to the author by mail, or through http://rt.cpan.org.
You can not require
this module except in a BEGIN block. This is a
consequence of the use of Win32::API, which has the same restriction, at
least in some versions.
If you require
this module, you must explicitly call <
Win32::Process::Info-
import()
>>, so that the module will know what
variants are available.
If your code calls fork (), you must load this module as
use Win32::Process::Info qw{NT};
This renders the WMI variant unavailable. See BUGS.
Win32::Process::Info focuses on returning static data about a process. If this module doesn't do what you want, maybe one of the following ones will.
This module would not exist without the following people:
Aldo Calpini, who gave us Win32::API.
Jenda Krynicky, whose ``How2 create a PPM distribution'' (http://jenda.krynicky.cz/perl/PPM.html) gave me a leg up on both PPM and tar distributions.
Dave Roth, http://www.roth.net/perl/, author of Win32 Perl Programming: Administrators Handbook, which is published by Macmillan Technical Publishing, ISBN 1-57870-215-1
Dan Sugalski sugalskd@osshe.edu, author of VMS::Process, where I got (for good or ill) the idea of just grabbing all the data I could find on a process and smashing it into a big hash.
The folks of Cygwin (http://www.cygwin.com/), especially Christopher G. Faylor, author of ps.cc.
Judy Hawkins of Pitney Bowes, for providing testing and patches for NT 4.0 without WMI.
Thomas R. Wyant, III (wyant at cpan dot org)
Copyright (C) 2001-2005 by E. I. DuPont de Nemours and Company, Inc. All rights reserved.
Copyright (C) 2007-2011, 2013-2014 by Thomas R. Wyant, III
This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory LICENSES.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
Win32::Process::Info - Provide process information for Windows 32 systems. |