Solved

Counting processes with the PDH

Posted on 1998-05-18
12
303 Views
Last Modified: 2013-12-03
My program is supposed to count the number & names of processing currently running on a windows NT 4 workstation.

I am using PdhEnumObjectItems to get this information.
For some reason the information returned is only correct for the first call to this function. Subsequent calls always return the same number of processes even if the number of processes has changed. Any ideas.
0
Comment
Question by:shimon_crown
  • 4
  • 4
  • 3
  • +1
12 Comments
 
LVL 2

Expert Comment

by:tonp
ID: 1402567
I would suggest to take a different route. The PSAPI interface is more suited to your task (with functions like EnumProcess and EnumProcessModules). A (very) complete description of how to handle your task can be found in Microsoft's knowledgebase article Q175030 (www.microsft.com).
0
 

Author Comment

by:shimon_crown
ID: 1402568
I am aware of this possibility but for this particular project I am using the PDH for getting other information related to system performance. This cannot be obtained from the PSAPI so it would be much neater to avoid using it altogether.
0
 
LVL 23

Expert Comment

by:chensu
ID: 1402569
It seems to be a bug of Win32. You may try creating a thread to call PdhEnumObjectItems each time you need the information. Hope it will get the latest information.
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 2

Expert Comment

by:tonp
ID: 1402570
I just tried out a simple program, listing processes with the pdh functions (copied source directly from MSDN). Seems to work fine, it correctly lists new processes. Copy the code below and compile it. Now, run it (in a command prompt). Next start some process (e.g. notepad) and run the test app again. It will correctly show the new notepad process (at least, this is what I see on my NT 4.0 sp3 machine).

---- pdh.cpp ----
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE  1
#endif
#define tmain     wmain
#else
#define tmain     main
#endif

// This program only needs the essential windows header files.
#define WIN32_LEAN_AND_MEAN 1

#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>

int tmain ()
{
    PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPTSTR      szThisInstance          = NULL;


// Determine the required buffer size for the data.

    pdhStatus = PdhEnumObjectItems (
        NULL,                   // reserved
        NULL,                   // local machine
        TEXT("Process"),        // object to enumerate
        szCounterListBuffer,    // pass in NULL buffers
        &dwCounterListSize,     // an 0 length to get
        szInstanceListBuffer,   // required size
        &dwInstanceListSize,    // of the buffers in chars
        PERF_DETAIL_WIZARD,     // counter detail level
        0);

    if (pdhStatus == ERROR_SUCCESS)
    {
    // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
            (dwCounterListSize * sizeof (TCHAR)));
        szInstanceListBuffer = (LPTSTR)malloc (
            (dwInstanceListSize * sizeof (TCHAR)));
        if ((szCounterListBuffer != NULL) &&
            (szInstanceListBuffer != NULL))
        {
            pdhStatus = PdhEnumObjectItems (
                NULL,   // reserved
                NULL,   // local machine
                TEXT("Process"), // object to enumerate
                szCounterListBuffer,    // pass in NULL buffers
                &dwCounterListSize,     // an 0 length to get
                szInstanceListBuffer,   // required size
                &dwInstanceListSize,    // of the buffers in chars
                PERF_DETAIL_WIZARD,     // counter detail level
                0);    
            if (pdhStatus == ERROR_SUCCESS)
            {
                _tprintf (TEXT("\nRunning Processes:"));
            // Walk the return instance list.
                for (szThisInstance = szInstanceListBuffer;
                     *szThisInstance != 0;
                     szThisInstance += lstrlen(szThisInstance) + 1)
                {
                     _tprintf (TEXT("\n  %s"), szThisInstance);
                }
            }
        }
        else
        {
            _tprintf (TEXT("\nPROCLIST: unable to allocate buffers"));
        }

        if (szCounterListBuffer != NULL)
            free (szCounterListBuffer);

        if (szInstanceListBuffer != NULL)
            free (szInstanceListBuffer);
    }
    else
    {
        _tprintf(TEXT("\nUnable to determine required buffer size."));
    }
    return 0;
}

0
 
LVL 23

Expert Comment

by:chensu
ID: 1402571
tonp,

You misunderstand the problem. Yes, if you quit the program and restart it again, it will list the lastest information. That is why I suggest creating a thread. But, what shimon_crown is talking about is during the program session. You may make a loop to call PdhEnumObjectItems. When it is running, open some new applications to see what happens.
0
 
LVL 2

Expert Comment

by:tonp
ID: 1402572
Ok, I see. Thanks for the info!
0
 

Author Comment

by:shimon_crown
ID: 1402573
See your own comment.
0
 
LVL 23

Expert Comment

by:chensu
ID: 1402574
Have you tried what I suggested? Does it work?
0
 

Author Comment

by:shimon_crown
ID: 1402575
Not yet as I have been in a course. While I don't think this is a practical suggestion if only because the project demands a very stable NT without starting and stopping threads all the time it is worth looking into to see if it can shed more light on the bug.
Practically  I shall probably revert to using PSAPI as suggested by tonp.
0
 
LVL 7

Expert Comment

by:BlackMan
ID: 1402576
Are you sure that your CounterListBuffer and InstanceListBuffer are large enough for holding all the informations? If you allocate them on the first call based on the required size, there will be no room for new processes. I think the best solution is in each call to yor procedure to query about the size (send CounterListSize=0), allocate the buffer, get the objects and deallocate the buffer. This way you are sure that the buffer is always large enough.
0
 

Author Comment

by:shimon_crown
ID: 1402577
Sorry it still doesn't work. I tried chensu's method and it works so if he wants to resubmit the answer the points are his.
0
 
LVL 23

Accepted Solution

by:
chensu earned 300 total points
ID: 1402578
It seems to be a bug of Win32. You may try creating a thread to call PdhEnumObjectItems each time you need the information.

Thank you.
0

Featured Post

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question