After seeing this node I started trying to understand why Win32::Process::Memory wouldn't work. The node author warned that Win32 modules have issues. I found this module has major problems but I haven't had issues with other Win32 modules. If anyone is looking for Win32 modules to take over this one seems to need some work.
I ran the test program from the other node but saw different output:
use strict ; use warnings ; use Win32::Process::Memory ; my $proc = Win32::Process::Memory->new({ name => 'notepad.exe' }); printf "Commited Memory = %X Bytes\n", $proc->get_memtotal ; __END__ Win32::Process::Info is required to get process by name at C:/Strawber +ry/perl/site/lib/Win32/Process/Memory.pm line 35.
I installed Win32::Process::Info but it should have been a prerequisite of installing Win32::Process::Memory. After installing it and running the test program again I saw the same output as was reported in the other thread.
Use of uninitialized value in lc at C:/Perl64/site/lib/Win32/Process/M +emory.pm line 38.
Line 38 looks like this:
foreach ( Win32::Process::Info->new( '', 'NT' )->GetProcInfo ) + { if ( lc( $_->{Name} ) eq $pargs->{name} ) { ######## Line +38 $pargs->{pid} = $_->{ProcessId};
Since $pargs->{name} is the name that was passed to the function the problem seemed to be with $_->{Name}. I wrote this script to see what ->GetProcInfo is returning.
use strict ; use warnings ; use Win32::Process::Info ; use Data::Dumper; foreach ( (Win32::Process::Info->new( '', 'NT' )->GetProcInfo ) ) { print Dumper($_); print '*'x75, "\n"; }
The output looked like this (these are the last few):
[...] $VAR1 = { '_status' => 127, 'ProcessId' => 10524 }; ********************************************************************** +***** $VAR1 = { '_status' => 127, 'ProcessId' => 7768 }; ********************************************************************** +***** $VAR1 = { 'WriteOperationCount' => 0, 'WriteTransferCount' => 0, '_status' => 127, 'MaximumWorkingSetSize' => 1413120, 'MinimumWorkingSetSize' => 204800, 'OtherOperationCount' => 1104, 'OtherTransferCount' => 9046, 'CreationDate' => 1530745952, 'KernelModeTime' => '0.03125', 'UserModeTime' => '0.15625', 'ProcessId' => 484, 'ReadTransferCount' => 398115, 'ReadOperationCount' => 77 }; ********************************************************************** +*****
None of the hashes that were output contained a key called 'Name'. I found if I removed the arguments to Win32::Process::Info->new( '', 'NT' ) that the returned hashes do contain a key called 'Name'.
use strict ; use warnings ; use Win32::Process::Info ; use Data::Dumper; foreach ( (Win32::Process::Info->new( )->GetProcInfo )[-1]) { print Dumper($_); print '*'x75, "\n"; } __END__ $VAR1 = { 'QuotaPagedPoolUsage' => 123, 'ParentProcessId' => 7984, 'ProcessId' => 5568, 'Caption' => 'perl.exe', 'OwnerSid' => 'S-1-5-21-3545305261-4160602198-2318032092-100 +1', 'ExecutablePath' => 'C:\\Strawberry\\perl\\bin\\perl.exe', 'Status' => undef, 'Owner' => 'QUEST\\Brent', 'WindowsVersion' => '6.3.9600', 'ThreadCount' => 6, 'WriteTransferCount' => '0', 'HandleCount' => 151, 'TerminationDate' => undef, 'VirtualSize' => '81350656', 'SessionId' => 2, 'UserModeTime' => '0.21875', 'OtherTransferCount' => '136620', 'OtherOperationCount' => '4717', 'KernelModeTime' => '0.203125', 'InstallDate' => undef, 'PageFaults' => 4153, 'PeakPageFileUsage' => 8484, 'Name' => 'perl.exe', 'PageFileUsage' => 8484, 'OSCreationClassName' => 'Win32_OperatingSystem', 'PrivatePageCount' => '8687616', 'PeakVirtualSize' => '81350656', 'QuotaPeakNonPagedPoolUsage' => 12, 'PeakWorkingSetSize' => 15336, 'OSName' => 'Microsoft Windows 8.1|C:\\Windows|\\Device\\Har +ddisk0\\Partition4', 'Priority' => 8, 'QuotaNonPagedPoolUsage' => 12, 'MinimumWorkingSetSize' => 200, 'MaximumWorkingSetSize' => 1380, 'CSCreationClassName' => 'Win32_ComputerSystem', 'CSName' => 'QUEST', 'QuotaPeakPagedPoolUsage' => 123, 'ReadOperationCount' => '86', 'Description' => 'perl.exe', 'Handle' => '5568', 'WriteOperationCount' => '0', 'CreationDate' => 1530731971, 'ExecutionState' => undef, 'CommandLine' => '"C:\\Strawberry\\perl\\bin\\perl.exe" "C:\ +\usr\\pm\\Win32\\win32processinfo_noargs.pl" ', 'ReadTransferCount' => '375821', 'CreationClassName' => 'Win32_Process', 'WorkingSetSize' => '15704064' }; ********************************************************************** +*****
I found a description of the arguments to new in the documentation that explains what happens if no arguments are passed to new.
$pi = Win32::Process::Info->new ([machine], [variant], [hash]) This method instantiates a process information object, connected to th +e given machine, and using the given variant. The following variants are currently supported: NT - Uses the NT-native mechanism. Good on any NT, including Windows 2 +000. This variant does not support connecting to another machine, so +the 'machine' argument must be an empty string (or undef, if you pref +er). PT - Uses Dan Urist's Proc::ProcessTable, making it possible (paradoxi +cally) to use this module on other operating systems than Windows. On +ly 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, a +nd possibly others, depending on their vintage and whether WMI has be +en 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 resor +t. This can be changed using Win32::Process::Info->Set (variant => wh +atever).
The WMI variant seems to be providing more information that includes the 'Name' key. I then modified Memory.pm on my machine so that new is called with no arguments. At that point the following test script will just hang.
use strict ; use warnings ; use Win32::Process::Memory ; my $proc = Win32::Process::Memory->new({ name => 'cmd.exe' }); #my $proc = Win32::Process::Memory->new({ name => 'notepad.exe' }); print "ok1\n"; printf "Commited Memory = %X Bytes\n", $proc->get_memtotal ; print "ok2\n"; __END__ pargs->pid = 7984 hi 1 hi 2 ok1 hi 3 .....(hangs here)
Here is the part of memory.pm that I added some print statements to for debugging.
# get process handle by command line name if ( defined( $pargs->{name} ) ) { eval 'use Win32::Process::Info;'; die "Win32::Process::Info is required to get process by name" +if $@; $pargs->{name} = lc( $pargs->{name} ); #foreach ( Win32::Process::Info->new( '', 'NT' )->GetProcInfo +) { foreach ( Win32::Process::Info->new( )->GetProcInfo ) { if ( lc( $_->{Name} ) eq $pargs->{name} ) { $pargs->{pid} = $_->{ProcessId}; print "pargs->pid = $pargs->{pid}\n"; last; } } } # get process handle by pid if ( defined( $pargs->{pid} ) ) { my $hProcess = _OpenByPid( $pargs->{pid}, $access ); print "hi 1\n"; $this->{hProcess} = $hProcess if $hProcess; print "hi 2\n"; } return $this; } sub DESTROY { my $this = shift; _CloseProcess( $this->{hProcess} ) if defined $this->{hProcess}; } sub get_memlist { _GetMemoryList( $_[0]->{hProcess} ); } sub get_memtotal { my $this = shift; print "hi 3\n"; my %memlist = $this->get_memlist; print "hi 4\n"; my $sum = 0; $sum += $_ foreach values %memlist; return $sum; }
It stops at the call to get_memlist and that is just a wrapper for _GetMemoryList. This is the point where I'm stuck since this is an xs function that I don't know how to troubleshoot. This module has no significant tests defined and doesn't seem to have been touched in a long time. Maybe someone who knows XS could fix it up. It isn't something I really need. I was just curious to see how far I could get with troubleshooting it.
Edit: Fixed link.
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |