Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 08:22
Оценка:
Здравствуйте ! Программисты , очень нужна Ваша помощь . Уже сил нету . Как работать с ключом HKEY_PERFORMANCE_DATA? Нужно определить значение основных счётчиков продуктивности . Уже перечитал всё , что можно и нельзя,но так и не разобрался .

Как считать с этого ключа данные ?

#include "stdafx.h"
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
 
#define TOTALBYTES    8192
#define BYTEINCREMENT 4096
 
void main()
{
    DWORD BufferSize = TOTALBYTES;
    DWORD cbData;
    DWORD dwRet;
 
    PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
    cbData = BufferSize;
 
    printf("\nRetrieving the data...");
 
    dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                             TEXT("Global"),
                             NULL,
                             NULL,
                             (LPBYTE) PerfData,
                             &cbData );
    while( dwRet == ERROR_MORE_DATA )
    {
        // Get a buffer that is big enough.
 
        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
        cbData = BufferSize;
 
        printf(".");
        dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                         TEXT("Global"),
                         NULL,
                         NULL,
                         (LPBYTE) PerfData,
                         &cbData );
    }
    if( dwRet == ERROR_SUCCESS )
        printf("\n\nFinal buffer size is %d\n", BufferSize);
    else printf("\nRegQueryValueEx failed (%d)\n", dwRet);
}


прочитал , что список активных счётчиков лежит в HKLM\Software\Microsoft\Windows NT\Corrent Version\PerfLib
понял , что там изображены счётчики и их индексы

Я так понимаю, что для каждого счётчика нужно использовать свой индекс?


#include "stdafx.h"
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <iostream>
using namespace std;
 
#define TOTALBYTES    8192
#define BYTEINCREMENT 4096
const int Process_Index = 230;
const int PID_Process = 784;
 
void main()
{
    DWORD BufferSize = TOTALBYTES;   //размер буфера
    DWORD cbData;
    DWORD dwRet;   //код возврата
 
    PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
    PPERF_OBJECT_TYPE PerObjType;
    PPERF_INSTANCE_DEFINITION  PerDefin;
    PPERF_COUNTER_BLOCK  PerCount;
 
    int i,k,j; //для циклов
    string name;
    cbData = BufferSize;
 
    printf("\nRetrieving the data...");
 
    dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                             TEXT("Global"),
                             NULL,
                             NULL,
                             (LPBYTE) PerfData,
                             &cbData );
    while( dwRet == ERROR_MORE_DATA )
    {
        // Get a buffer that is big enough.
 
        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
        cbData = BufferSize;
 
        printf(".");
        dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                         TEXT("Global"),
                         NULL,
                         NULL,
                         (LPBYTE) PerfData,
                         &cbData );
    }
    if( dwRet == ERROR_SUCCESS )
       { printf("\n\nFinal buffer size is %d\n", BufferSize);
       // cout<<PerfData<<" "<<endl;
    }
        
    else printf("\nRegQueryValueEx failed (%d)\n", dwRet);
 
    RegCloseKey(HKEY_PERFORMANCE_DATA);
 
    for (i=0;i<PerfData->NumObjectTypes;i++)
    {
    //ищем объект Process (индекс 230)
        if(PerObjType->ObjectNameTitleIndex=Process_Index)
        {   //заполняем расположение описаний счётчиков PERE_COUNTER_DEFINITION
 
            PerCount=/*....*/
        }
    //  Получаем экземпляры объекта Process, если они есть
    
        if(PerObjType->NumInstances>0)
            //получаем указатель на первую структуру PERF_INFINITION
                PerDefin=/*...*/
 
    
    
    }}


Как это всё обрабатывать то? ((

Как узнать , например , загрузку процессора или ещё что-нибудь?

Не знаю, что и делать ((

Помогите , пожалуйста , подтолкните в правильное русло
Re: Непонятный ключ HKEY_PERFORMANCE_DATA
От: 11molniev  
Дата: 04.05.14 11:01
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN>Здравствуйте ! Программисты , очень нужна Ваша помощь . Уже сил нету . Как работать с ключом HKEY_PERFORMANCE_DATA? Нужно определить значение основных счётчиков продуктивности . Уже перечитал всё , что можно и нельзя,но так и не разобрался .

NNN>Как считать с этого ключа данные ?
NNN>Помогите , пожалуйста , подтолкните в правильное русло

Все очень просто, открываете гугл, вбиваете "Using the Registry Functions to Consume Counter Data" в первой ссылке переходите на MSDN, в меню слева выбираете "Retrieving Counter Data" и смотрите пример от производителя.

Если хочется ещё проще, то открываете не первую ссылку в гугле, а вторую "Using the PDH Functions to Consume Counter Data" копипастите код пяти шагов к себе и получаете программу.

PS. Заодно рекомендуется ознакомится и с остальной частью Win32 & COM developer / Windows DevCenter — Desktop --> Diagnostics --> Perfomance Counters
Re[2]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 12:32
Оценка:
Здравствуйте, 11molniev, Вы писали:

1>Здравствуйте, NNN7, Вы писали:


NNN>>Здравствуйте ! Программисты , очень нужна Ваша помощь . Уже сил нету . Как работать с ключом HKEY_PERFORMANCE_DATA? Нужно определить значение основных счётчиков продуктивности . Уже перечитал всё , что можно и нельзя,но так и не разобрался .

NNN>>Как считать с этого ключа данные ?
NNN>>Помогите , пожалуйста , подтолкните в правильное русло

1>Все очень просто, открываете гугл, вбиваете "Using the Registry Functions to Consume Counter Data" в первой ссылке переходите на MSDN, в меню слева выбираете "Retrieving Counter Data" и смотрите пример от производителя.


1>Если хочется ещё проще, то открываете не первую ссылку в гугле, а вторую "Using the PDH Functions to Consume Counter Data" копипастите код пяти шагов к себе и получаете программу.


1>PS. Заодно рекомендуется ознакомится и с остальной частью Win32 & COM developer / Windows DevCenter — Desktop --> Diagnostics --> Perfomance Counters



Спасибо за ответ . Я всё посмотрел , но всё равно не пойму , как правильно всё сделать . Мне нужно сохранить в отдельных переменных значения счётчиков , например , загрузку процессора , Memory ..

Вот посмотрел эту ссылку http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178(v=vs.85).aspx

пример не выполняется , пишет :error LNK2019: unresolved external symbol "int __cdecl DisplayCalculatedValue(struct _rawdata *,struct _rawdata *)" (?DisplayCalculatedValue@@YAHPAU_rawdata@@0@Z) referenced in function _wmain
1>c:\users\samsung\documents\visual studio 2012\Projects\ConsoleApplication7\Debug\ConsoleApplication7.exe : fatal error LNK1120: 1 unresolved externals

и какой-то огромный код в примере


Потом посмотрел 2-ой пример:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <pdh.h>
#include <pdhmsg.h>

#pragma comment(lib, "pdh.lib")

CONST ULONG SAMPLE_INTERVAL_MS    = 1000;
CONST PWSTR BROWSE_DIALOG_CAPTION = L"Select a counter to monitor.";

void wmain(void)
{
    PDH_STATUS Status;
    HQUERY Query = NULL;
    HCOUNTER Counter;
    PDH_FMT_COUNTERVALUE DisplayValue;
    DWORD CounterType;
    SYSTEMTIME SampleTime;
    PDH_BROWSE_DLG_CONFIG BrowseDlgData;
    WCHAR CounterPathBuffer[PDH_MAX_COUNTER_PATH];

    //
    // Create a query.
    //

    Status = PdhOpenQuery(NULL, NULL, &Query);
    if (Status != ERROR_SUCCESS) 
    {
       wprintf(L"\nPdhOpenQuery failed with status 0x%x.", Status);
       goto Cleanup;
    }

    //
    // Initialize the browser dialog window settings.
    //

    ZeroMemory(&CounterPathBuffer, sizeof(CounterPathBuffer));
    ZeroMemory(&BrowseDlgData, sizeof(PDH_BROWSE_DLG_CONFIG));

    BrowseDlgData.bIncludeInstanceIndex = FALSE;
    BrowseDlgData.bSingleCounterPerAdd = TRUE;
    BrowseDlgData.bSingleCounterPerDialog = TRUE;
    BrowseDlgData.bLocalCountersOnly = FALSE;
    BrowseDlgData.bWildCardInstances = TRUE;
    BrowseDlgData.bHideDetailBox = TRUE;
    BrowseDlgData.bInitializePath = FALSE;
    BrowseDlgData.bDisableMachineSelection = FALSE;
    BrowseDlgData.bIncludeCostlyObjects = FALSE;
    BrowseDlgData.bShowObjectBrowser = FALSE;
    BrowseDlgData.hWndOwner = NULL;
    BrowseDlgData.szReturnPathBuffer = CounterPathBuffer;
    BrowseDlgData.cchReturnPathLength = PDH_MAX_COUNTER_PATH;
    BrowseDlgData.pCallBack = NULL;
    BrowseDlgData.dwCallBackArg = 0;
    BrowseDlgData.CallBackStatus = ERROR_SUCCESS;
    BrowseDlgData.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
    BrowseDlgData.szDialogBoxCaption = BROWSE_DIALOG_CAPTION;

    //
    // Display the counter browser window. The dialog is configured
    // to return a single selection from the counter list.
    //

    Status = PdhBrowseCounters(&BrowseDlgData);

    if (Status != ERROR_SUCCESS) 
    {
        if (Status == PDH_DIALOG_CANCELLED) 
        {
            wprintf(L"\nDialog canceled by user.");
        }
        else 
        {
            wprintf(L"\nPdhBrowseCounters failed with status 0x%x.", Status);
        }
        goto Cleanup;
    } 
    else if (wcslen(CounterPathBuffer) == 0) 
    {
        wprintf(L"\nUser did not select any counter.");
        goto Cleanup;
    }
    else
    {
        wprintf(L"\nCounter selected: %s\n", CounterPathBuffer);
    }

    //
    // Add the selected counter to the query.
    //

    Status = PdhAddCounter(Query, CounterPathBuffer, 0, &Counter);
    if (Status != ERROR_SUCCESS) 
    {
        wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
        goto Cleanup;
    }

    //
    // Most counters require two sample values to display a formatted value.
    // PDH stores the current sample value and the previously collected
    // sample value. This call retrieves the first value that will be used
    // by PdhGetFormattedCounterValue in the first iteration of the loop
    // Note that this value is lost if the counter does not require two
    // values to compute a displayable value.
    //

    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS) 
    {
        wprintf(L"\nPdhCollectQueryData failed with 0x%x.\n", Status);
        goto Cleanup;
    }

    //
    // Print counter values until a key is pressed.
    //

    while (!_kbhit()) 
    {
        Sleep(SAMPLE_INTERVAL_MS);

        GetLocalTime(&SampleTime);

        Status = PdhCollectQueryData(Query);
        if (Status != ERROR_SUCCESS) 
        {
            wprintf(L"\nPdhCollectQueryData failed with status 0x%x.", Status);
        }

        wprintf(L"\n\"%2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d\"",
                SampleTime.wMonth,
                SampleTime.wDay,
                SampleTime.wYear,
                SampleTime.wHour,
                SampleTime.wMinute,
                SampleTime.wSecond,
                SampleTime.wMilliseconds);

        //
        // Compute a displayable value for the counter.
        //

        Status = PdhGetFormattedCounterValue(Counter,
                                             PDH_FMT_DOUBLE,
                                             &CounterType,
                                             &DisplayValue);
        if (Status != ERROR_SUCCESS) 
        {
            wprintf(L"\nPdhGetFormattedCounterValue failed with status 0x%x.", Status);
            goto Cleanup;
        }

        wprintf(L",\"%.20g\"", DisplayValue.doubleValue);
    }

Cleanup:

    //
    // Close the query.
    //

    if (Query) 
    {
       PdhCloseQuery(Query);
    }
}



Он вроде работает .
Но мне нужно сделать так , чтобы в программе уже определялось , какие счётчики считывать ( например : загрузка ЦП, Memory) . Как это можно сделать ?
Чтобы не появлялось окно с выбором счётчиков?

Пожалуйста , помогите
Re[3]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: 11molniev  
Дата: 04.05.14 12:49
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN>Спасибо за ответ . Я всё посмотрел , но всё равно не пойму , как правильно всё сделать . Мне нужно сохранить в отдельных переменных значения счётчиков , например , загрузку процессора , Memory ..


NNN>Вот посмотрел эту ссылку http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178(v=vs.85).aspx


NNN>пример не выполняется , пишет :error LNK2019: unresolved external symbol "int __cdecl DisplayCalculatedValue(struct _rawdata *,struct _rawdata *)" (?DisplayCalculatedValue@@YAHPAU_rawdata@@0@Z) referenced in function _wmain

1>>c:\users\samsung\documents\visual studio 2012\Projects\ConsoleApplication7\Debug\ConsoleApplication7.exe : fatal error LNK1120: 1 unresolved externals

Если вы вспомните язык Си и внимательно посмотрите на эту функцию или посмотрите в msdn/интернет-е код ошибки LNK2019 то обнаружите, что ошибка связана с тем, что прототип функции объявлен, использован, но нет его реализации.
Вы должны сами написать эту функцию и определить, что ей делать с получаемыми данными.

NNN>Потом посмотрел 2-ой пример:

NNN>Он вроде работает .
NNN>Но мне нужно сделать так , чтобы в программе уже определялось , какие счётчики считывать ( например : загрузка ЦП, Memory) . Как это можно сделать ?
NNN>Чтобы не появлялось окно с выбором счётчиков?
Этот пример избыточен, он добавляет один выбранный пользователем счетчик — вы можете не предоставлять пользователю выбора, а тупо вбить путь к счетчику как константу в PdhAddCounter, типа:
PdhAddCounterW(hQuery, L"\\Processor(0)\\% Processor Time", 0, &hCounter);
Но нужно помнить, что на разных системах (локализациях) пути будут отличаться. Чтоб не выводила запроса — уберите лишние вызовы. Вызовов PdhAddCounter, на один запрос может быть множество — ассоциируйте все желаемые параметры и в цикле (разумеется с паузой) получайте их значения.

NNN>Пожалуйста , помогите

Прочтите в MSDN описание всех функций из примера №2.
Re[4]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 13:04
Оценка:
Здравствуйте, 11molniev, Вы писали:

1>Здравствуйте, NNN7, Вы писали:


NNN>>Спасибо за ответ . Я всё посмотрел , но всё равно не пойму , как правильно всё сделать . Мне нужно сохранить в отдельных переменных значения счётчиков , например , загрузку процессора , Memory ..


NNN>>Вот посмотрел эту ссылку http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178(v=vs.85).aspx


NNN>>пример не выполняется , пишет :error LNK2019: unresolved external symbol "int __cdecl DisplayCalculatedValue(struct _rawdata *,struct _rawdata *)" (?DisplayCalculatedValue@@YAHPAU_rawdata@@0@Z) referenced in function _wmain

1>>>c:\users\samsung\documents\visual studio 2012\Projects\ConsoleApplication7\Debug\ConsoleApplication7.exe : fatal error LNK1120: 1 unresolved externals

1>Если вы вспомните язык Си и внимательно посмотрите на эту функцию или посмотрите в msdn/интернет-е код ошибки LNK2019 то обнаружите, что ошибка связана с тем, что прототип функции объявлен, использован, но нет его реализации.

1>Вы должны сами написать эту функцию и определить, что ей делать с получаемыми данными.

NNN>>Потом посмотрел 2-ой пример:

NNN>>Он вроде работает .
NNN>>Но мне нужно сделать так , чтобы в программе уже определялось , какие счётчики считывать ( например : загрузка ЦП, Memory) . Как это можно сделать ?
NNN>>Чтобы не появлялось окно с выбором счётчиков?
1>Этот пример избыточен, он добавляет один выбранный пользователем счетчик — вы можете не предоставлять пользователю выбора, а тупо вбить путь к счетчику как константу в PdhAddCounter, типа:
1>PdhAddCounterW(hQuery, L"\\Processor(0)\\% Processor Time", 0, &hCounter);
1>Но нужно помнить, что на разных системах (локализациях) пути будут отличаться. Чтоб не выводила запроса — уберите лишние вызовы. Вызовов PdhAddCounter, на один запрос может быть множество — ассоциируйте все желаемые параметры и в цикле (разумеется с паузой) получайте их значения.

NNN>>Пожалуйста , помогите

1>Прочтите в MSDN описание всех функций из примера №2.


Спасибо за ответ . Возник вопрос : а как правильно получить путь к счётчику? если смотреть в реестре , то описание счётчиков(имя и индекс) лежит в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 , но не писать же этот путь?
Re[5]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: 11molniev  
Дата: 04.05.14 13:41
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN>Спасибо за ответ . Возник вопрос : а как правильно получить путь к счётчику? если смотреть в реестре , то описание счётчиков(имя и индекс) лежит в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 , но не писать же этот путь?


Я точно не помню. Тема поднималась здесь на этом форуме, и там проскальзывали разные решения, но вспомнить тяжело.

Если говорить об одной системе (в смысле язык, версия, установленное по) — то путь который дает PdhEnumObjects/диалог выбора счетчика/системный монитор — будет универсален. (устанавливаемое по может расширять число счетчиков).
Если не ошибаюсь, то базовые счетчики (память, процессор — то что вас интересует) будут иметь один и тот же путь во всех версиях — но лучше поставьте на виртуалке английскую xp к примеру и посмотрите.
Re[6]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 13:51
Оценка:
Здравствуйте, 11molniev, Вы писали:

1>Здравствуйте, NNN7, Вы писали:


NNN>>Спасибо за ответ . Возник вопрос : а как правильно получить путь к счётчику? если смотреть в реестре , то описание счётчиков(имя и индекс) лежит в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 , но не писать же этот путь?


1> Я точно не помню. Тема поднималась здесь на этом форуме, и там проскальзывали разные решения, но вспомнить тяжело.


1>Если говорить об одной системе (в смысле язык, версия, установленное по) — то путь который дает PdhEnumObjects/диалог выбора счетчика/системный монитор — будет универсален. (устанавливаемое по может расширять число счетчиков).

1>Если не ошибаюсь, то базовые счетчики (память, процессор — то что вас интересует) будут иметь один и тот же путь во всех версиях — но лучше поставьте на виртуалке английскую xp к примеру и посмотрите.

ну у меня сейчас стоит Windows , 64 разрядная
то есть , нельзя записать путь как HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Memory?
Re[6]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 14:10
Оценка:
Здравствуйте, 11molniev, Вы писали:

1>Здравствуйте, NNN7, Вы писали:


NNN>>Спасибо за ответ . Возник вопрос : а как правильно получить путь к счётчику? если смотреть в реестре , то описание счётчиков(имя и индекс) лежит в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 , но не писать же этот путь?


1> Я точно не помню. Тема поднималась здесь на этом форуме, и там проскальзывали разные решения, но вспомнить тяжело.


1>Если говорить об одной системе (в смысле язык, версия, установленное по) — то путь который дает PdhEnumObjects/диалог выбора счетчика/системный монитор — будет универсален. (устанавливаемое по может расширять число счетчиков).

1>Если не ошибаюсь, то базовые счетчики (память, процессор — то что вас интересует) будут иметь один и тот же путь во всех версиях — но лучше поставьте на виртуалке английскую xp к примеру и посмотрите.

Вот , попробовал сделать что-то , вроде всё просто , но не работает , везде faild выбивает :


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#pragma comment(lib, "pdh.lib")

CONST ULONG SAMPLE_INTERVAL_MS    = 1000;
CONST PWSTR BROWSE_DIALOG_CAPTION = L"Select a counter to monitor.";

void wmain(void)
{
    PDH_STATUS Status;
    HQUERY Query = NULL;
    HCOUNTER Counter;
    DWORD CounterType;
    SYSTEMTIME SampleTime;
    PDH_FMT_COUNTERVALUE DisplayValue;


   //Создаём запрос 
    Status = PdhOpenQuery(NULL, NULL, &Query);  //запрос на использование счётчиков производительности
    if (Status != ERROR_SUCCESS) 
    {
      wprintf(L"\nPdhOpenQuery failed with status 0x%x.", Status);
      
    }

    /*Добавить счётчик в запрос*/
    Status = PdhAddCounter(Query, (LPCTSTR)"\\Processor(0)\\% Processor Time", 0, &Counter);
    if (Status != ERROR_SUCCESS) 
    {
        wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
        
    }
    
    /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);  
    if (Status != ERROR_SUCCESS) 
    {
       wprintf(L"\nPdhCollectQueryData failed with 0x%x.\n", Status);
    }
    
     /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,
                                             PDH_FMT_DOUBLE,
                                             &CounterType,
                                             &DisplayValue);
   if (Status != ERROR_SUCCESS) 
    {
            wprintf(L"\nPdhGetFormattedCounterValue failed with status 0x%x.", Status);
    }

        wprintf(L"\"%.20g\"", DisplayValue.doubleValue);
    

//Cleanup:

    //
    // Close the query.
    //
    if (Query) 
    {
       PdhCloseQuery(Query);
    }
}


Помогите , пожалуйста , что не так сделал?
Re[7]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 14:26
Оценка:
Первая функция создания запроса работает . А вот во второй (и в следствии дальше во всех остальных) выдаёт ошибку


/*Добавить счётчик в запрос*/
   Status = PdhAddCounter(Query, (LPCTSTR)"\\Processor(0)\\% Processor Time", 0, &Counter);
    if (Status != ERROR_SUCCESS) 
    {
        wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
        
    }
Re[7]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: 11molniev  
Дата: 04.05.14 14:55
Оценка:
Здравствуйте, NNN7, Вы писали:

1>>Если говорить об одной системе (в смысле язык, версия, установленное по) — то путь который дает PdhEnumObjects/диалог выбора счетчика/системный монитор — будет универсален. (устанавливаемое по может расширять число счетчиков).

1>>Если не ошибаюсь, то базовые счетчики (память, процессор — то что вас интересует) будут иметь один и тот же путь во всех версиях — но лучше поставьте на виртуалке английскую xp к примеру и посмотрите.

NNN>Вот , попробовал сделать что-то , вроде всё просто , но не работает , везде faild выбивает :


NNN>

NNN>    /*Добавить счётчик в запрос*/
NNN>    Status = PdhAddCounter(Query, (LPCTSTR)"\\Processor(0)\\% Processor Time", 0, &Counter);
NNN>    if (Status != ERROR_SUCCESS) 
NNN>    {
NNN>        wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
        
NNN>    }
NNN>


1. Надо запоминать, что делаете или делегировать это системе контроля версий
2. (LPCTSTR) не надо писать. Тем более это скорей всего ошибка, либо делайте так:
PdhAddCounterA(Query, "\\Processor(0)\\% Processor Time", 0, &Counter);
либо так:
PdhAddCounterW(Query, L"\\Processor(0)\\% Processor Time", 0, &Counter);
второй вариант предпочтительней
3. Не надо задавать вопросы "везде faild" и потому что "failed" и потому что есть GetLastError/FormatMessage которые описывают причину ошибки и код ошибки которая возвращает функция не ERROR_SUCCESS.
4. А счетчик "\\Processor(0)\\% Processor Time" у вас в русскоязычной системе есть? На русскоязычной восьмерке он будет называться L"\\Сведения о процессоре(Total)\\% загруженности процессора".
Re[8]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 15:21
Оценка:
1>1. Надо запоминать, что делаете или делегировать это системе контроля версий
1>2. (LPCTSTR) не надо писать. Тем более это скорей всего ошибка, либо делайте так:
1>PdhAddCounterA(Query, "\\Processor(0)\\% Processor Time", 0, &Counter);
1>либо так:
1>PdhAddCounterW(Query, L"\\Processor(0)\\% Processor Time", 0, &Counter);
1>второй вариант предпочтительней
1>3. Не надо задавать вопросы "везде faild" и потому что "failed" и потому что есть GetLastError/FormatMessage которые описывают причину ошибки и код ошибки которая возвращает функция не ERROR_SUCCESS.
1>4. А счетчик "\\Processor(0)\\% Processor Time" у вас в русскоязычной системе есть? На русскоязычной восьмерке он будет называться L"\\Сведения о процессоре(Total)\\% загруженности процессора".

Исправил , как Вы сказали :



    /*Добавить счётчик в запрос*/
  Status = PdhAddCounterA(Query, "\\Сведения о процессоре(Total)\\% загруженности процессора", 0, &Counter);  //PdhAddCounter(Query,"\\Процессор(_Total)\\% загруженности процессора", 0, &Counter);
    if (Status != ERROR_SUCCESS) 
    {
        wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
        
    }
    else 
    {   std::cout<<std::endl;
        wprintf(L"\nAddCounter - OK");
    }
    
    /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
   Status = PdhCollectQueryData(Query);  
    if (Status != ERROR_SUCCESS) 
    {
       wprintf(L"\nPdhCollectQueryData failed with 0x%x.\n", Status);
       int error =0;
       error=GetLastError();
            std::cout<<"error="<<error<<std::endl;
    }
    else 
    {    std::cout<<std::endl;
         wprintf(L"\CollectQueryData -OK\n");
    }
    
    /*Вычислить отображаемое  значение для указанного счетчика.*/
   Status = PdhGetFormattedCounterValue(Counter,
                                             PDH_FMT_DOUBLE,
                                             &CounterType,
                                             &DisplayValue);
   if (Status != ERROR_SUCCESS) 
    {
           // wprintf(L"\nPdhGetFormattedCounterValue failed with status 0x%x.", Status);
            int error =GetLastError();
            std::cout<<"error="<<error;
    }
   
    else 
    {    std::cout<<std::endl;
         wprintf(L"\ Formatted -OK\n");
    }
    

    wprintf(L",\"%.20g\"", DisplayValue.doubleValue);
//Cleanup:

    //
    // Close the query.
    //
    if (Query) 
    {
       PdhCloseQuery(Query);
    }
}


Не работает . GetLastError () возвращает непонятные вообще ошибки
Re[9]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 04.05.14 15:23
Оценка:
GetLastError () возвращает непонятные вообще ошибки, код = -214781647 в случаях вызова Collect..() и Format..()
Re: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 05.05.14 13:30
Оценка:
Здравствуйте, NNN7, Вы писали:

С именами счетчиков действительно дело обстоит неважно, они в русской и английской версиях различны. Похоже, не лечится.

Если можно допустить юзеровский интерфейс, советую посмотреть в сторону PdhBrowseCounters

http://msdn.microsoft.com/en-us/library/windows/desktop/aa372542(v=vs.85).aspx

Она выдаст диалог, в котором можно выбирать счетчки, а потом получите их имена в соответствии с текущей локалью

Вот здесь

http://msdn.microsoft.com/en-us/library/windows/desktop/aa371886(v=vs.85).aspx

пример, правда, только для одного счетчика.
With best regards
Pavel Dvorkin
Re[2]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 05.05.14 16:19
Оценка:
Здравствуйте, Pavel Dvorkin.
Спасибо , с этим примером я разобрался , почитал , что к чему . Убрал интерфейс , попробовал в консоли всё это сделать для некоторых счётчиков — всё получилось .
Мне теперь нужно в графическом виде это представить , а именно записать значение счётчика (какого-либо ) в ListBox . Всё считает , все функции работают , но не могу разобраться , как конвертировать результат в строку — для вывода .

Вот мой код:


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
#define COMBOBOX 1
#define LISTBOX 2
HWND CB,LB;
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );

//главня функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{

 wchar_t str [51];  //буфер
 PDH_STATUS Status;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 SYSTEMTIME SampleTime;
 PDH_FMT_COUNTERVALUE DisplayValue;

 char buf [50];

  switch (uMsg)
 {

case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {EndDialog(hwnd,NULL);
                return TRUE;
               }

              break;

case WM_INITDIALOG:
    //Создаём список лет:
        CB=CreateWindow((LPCSTR)"Combobox",(LPCSTR)"Combo1", CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE/*|WS_VSCROLL|CBS_DROPDOWNLIST*/,
        90,360,200,300, hwnd, (HMENU)COMBOBOX,0, NULL); 
        
        //Заносим значения лет:
        SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Use time");
        SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
        SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");


   //Создаём запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);  //запрос на использование счётчиков производительности
   if(Status==ERROR_SUCCESS)
   {MessageBox(hwnd,(LPSTR)"open-OK",(LPCSTR)"",MB_OK);}

    /*Добавить счётчик в запрос*/
 
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status == ERROR_SUCCESS)
    {MessageBox(hwnd,(LPSTR)"add-OK",(LPCSTR)"",MB_OK);}

    /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status == ERROR_SUCCESS)
      {MessageBox(hwnd,(LPSTR)"collect-OK",(LPCSTR)"",MB_OK);
      }
 
    Sleep(1000);
 
    Status = PdhCollectQueryData(Query);
    if (Status == ERROR_SUCCESS)
    {MessageBox(hwnd,(LPSTR)"collect-OK",(LPCSTR)"",MB_OK);
    }
   
    
     /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,
        PDH_FMT_DOUBLE,
        &CounterType,
        &DisplayValue);
    if(Status==ERROR_SUCCESS)
    {MessageBox(hwnd,(LPSTR)"formatted-OK",(LPCSTR)"",MB_OK);
    }

    //вывод результата:

        
        LB=CreateWindow("Listbox", NULL, 
        WS_VISIBLE|WS_CHILD| WS_VSCROLL | WS_TABSTOP |WS_BORDER ,
        90,140,300,200, hwnd, (HMENU)LISTBOX, 0, NULL); 
        
        wsprintf(buf, "%f", DisplayValue);
        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);

     if (Query)
    {
        PdhCloseQuery(Query);
    }
 }
   return 0;   
}



Вот место , где пытаюсь занести в ListBox :


 LB=CreateWindow("Listbox", NULL, 
        WS_VISIBLE|WS_CHILD| WS_VSCROLL | WS_TABSTOP |WS_BORDER ,
        90,140,300,200, hwnd, (HMENU)LISTBOX, 0, NULL); 
        
        wsprintf(buf, "%f", DisplayValue);
        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);


Но на конвертацию значение не реагирует .

Как это можно сделать ? Помогите , пожалуйста .
Заранее спасибо!
Re[2]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 05.05.14 18:18
Оценка:
Здравствуйте, Pavel Dvorkin. С преобразованием я уже разобрался , вроде получилось :



#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
#define COMBOBOX 1
#define LISTBOX 2
HWND CB,LB;

 wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;


BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );

//главня функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   return TRUE;
                }

               if(LOWORD(wpar)==SELECT)
               {
                GetDlgItemText(hwnd,COMBOBOX,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               }
              break;

    case WM_INITDIALOG:
    //Создаём список счётчиков производительности
    CB=CreateWindow((LPCSTR)"Combobox",(LPCSTR)"Combo1", CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE,90,360,200,300, hwnd, (HMENU)COMBOBOX,0, NULL); 
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=CreateWindow("Listbox", NULL,WS_VISIBLE|WS_CHILD| WS_VSCROLL | WS_TABSTOP |WS_BORDER , 90,140,300,200, hwnd, (HMENU)LISTBOX, 0, NULL); 
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}
 }
   return 0;   
}


Возник такой вопрос : а как сделать , чтобы выводимые значения обновлялись как-то ? сами или по нажатию кнопки .. Думаю,думаю..никак не могу сообразить .


Эх, ещё бы с функциями реестра как-то разобраться..
Re[3]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 06.05.14 05:09
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN> case WM_INITDIALOG:

NNN> //Создаём список счётчиков производительности
NNN> CB=CreateWindow((LPCSTR)"Combobox",(LPCSTR)"Combo1", CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE,90,360,200,300, hwnd, (HMENU)COMBOBOX,0, NULL);

Не стоит так делать. Просто в редакторе ресурсов брось на панель диалога комбобокс, взяв его с панели инструментов. Для получения его хендла — GetDlgItem

NNN> //Создаём список для вывода значения счётчиков

NNN> LB=CreateWindow("Listbox", NULL,WS_VISIBLE|WS_CHILD| WS_VSCROLL | WS_TABSTOP |WS_BORDER , 90,140,300,200, hwnd, (HMENU)LISTBOX, 0, NULL);

То же самое.

NNN> if(Status!=ERROR_SUCCESS)

NNN> {
NNN> MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);

Хорошо, но надо в этом случае выйти и закрыть диалог, а сейчас идет все дальше...

NNN> if (Status != ERROR_SUCCESS)

NNN> {
NNN> MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
NNN> }

То же. И далее то же.

NNN>Возник такой вопрос : а как сделать , чтобы выводимые значения обновлялись как-то ? сами или по нажатию кнопки .. Думаю,думаю..никак не могу сообразить .


По таймеру. Заведи таймер (SetTimer) на WM_INITDIALOG, по WM_TIMER делай все, что делаешь (вынеси в отдельную функцию) и перезаливай в контролы. Не забудь при закрытии диалога его убить (KillTimer).


NNN>Эх, ещё бы с функциями реестра как-то разобраться..


Не надо, Pdh проще и понятнее. Он специально для этого разработан.
With best regards
Pavel Dvorkin
Re[4]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Аноним  
Дата: 06.05.14 19:17
Оценка:
Здравствуйте, Pavel Dvorkin. Снова спасибо Вам за ответ .Ошибки попытался исправить.
Честно — никогда не делал ничего с таймером ( новичок совсем). Почитал о всём этом . Сделал так:



#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
HWND CB,LB;
 
wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;



BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );

//главня функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   return TRUE;
                }

               if(LOWORD(wpar)==SELECT)
               {
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               }
              break;

    case WM_TIMER:
        //проделываем :

        if(LOWORD(wpar)==SELECT)
               {
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
                }

              break;

 case WM_INITDIALOG:

     /*Создание таймера!*/
     SetTimer(hwnd,1,3000,NULL);  //таймер на каждые 3 секунды

    //Создаём список счётчиков производительности
    CB=GetDlgItem(hwnd,COMBO);
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=GetDlgItem(hwnd,LIST);
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}
 }
   return 0;   
}


Установил SetTimer(), а в WM_TIME проделывал действия . При выходе — убиваем таймер .
Но что-то оно не то . Не понял на счёт контролов (что это и зачем ?) Пожалуйста , можете объяснить , что к чему?

На счёт функций реестра.. — нужны они мне всё равно ( знаю, что глупо их использовать), задают такое , сам не рад
Сейчас буду читать и о них, попытаюсь хоть немного разобраться
Re[2]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Аноним  
Дата: 06.05.14 19:33
Оценка:
Здравствуйте, Pavel Dvorkin. + ещё забыл дописать уничтожение таймера:

//Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   KillTimer(hwnd,1);
                   return TRUE;
                }
Re[5]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 07.05.14 07:42
Оценка:
Здравствуйте, Аноним, Вы писали:


А> case WM_TIMER:

А> //проделываем :

Не то проделываем. Здесь надо вызвать функцию (отдельную), которая делает то, что сейчас делается на WM_INITDIALOG. Иными словам ,вытащить код из WM_INITDIALOG, оформить как отдельную функцию и здесь вызывать. Она должна, во-первых, очищать листбокс и комбобокс, потом делать все Pdh — запросы, получать тем самым новые DispalyValue и DispalyValue2, а дальше, как у тебя. Тогда они будут по таймеру меняться, ну и отображаться.
With best regards
Pavel Dvorkin
Re[6]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 07.05.14 16:04
Оценка:
Здравствуйте, Pavel Dvorkin. Спасибо за ответ . Всё равно не получается никак
Создал функцию func() , в которой очищаю листбокс и комбобокс , а дальше просто вставил текст с WM_INITDIALOG. А в WM_TIMER вызвал эту функцию . Но неправильно сделал , не пойму , почему . Можете , пожалуйста , помочь , как это правильно сделать ? Вот код мой :


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
HWND CB,LB;
int func(HWND hwnd);
 

wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;



BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );

//главня функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
               KillTimer(hwnd,1);
             
                   return TRUE;
                }

               if(LOWORD(wpar)==SELECT)
               {
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               }
              break;

    case WM_TIMER:
        func(hwnd);

 case WM_INITDIALOG:
     //установка таймера
     SetTimer(hwnd,1,3000,NULL);
    
    //Создаём список счётчиков производительности
    CB=GetDlgItem(hwnd,COMBO);
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=GetDlgItem(hwnd,LIST);
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}
 }
   return 0;   
}

//функция
int func(HWND hwnd)
{

    //Создаём
    CB=GetDlgItem(hwnd,COMBO);
    LB=GetDlgItem(hwnd,LIST);
    //очищаем :
    SendMessage(LB, LB_RESETCONTENT, 0, 0);
    SendMessage(CB,LB_RESETCONTENT,0,0);

   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}


}


Ошибок не выдаёт , но при запуске бред какой-то получается . Нули выводит. Сил уже нету , не пойму , что к чему
Re[6]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 07.05.14 19:21
Оценка:
Здравствуйте, Pavel Dvorkin. Вот ещё немного переделал код:


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
HWND CB,LB;
int func(HWND hwnd);
 

wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;



BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );

//главня функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
               KillTimer(hwnd,1);
             
                   return TRUE;
                }

               if(LOWORD(wpar)==SELECT)
               {
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               }
              break;

    case WM_TIMER:
        func(hwnd);
        break;

 case WM_INITDIALOG:
     //установка таймера
     SetTimer(hwnd,1,1000,NULL);
    
    //Создаём список счётчиков производительности
    CB=GetDlgItem(hwnd,COMBO);
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=GetDlgItem(hwnd,LIST);
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}
 }
   return 0;   
}

//функция
int func(HWND hwnd)
{
    //Создаём
    LB=GetDlgItem(hwnd,LIST);
    //очищаем :
    SendMessage(LB, LB_RESETCONTENT, 0, 0);
    
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query2){PdhCloseQuery(Query2);}

    
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               
}


Уже немного похоже на правду , хоть новые значения появляются , но смущает , что при выборе счётчика сначала заносятся 2 одинаковых значения ( а должно одно) , потом они меняются на другое и так далее (переключаются каждую секунду) и если выбрать какой-то другой счётчик , то результат 1-го счётчика стирается. А нужно- чтобы он сохранялся на своём месте и дальше продолжал меняться.

Что не так написал ?
Re[7]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 08.05.14 04:40
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN> if(LOWORD(wpar)==SELECT)

NNN> {
NNN> GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
NNN> if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
NNN> { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
NNN> SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
NNN> }

NNN> if(lstrcmp((LPCSTR)str,"% User time") == 0)

NNN> {
NNN> sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
NNN> SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2);
NNN> }
NNN> }
NNN> break;

NNN> case WM_TIMER:

NNN> func(hwnd);
NNN> break;

NNN>Уже немного похоже на правду , хоть новые значения появляются , но смущает , что при выборе счётчика сначала заносятся 2 одинаковых значения ( а должно одно) , потом они меняются на другое и так далее (переключаются каждую секунду) и если выбрать какой-то другой счётчик , то результат 1-го счётчика стирается. А нужно- чтобы он сохранялся на своём месте и дальше продолжал меняться.


NNN>Что не так написал ?


Код выше на if(LOWORD(wpar)==SELECT) заносит что-то, а код в func тоже заносит. В итоге 2 раза.

Одно из двух :

Либо изменение должно делаться по нажатию Select. Тогда таймеровский код должен лишь изменять DisplayValue1-2, но не заносить. Изменеие произойдет только при нажатии Select
Либо таймеровский код как есть, но тогда Select не нужна. Изменения будут производиться автоматически

Либо что-то третье, но тогда продумай, что именно.

P.S. Код на WM_INITDIALOG фактически тот же, что и в func. Имеет смысл убрать дублирование. Просто вызови на WM_INITDIALOG эту func.
With best regards
Pavel Dvorkin
Re[8]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 09.05.14 08:20
Оценка:
Здравствуйте, Pavel Dvorkin. Спасибо большое за ответ , учёл замечания. Возникла такая идея : сделать функцию добавления нового запроса , чтобы не дублировать каждый раз текст , а просто передать в функцию путь счётчика:


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
HWND CB,LB,LB2,LB3;
void func(HWND hwnd);
int New_Query(HWND hwnd,LPCWSTR s);

 wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;



BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, то закрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   KillTimer(hwnd,1);
                   return TRUE;
                }
               if(LOWORD(wpar)==STOP)//убрать таймер
               {KillTimer(hwnd,1);
               }
              break;

    case WM_TIMER:
        func(hwnd);
        break;

 case WM_INITDIALOG:
    //установка таймера
     SetTimer(hwnd,1,500,NULL);
    //Создаём список счётчиков производительности
    CB=GetDlgItem(hwnd,COMBO);
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=GetDlgItem(hwnd,LIST);
    LB2=GetDlgItem(hwnd,LIST2);
    LB3=GetDlgItem(hwnd,LIST3);
    func(hwnd);
 }
   return 0;   
}

//функция
void func(HWND hwnd)
{   //очищаем :
    SendMessage(LB, LB_RESETCONTENT, 0, 0);
    SendMessage(LB2,LB_RESETCONTENT,0,0);

        LPCWSTR s1="\\Processor(_Total)\\% User Time";
    New_Query(hwnd,s1);
                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

                if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB2, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               
}

int New_Query(HWND hwnd,LPCWSTR s)   //функция создания нового запроса
{
   //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query,s, 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
    Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    
}


Но возникла проблема : как передать LPCWSTR в функцию ? сейчас у меня ругается :error C2440: 'initializing' : cannot convert from 'const char [31]' to 'LPCWSTR'
подскажите , пожалуйста
Re[8]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 09.05.14 08:25
Оценка:
Здравствуйте, Pavel Dvorkin.И вот так вот писал :int New_Query(HWND hwnd,TCHAR s[])- не передаёт
Re[8]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 09.05.14 08:47
Оценка:
Здравствуйте, Pavel Dvorkin, также непонятен один момент . Уже перепробовал много вариантов решения , и таймеры разные ставил и пробовал разбивать на несколько функция — не получается Проблема такая : я сделал для каждого счётчика — отдельный листбокс . При выборе счётчика его значение заносится в соответствующий листбокс , но при выборе следующего счётчика значения заносится в новый листбокс , а в 1-ом всё стирается и прекращает работать . А нужно , чтобы все 3 листбокса работали вместе , независимо друг от друга .

Как это можно реализовать ? Уже всю голову сломал — не пойму .

Вот код:


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#pragma comment(lib, "pdh.lib")
HWND CB,LB,LB2,LB3;
int func(HWND hwnd);

 wchar_t str [51];  //буфер
 TCHAR buf[20] = {0};  //для вывода
 TCHAR buf2 [20] ={0};
 PDH_STATUS Status;
 PDH_STATUS Status2;
 HQUERY Query2=NULL;
 HQUERY Query = NULL;
 HCOUNTER Counter;
 DWORD CounterType;
 PDH_FMT_COUNTERVALUE DisplayValue;
  HCOUNTER Counter2;
 DWORD CounterType2;
 PDH_FMT_COUNTERVALUE DisplayValue2;



BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 
BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
  switch (uMsg)
 {
    case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   KillTimer(hwnd,1);
                   return TRUE;
                }
               if(LOWORD(wpar)==STOP)//убрать таймер
                 {KillTimer(hwnd,1);
                 }

              break;

    case WM_TIMER:
        func(hwnd);
        break;

 case WM_INITDIALOG:
    //установка таймера
     SetTimer(hwnd,1,500,NULL);
     SetTimer(hwnd,2,500,NULL);
    //Создаём список счётчиков производительности
    CB=GetDlgItem(hwnd,COMBO);
    //Заносим возможные варианты  счётчиков
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time");
    SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time");
    //Создаём список для вывода значения счётчиков
    LB=GetDlgItem(hwnd,LIST);
    LB2=GetDlgItem(hwnd,LIST2);
    LB3=GetDlgItem(hwnd,LIST3);
    func(hwnd);
 }
   return 0;   
}

//функция
int func(HWND hwnd)
{   //очищаем :
    SendMessage(LB, LB_RESETCONTENT, 0, 0);
    SendMessage(LB2,LB_RESETCONTENT,0,0);
    
  //Создать запрос 
   Status = PdhOpenQueryW(NULL, 0, &Query);
   if(Status!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
       return TRUE;
   }
   //Добавить счётчик в запрос
    Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
   /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
   Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status = PdhCollectQueryData(Query);
    if (Status != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
   Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue);
    if(Status!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
    if (Query){PdhCloseQuery(Query);}

    //НОВЫЙ ЗАПРОС!!!
     Status2 = PdhOpenQueryW(NULL, 0, &Query2);
   if(Status2!=ERROR_SUCCESS)
   {
       MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK);
       EndDialog(hwnd,NULL);
                   return TRUE;
   }
   //Добавить счётчик в запрос
    Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
/*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе
    и обновляет код состояния каждого счетчика*/
 Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    Sleep(1000);
    Status2 = PdhCollectQueryData(Query2);
    if (Status2 != ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
    /*Вычислить отображаемое  значение для указанного счетчика.*/
 Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2);
    if(Status2!=ERROR_SUCCESS)
    {
        MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
                   return TRUE;
    }
        /*закрываем запрос*/
if (Query2){PdhCloseQuery(Query2);}


                GetDlgItemText(hwnd,COMBO,(LPSTR)str,51);
                if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0)
                    {   sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue);
                        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);
                    }

              if(lstrcmp((LPCSTR)str,"% User time") == 0)
                    {
                        sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue);
                        SendMessage(LB2, LB_ADDSTRING, 1, ( LPARAM)buf2);
                    }
               
}
Re[9]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 09.05.14 09:35
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN>Но возникла проблема : как передать LPCWSTR в функцию ? сейчас у меня ругается :error C2440: 'initializing' : cannot convert from 'const char [31]' to 'LPCWSTR'

NNN>подскажите , пожалуйста

Почитай про Unicode и ANSI. Либо то, либо другое. У тебя какая-то странная смесь, отсюда и проблемы.

Проект юникодный или нет ?
With best regards
Pavel Dvorkin
Re[10]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 09.05.14 09:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, NNN7, Вы писали:


NNN>>Но возникла проблема : как передать LPCWSTR в функцию ? сейчас у меня ругается :error C2440: 'initializing' : cannot convert from 'const char [31]' to 'LPCWSTR'

NNN>>подскажите , пожалуйста

PD>Почитай про Unicode и ANSI. Либо то, либо другое. У тебя какая-то странная смесь, отсюда и проблемы.


PD>Проект юникодный или нет ?


Нет , не юникодный
Re[11]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 09.05.14 12:15
Оценка:
Здравствуйте, NNN7, Вы писали:


PD>>Проект юникодный или нет ?


NNN>Нет , не юникодный


Тогда незачем wchar_t использовать. Используй ВЕЗДЕ просто char.
With best regards
Pavel Dvorkin
Re: Пример работы с HKEY_PERFORMANCE_DATA
От: SergeCpp Россия http://zoozahita.ru
Дата: 09.05.14 13:07
Оценка:
http://rsdn.ru/forum/src/1488374.all
Автор: SergeCpp
Дата: 15.11.05

http://old-dos.ru/files/file_3785.html
Файл Perf.cpp
http://zoozahita.ruБездомные животные Екатеринбурга ищут хозяев
Re[12]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 05:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, NNN7, Вы писали:



PD>>>Проект юникодный или нет ?


NNN>>Нет , не юникодный


PD>Тогда незачем wchar_t использовать. Используй ВЕЗДЕ просто char.


Спасибо за ответ !
Re[12]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 06:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, NNN7, Вы писали:



PD>>>Проект юникодный или нет ?


NNN>>Нет , не юникодный


PD>Тогда незачем wchar_t использовать. Используй ВЕЗДЕ просто char.


Спасибо!
Re[12]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 11:42
Оценка:
Здравствуйте, Pavel Dvorkin. Можно к Вам обратиться ещё с вопросами ? разобрался с PDH функциями , но теперь нужно разобраться ещё и с функциями реестра .
Прочитал пример с msdn : http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178%28v=vs.85%29.aspx и для вывода http://msdn.microsoft.com/en-us/library/windows/desktop/aa371891%28v=vs.85%29.aspx . Это консольный вариант вывода значения счётчика , работает нормально, всё выводит .

Но как реализовать это в графическом варианте ? Чтобы вывело значение счётчика не в консоль , а в листбокс , например . Я всё пробую — никак не получается переделать программу.

Вот что я переделывал:


#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <strsafe.h>
using namespace std;
#pragma comment(lib, "pdh.lib")

// Contains the elements required to calculate a counter value.
typedef struct _rawdata
{
    DWORD CounterType;
    ULONGLONG Data;          // Raw counter data
    LONGLONG Time;           // Is a time value or a base value
    DWORD MultiCounterData;  // Second raw counter value for multi-valued counters
    LONGLONG Frequency;
}RAW_DATA, *PRAW_DATA;

#define INIT_OBJECT_BUFFER_SIZE 48928   // Initial buffer size to use when querying specific objects.
#define INIT_GLOBAL_BUFFER_SIZE 122880  // Initial buffer size to use when using "Global" to query all objects.
#define BUFFER_INCREMENT 16384          // Increment buffer size in 16K chunks.
#define MAX_INSTANCE_NAME_LEN      255  // Max length of an instance name.
#define MAX_FULL_INSTANCE_NAME_LEN 511  // Form is parentinstancename/instancename#nnn.
//прототипы:
LPBYTE GetPerformanceData(LPWSTR pwszSource, DWORD dwInitialBufferSize);
BOOL GetCounterValues(DWORD dwObjectIndex, DWORD dwCounterIndex, LPWSTR pInstanceName, RAW_DATA* pRawData);
BOOL GetValue(PERF_OBJECT_TYPE* pObject, PERF_COUNTER_DEFINITION* pCounter, PERF_COUNTER_BLOCK* pCounterDataBlock, PRAW_DATA pRawData);
PERF_COUNTER_BLOCK* GetCounterBlock(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName);
PERF_COUNTER_DEFINITION* GetCounter(PERF_OBJECT_TYPE* pObject, DWORD dwCounterToFind);
PERF_OBJECT_TYPE* GetObject(DWORD dwObjectToFind);
PERF_INSTANCE_DEFINITION* GetObjectInstance(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName);
DWORD GetSerialNo(LPWSTR pInstanceName);
BOOL GetFullInstanceName(PERF_INSTANCE_DEFINITION* pInstance, DWORD CodePage, WCHAR* pName);
BOOL ConvertNameToUnicode(UINT CodePage, LPCSTR pNameToConvert, DWORD dwNameToConvertLen, LPWSTR pConvertedName);
PERF_INSTANCE_DEFINITION* GetParentInstance(PERF_OBJECT_TYPE* pObject, DWORD dwInstancePosition);
BOOL DisplayCalculatedValue(RAW_DATA* pSample1, RAW_DATA* pSample2);
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );
//Global variables
LPBYTE g_pPerfDataHead = NULL;   // Head of the performance data.
HWND CB,LB,LB2,LB3, list;
 wchar_t str [51];  //буфер

 //главная функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 

BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
    RAW_DATA Sample1;
    RAW_DATA Sample2;
    BOOL fSuccess = FALSE;

  switch (uMsg)
 {
case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   return TRUE;
                }
    break;
case WM_INITDIALOG:
    // Retrieve counter data for the Processor object.
    g_pPerfDataHead = (LPBYTE)GetPerformanceData(L"238", INIT_OBJECT_BUFFER_SIZE);
    if (NULL == g_pPerfDataHead)
    {   MessageBox(hwnd,(LPCWSTR)"GetPerformanceData failed",(LPCWSTR)"",MB_OK);
        EndDialog(hwnd,NULL);
        return 0;
    }

    // Then, sample the "% User Time" counter for instance "0" of the Processor object.
    fSuccess = GetCounterValues(238, 142, L"0", &Sample1);
    if (FALSE == fSuccess)
    {    MessageBox(hwnd,(LPCWSTR)"GetCounterValues failed",(LPCWSTR)"",MB_OK);
         EndDialog(hwnd,NULL);
         return 0;
    }
     // Display 2 data points for the counter.
    for (DWORD i = 0; i <2; i++)
    {
        Sleep(1000);  // Wait one second before taking the next sample

        // Retrieve the object data again and get the next sample.
        g_pPerfDataHead = (LPBYTE)GetPerformanceData(L"238", INIT_OBJECT_BUFFER_SIZE);
        if (NULL == g_pPerfDataHead)
        {   MessageBox(hwnd,(LPCWSTR)"GetPerformanceData in loop failed",(LPCWSTR)"",MB_OK);
            EndDialog(hwnd,NULL);
            return 0;
        }

        fSuccess = GetCounterValues(238,142, L"0", &Sample2);
        if (FALSE == fSuccess)
        {    MessageBox(hwnd,(LPCWSTR)"GetCounterValues failed",(LPCWSTR)"",MB_OK);
             EndDialog(hwnd,NULL);
             return 0;
           
        }
        // Calculate the value based on the two samples. For counter
        // types that do not use two samples, set the second parameter
        // to NULL.
        fSuccess = DisplayCalculatedValue(&Sample1, &Sample2);
        if (FALSE == fSuccess)
        {   MessageBox(hwnd,(LPCWSTR)"DisplayCalculatedValue failed",(LPCWSTR)"",MB_OK);
            EndDialog(hwnd,NULL);
            return 0;
        }
    }
        return 0;
    }
  }


Эта главная функция , в которой вызываются все остальные функции .

Остальные функции:


//Функции :


// Retrieve a buffer that contains the specified performance data.
// The pwszSource parameter determines the data that GetRegistryBuffer returns.
//
// Typically, when calling RegQueryValueEx, you can specify zero for the size of the buffer
// and the RegQueryValueEx will set your size variable to the required buffer size. However, 
// if the source is "Global" or one or more object index values, you will need to increment
// the buffer size in a loop until RegQueryValueEx does not return ERROR_MORE_DATA. 
LPBYTE GetPerformanceData(LPWSTR pwszSource, DWORD dwInitialBufferSize)
{
    LPBYTE pBuffer = NULL;
    DWORD dwBufferSize = 0;        //Size of buffer, used to increment buffer size
    DWORD dwSize = 0;              //Size of buffer, used when calling RegQueryValueEx
    LPBYTE pTemp = NULL;           //Temp variable for realloc() in case it fails
    LONG status = ERROR_SUCCESS; 
    HANDLE hHeap;
    dwBufferSize = dwSize = dwInitialBufferSize;

    hHeap=HeapCreate(0,0x01000,0);  //куча
    pBuffer=(LPBYTE)HeapAlloc(hHeap,0,0);   //вместо malloc
   // pBuffer = (LPBYTE)malloc(dwBufferSize);
    if (pBuffer)
    {
        while (ERROR_MORE_DATA == (status = RegQueryValueEx(HKEY_PERFORMANCE_DATA, pwszSource, NULL, NULL, pBuffer, &dwSize)))
        {
            //Contents of dwSize is unpredictable if RegQueryValueEx fails, which is why
            //you need to increment dwBufferSize and use it to set dwSize.
            dwBufferSize += BUFFER_INCREMENT;

            pTemp = (LPBYTE)realloc(pBuffer, dwBufferSize);
            if (pTemp)
            {
                pBuffer = pTemp;
                dwSize = dwBufferSize;
            }
        }

        if (ERROR_SUCCESS != status)
        {  HeapFree(hHeap,0,pBuffer);  //вместо  free
            //free(pBuffer);
            pBuffer = NULL;
        }
    }


    RegCloseKey(HKEY_PERFORMANCE_DATA);

    return pBuffer;
}


// Use the object index to find the object in the performance data. Then, use the
// counter index to find the counter definition. The definition contains the offset
// to the counter data in the counter block. The location of the counter block 
// depends on whether the counter is a single instance counter or multiple instance counter.
// After finding the counter block, retrieve the counter data.
BOOL GetCounterValues(DWORD dwObjectIndex, DWORD dwCounterIndex, LPWSTR pInstanceName, RAW_DATA* pRawData)
{
    PERF_OBJECT_TYPE* pObject = NULL;
    PERF_COUNTER_DEFINITION* pCounter = NULL;
    PERF_COUNTER_BLOCK* pCounterDataBlock = NULL;
    BOOL fSuccess = FALSE;

    pObject = GetObject(dwObjectIndex);

    pCounter = GetCounter(pObject, dwCounterIndex);
    if (NULL == pCounter)
    {
       
        goto cleanup;
    }

    // Retrieve a pointer to the beginning of the counter data block. The counter data
    // block contains all the counter data for the object.
    pCounterDataBlock = GetCounterBlock(pObject, pInstanceName);
    if (NULL == pCounterDataBlock)
    {
        
        goto cleanup;
    }

    ZeroMemory(pRawData, sizeof(RAW_DATA));
    pRawData->CounterType = pCounter->CounterType;
    fSuccess = GetValue(pObject, pCounter, pCounterDataBlock, pRawData);

cleanup:

    return fSuccess;
}


// Use the object index to find the object in the performance data.
PERF_OBJECT_TYPE* GetObject(DWORD dwObjectToFind)
{
    LPBYTE pObject = g_pPerfDataHead + ((PERF_DATA_BLOCK*)g_pPerfDataHead)->HeaderLength;
    DWORD dwNumberOfObjects = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->NumObjectTypes;
    BOOL fFoundObject = FALSE;

    for (DWORD i = 0; i < dwNumberOfObjects; i++)
    {
        if (dwObjectToFind == ((PERF_OBJECT_TYPE*)pObject)->ObjectNameTitleIndex)
        {
            fFoundObject = TRUE;
            break;
        }

        pObject += ((PERF_OBJECT_TYPE*)pObject)->TotalByteLength;
    }

    return (fFoundObject) ? (PERF_OBJECT_TYPE*)pObject : NULL;  
}

// Use the counter index to find the object in the performance data.
PERF_COUNTER_DEFINITION* GetCounter(PERF_OBJECT_TYPE* pObject, DWORD dwCounterToFind)
{
    PERF_COUNTER_DEFINITION* pCounter = (PERF_COUNTER_DEFINITION*)((LPBYTE)pObject + pObject->HeaderLength);
    DWORD dwNumberOfCounters = pObject->NumCounters;
    BOOL fFoundCounter = FALSE;

    for (DWORD i = 0; i < dwNumberOfCounters; i++)
    {
        if (pCounter->CounterNameTitleIndex == dwCounterToFind)
        {
            fFoundCounter = TRUE;
            break;
        }

        pCounter++;
    }

    return (fFoundCounter) ? pCounter : NULL;
}


// Returns a pointer to the beginning of the PERF_COUNTER_BLOCK. The location of the 
// of the counter data block depends on whether the object contains single instance
// counters or multiple instance counters (see PERF_OBJECT_TYPE.NumInstances).
PERF_COUNTER_BLOCK* GetCounterBlock(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName)
{
    PERF_COUNTER_BLOCK* pBlock = NULL;
    PERF_INSTANCE_DEFINITION* pInstance = NULL;

    // If there are no instances, the block follows the object and counter structures.
    if (0 == pObject->NumInstances || PERF_NO_INSTANCES == pObject->NumInstances) 
    {                                
        pBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pObject + pObject->DefinitionLength);
    }
    else if (pObject->NumInstances > 0 && pInstanceName)  // Find the instance. The block follows the instance
    {                                                     // structure and instance name.
        pInstance = GetObjectInstance(pObject, pInstanceName);
        if (pInstance)
        {
            pBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pInstance + pInstance->ByteLength);
        }
    }

    return pBlock;
}


// If the instance names are unique (there will never be more than one instance
// with the same name), then finding the same instance is not an issue. However, 
// if the instance names are not unique, there is no guarantee that the instance 
// whose counter value you are retrieving is the same instance from which you previously
// retrieved data. This function expects the instance name to be well formed. For 
// example, a process object could have four instances with each having svchost as its name.
// Since service hosts come and go, there is no way to determine if you are dealing with 
// the same instance. 
//
// The convention for specifying an instance is parentinstancename/instancename#nnn.
// If only instancename is specified, the first instance found that matches the name is used.
// Specify parentinstancename if the instance is the child of a parent instance.
PERF_INSTANCE_DEFINITION* GetObjectInstance(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName)
{
    PERF_INSTANCE_DEFINITION* pInstance = (PERF_INSTANCE_DEFINITION*)((LPBYTE)pObject + pObject->DefinitionLength);
    BOOL fSuccess = FALSE;
    WCHAR szName[MAX_FULL_INSTANCE_NAME_LEN + 1];
    PERF_COUNTER_BLOCK* pCounterBlock = NULL;
    DWORD dwSerialNo = GetSerialNo(pInstanceName);
    DWORD dwOccurrencesFound = 0;
    DWORD dwNameLen = 0;
    
    DWORD dwInputNameLen = (DWORD)wcslen(pInstanceName);

    for (LONG i = 0; i < pObject->NumInstances; i++)
    {
        GetFullInstanceName(pInstance, pObject->CodePage, szName);
        if ((dwNameLen = (DWORD)wcslen(szName)) <= dwInputNameLen)
        {   ////////////////////////////////////////////////////////////////////

            if (0 == _wcsnicmp(szName, pInstanceName, dwNameLen))  // The name matches
            {
                dwOccurrencesFound++;

                // If the input name does not specify an nth instance or
                // the nth instance has been found, return the instance.
                // It is 'dwSerialNo+1' because cmd#3 is the fourth occurrence.
                if (0 == dwSerialNo || dwOccurrencesFound == (dwSerialNo+1))
                {
                    return pInstance;
                }
            }
        }

        pCounterBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pInstance + pInstance->ByteLength);
        pInstance = (PERF_INSTANCE_DEFINITION*)((LPBYTE)pInstance + pInstance->ByteLength + pCounterBlock->ByteLength);
    }

    return NULL;
}


// Parses the instance name for the serial number. The convention is to use
// a serial number appended to the instance name to identify a specific
// instance when the instance names are not unique. For example, to specify
// the fourth instance of svchost, use svchost#3 (the first occurrence does
// not include a serial number).
DWORD GetSerialNo(LPWSTR pInstanceName)
{
    LPWSTR pSerialNo = NULL;
    DWORD dwLength = 0;
    DWORD value = 0;

    pSerialNo = wcschr(pInstanceName, '#');
    if (pSerialNo)
    {
        pSerialNo++;
        value = _wtoi(pSerialNo);
    }

    return value;
}


// Retrieve the full name of the instance. The full name of the instance includes
// the name of this instance and its parent instance, if this instance is a 
// child instance. The full name is in the form, "parent name/child name".
// For example, a thread instance is a child of a process instance. 
//
// Providers are encouraged to use Unicode strings for instance names. If 
// PERF_INSTANCE_DEFINITION.CodePage is zero, the name is in Unicode; otherwise,
// use the CodePage value to convert the string to Unicode.
BOOL GetFullInstanceName(PERF_INSTANCE_DEFINITION* pInstance, DWORD CodePage, WCHAR* pName)
{
    BOOL fSuccess = TRUE;
    PERF_INSTANCE_DEFINITION *pParentInstance = NULL;
    PERF_OBJECT_TYPE *pParentObject = NULL;
    DWORD dwLength = 0;
    WCHAR wszInstanceName[MAX_INSTANCE_NAME_LEN+1];
    WCHAR wszParentInstanceName[MAX_INSTANCE_NAME_LEN+1];

    if (CodePage == 0)  // Instance name is a Unicode string
    {
        // PERF_INSTANCE_DEFINITION->NameLength is in bytes, so convert to characters.
        dwLength = (MAX_INSTANCE_NAME_LEN < (pInstance->NameLength/2)) ? MAX_INSTANCE_NAME_LEN : pInstance->NameLength/2;
        StringCchCopyN(wszInstanceName, MAX_INSTANCE_NAME_LEN+1, (LPWSTR)(((LPBYTE)pInstance)+pInstance->NameOffset), dwLength);
        wszInstanceName[dwLength] = '\0';
    }
    else  // Convert the multi-byte instance name to Unicode
    {
        fSuccess = ConvertNameToUnicode(CodePage, 
            (LPCSTR)(((LPBYTE)pInstance)+pInstance->NameOffset),  // Points to string
            pInstance->NameLength,
            wszInstanceName);
    }

    if (pInstance->ParentObjectTitleIndex)
    {
        // Use the index to find the parent object. The pInstance->ParentObjectInstance
        // member tells you that the parent instance is the nth instance of the 
        // parent object.
        pParentObject = GetObject(pInstance->ParentObjectTitleIndex);
        pParentInstance = GetParentInstance(pParentObject, pInstance->ParentObjectInstance);

        if (CodePage == 0)  // Instance name is a Unicode string
        {
            dwLength = (MAX_INSTANCE_NAME_LEN < pParentInstance->NameLength/2) ? MAX_INSTANCE_NAME_LEN : pParentInstance->NameLength/2;
            StringCchCopyN(wszParentInstanceName, MAX_INSTANCE_NAME_LEN+1, (LPWSTR)(((LPBYTE)pParentInstance)+pParentInstance->NameOffset), dwLength);
            wszParentInstanceName[dwLength] = '\0';
        }
        else  // Convert the multi-byte instance name to Unicode
        {
            fSuccess = ConvertNameToUnicode(CodePage, 
                (LPCSTR)(((LPBYTE)pParentInstance)+pParentInstance->NameOffset),  //Points to string.
                pInstance->NameLength,
                wszParentInstanceName);
        }

        StringCchPrintf(pName, MAX_FULL_INSTANCE_NAME_LEN+1, L"%s/%s", wszParentInstanceName, wszInstanceName);
    }
    else
    {
        StringCchPrintf(pName, MAX_INSTANCE_NAME_LEN+1, L"%s", wszInstanceName);
    }

    return fSuccess;
}


// Converts a multi-byte string to a Unicode string. If the input string is longer than 
// MAX_INSTANCE_NAME_LEN, the input string is truncated.
BOOL ConvertNameToUnicode(UINT CodePage, LPCSTR pNameToConvert, DWORD dwNameToConvertLen, LPWSTR pConvertedName)
{
    BOOL fSuccess = FALSE;
    int CharsConverted = 0;
    DWORD dwLength = 0;

    // dwNameToConvertLen is in bytes, so convert MAX_INSTANCE_NAME_LEN to bytes.
    dwLength = (MAX_INSTANCE_NAME_LEN*sizeof(WCHAR) < (dwNameToConvertLen)) ? MAX_INSTANCE_NAME_LEN*sizeof(WCHAR) : dwNameToConvertLen;

    CharsConverted = MultiByteToWideChar((UINT)CodePage, 0, pNameToConvert, dwLength, pConvertedName, MAX_INSTANCE_NAME_LEN);
    if (CharsConverted)
    {
        pConvertedName[dwLength] = '\0';
        fSuccess = TRUE;
    }

    return fSuccess;
}


// Find the nth instance of an object.
PERF_INSTANCE_DEFINITION* GetParentInstance(PERF_OBJECT_TYPE* pObject, DWORD dwInstancePosition)
{
    LPBYTE pInstance = (LPBYTE)pObject + pObject->DefinitionLength;
    PERF_COUNTER_BLOCK* pCounter = NULL;

    for (DWORD i = 0; i < dwInstancePosition; i++)
    {
        pCounter = (PERF_COUNTER_BLOCK*)(pInstance + ((PERF_INSTANCE_DEFINITION*)pInstance)->ByteLength);
        pInstance += ((PERF_INSTANCE_DEFINITION*)pInstance)->ByteLength + pCounter->ByteLength;
    }

    return (PERF_INSTANCE_DEFINITION*)pInstance;
}


// Retrieve the raw counter value and any supporting data needed to calculate
// a displayable counter value. Use the counter type to determine the information
// needed to calculate the value.
BOOL GetValue(PERF_OBJECT_TYPE* pObject, 
    PERF_COUNTER_DEFINITION* pCounter, 
    PERF_COUNTER_BLOCK* pCounterDataBlock, 
    PRAW_DATA pRawData)
{
    PVOID pData = NULL;
    UNALIGNED ULONGLONG* pullData = NULL;
    PERF_COUNTER_DEFINITION* pBaseCounter = NULL;
    BOOL fSuccess = TRUE;

    //Point to the raw counter data.
    pData = (PVOID)((LPBYTE)pCounterDataBlock + pCounter->CounterOffset);

    //Now use the PERF_COUNTER_DEFINITION.CounterType value to figure out what
    //other information you need to calculate a displayable value.
    switch (pCounter->CounterType) {

    case PERF_COUNTER_COUNTER:
    case PERF_COUNTER_QUEUELEN_TYPE:
    case PERF_SAMPLE_COUNTER:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;
        if (PERF_COUNTER_COUNTER == pCounter->CounterType || PERF_SAMPLE_COUNTER == pCounter->CounterType)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    case PERF_OBJ_TIME_TIMER:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = pObject->PerfTime.QuadPart;
        break;

    case PERF_COUNTER_100NS_QUEUELEN_TYPE:
        pRawData->Data = *(UNALIGNED ULONGLONG *)pData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime100nSec.QuadPart;
        break;

    case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
        pRawData->Data = *(UNALIGNED ULONGLONG *)pData;
        pRawData->Time = pObject->PerfTime.QuadPart;
        break;

    case PERF_COUNTER_TIMER:
    case PERF_COUNTER_TIMER_INV:
    case PERF_COUNTER_BULK_COUNT:
    case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
        pullData = (UNALIGNED ULONGLONG *)pData;
        pRawData->Data = *pullData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;
        if (pCounter->CounterType == PERF_COUNTER_BULK_COUNT)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    case PERF_COUNTER_MULTI_TIMER:
    case PERF_COUNTER_MULTI_TIMER_INV:
        pullData = (UNALIGNED ULONGLONG *)pData;
        pRawData->Data = *pullData;
        pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;

        //These counter types have a second counter value that is adjacent to
        //this counter value in the counter data block. The value is needed for
        //the calculation.
        if ((pCounter->CounterType & PERF_MULTI_COUNTER) == PERF_MULTI_COUNTER)
        {
            ++pullData;
            pRawData->MultiCounterData = *(DWORD*)pullData;
        }
        break;

    //These counters do not use any time reference.
    case PERF_COUNTER_RAWCOUNT:
    case PERF_COUNTER_RAWCOUNT_HEX:
    case PERF_COUNTER_DELTA:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = 0;
        break;

    case PERF_COUNTER_LARGE_RAWCOUNT:
    case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
    case PERF_COUNTER_LARGE_DELTA:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pRawData->Time = 0;
        break;
    
    //These counters use the 100ns time base in their calculation.
    case PERF_100NSEC_TIMER:
    case PERF_100NSEC_TIMER_INV:
    case PERF_100NSEC_MULTI_TIMER:
    case PERF_100NSEC_MULTI_TIMER_INV:
        pullData = (UNALIGNED ULONGLONG*)pData;
        pRawData->Data = *pullData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime100nSec.QuadPart;

        //These counter types have a second counter value that is adjacent to
        //this counter value in the counter data block. The value is needed for
        //the calculation.
        if ((pCounter->CounterType & PERF_MULTI_COUNTER) == PERF_MULTI_COUNTER)
        {
            ++pullData;
            pRawData->MultiCounterData = *(DWORD*)pullData;
        }
        break;

    //These counters use two data points, this value and one from this counter's
    //base counter. The base counter should be the next counter in the object's 
    //list of counters.
    case PERF_SAMPLE_FRACTION:
    case PERF_RAW_FRACTION:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pBaseCounter = pCounter+1;  //Get base counter
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = (LONGLONG)(*(DWORD*)pData);
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_LARGE_RAW_FRACTION:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(LONGLONG*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_PRECISION_SYSTEM_TIMER:
    case PERF_PRECISION_100NS_TIMER:
    case PERF_PRECISION_OBJECT_TIMER:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(LONGLONG*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_AVERAGE_TIMER:
    case PERF_AVERAGE_BULK:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(DWORD*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }

        if (pCounter->CounterType == PERF_AVERAGE_TIMER)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    //These are base counters and are used in calculations for other counters.
    //This case should never be entered.
    case PERF_SAMPLE_BASE:
    case PERF_AVERAGE_BASE:
    case PERF_COUNTER_MULTI_BASE:
    case PERF_RAW_BASE:
    case PERF_LARGE_RAW_BASE:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;

    case PERF_ELAPSED_TIME:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pRawData->Time = pObject->PerfTime.QuadPart;
        pRawData->Frequency = pObject->PerfFreq.QuadPart;
        break;

    //These counters are currently not supported.
    case PERF_COUNTER_TEXT:
    case PERF_COUNTER_NODATA:
    case PERF_COUNTER_HISTOGRAM_TYPE:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;

    //Encountered an unidentified counter.
    default:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;
    }

    return fSuccess;
}

// Use the CounterType to determine how to calculate the displayable
// value. The case statement includes the formula used to calculate 
// the value.
BOOL DisplayCalculatedValue(RAW_DATA* pSample1, RAW_DATA* pSample2)
{
    BOOL fSuccess = TRUE;
    ULONGLONG numerator = 0;
    LONGLONG denominator = 0;
    double DisplayValue = 0;
    DWORD DisplayValue2 = 0;

    // If the counter type contains the PERF_DELTA_COUNTER flag, you need
    // two samples to calculate the value. 
    if (PERF_DELTA_COUNTER == (pSample1->CounterType & PERF_DELTA_COUNTER) &&
        NULL == pSample2)
    {
        fSuccess = FALSE;
        return fSuccess;
        
    }
    
    // Check for integer overflow or bad data from provider (the data from 
    // sample 2 must be greater than the data from sample 1).
    if (pSample2 != NULL && pSample1->Data > pSample2->Data)
    {                     
        // You would probably just drop the older sample and continue.                
        wprintf(L"Sample1 (%I64u) is larger than sample2 (%I64u).\n", pSample1->Data, pSample2->Data);
        fSuccess = FALSE;
        return fSuccess;
    }

    switch (pSample1->CounterType) 
    {
        case PERF_COUNTER_COUNTER:  //(N1 - N0)/((D1 - D0)/F)
        case PERF_SAMPLE_COUNTER:
        case PERF_COUNTER_BULK_COUNT:  
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue2 = (DWORD)(numerator/((double)denominator/pSample2->Frequency));
            wprintf(L"Display value is %u%s\n", DisplayValue2,
            (pSample1->CounterType == PERF_SAMPLE_COUNTER) ? L"." : L"/sec.");
            break;

        case PERF_COUNTER_QUEUELEN_TYPE:  //(N1 - N0)/(D1 - D0)
        case PERF_COUNTER_100NS_QUEUELEN_TYPE:  
        case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
        case PERF_COUNTER_LARGE_QUEUELEN_TYPE:  
        case PERF_AVERAGE_BULK:  //don't display
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)numerator/denominator;
            if (pSample1->CounterType != PERF_AVERAGE_BULK)
                wprintf(L"Display value is %f.\n", DisplayValue);
            break;

        case PERF_OBJ_TIME_TIMER:  // 100*(N1 - N0)/(D1 - D0)
        case PERF_COUNTER_TIMER:  
        case PERF_100NSEC_TIMER:
        case PERF_PRECISION_SYSTEM_TIMER: 
        case PERF_PRECISION_100NS_TIMER:
        case PERF_PRECISION_OBJECT_TIMER:
        case PERF_SAMPLE_FRACTION:  // 100*(N1 - N0)/(B1 - B0)
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)(100*numerator)/denominator;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_TIMER_INV:  // 100*(1- ((N1 - N0)/(D1 - D0)))
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(1 - ((double)numerator/denominator));
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_100NSEC_TIMER_INV:  // 100*(1- (N1 - N0)/(D1 - D0))
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(1 - (double)numerator/denominator);
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_MULTI_TIMER:  // 100*((N1 - N0)/((D1 - D0)/TB))/B1
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            denominator /= pSample2->Frequency;
            DisplayValue = 100*((double)numerator/denominator)/pSample2->MultiCounterData;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_100NSEC_MULTI_TIMER:  // 100*((N1 - N0)/(D1 - D0))/B1
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*((double)numerator/denominator)/pSample2->MultiCounterData;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_MULTI_TIMER_INV:  // 100*(B1- ((N1 - N0)/(D1 - D0)))
        case PERF_100NSEC_MULTI_TIMER_INV:
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(pSample2->MultiCounterData - ((double)numerator/denominator));
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_RAWCOUNT:  // N as decimal
        case PERF_COUNTER_LARGE_RAWCOUNT:
            wprintf(L"Display value is %I64u.\n", pSample1->Data);
            break;

        case PERF_COUNTER_RAWCOUNT_HEX:  // N as hexadecimal
        case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
            wprintf(L"Display value is %I64x.\n", pSample1->Data);
            break;

        case PERF_COUNTER_DELTA:  // N1 - N0
        case PERF_COUNTER_LARGE_DELTA:
            DisplayValue = (double)(pSample2->Data - pSample1->Data);
            wprintf(L"Display value is %I64u.\n", DisplayValue);
            break;

        case PERF_RAW_FRACTION:  // 100*N/B
        case PERF_LARGE_RAW_FRACTION:
            DisplayValue = (double)100*pSample1->Data/pSample1->Time;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_AVERAGE_TIMER:  // ((N1 - N0)/TB)/(B1 - B0)
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)numerator/pSample2->Frequency/denominator;
            wprintf(L"Display value is %f in seconds.\n", DisplayValue);
            break;

        case PERF_ELAPSED_TIME:  //(D0 - N0)/F
            DisplayValue = (double)(pSample1->Time - pSample1->Data)/pSample1->Frequency;
            wprintf(L"Display value is %f in seconds.\n", DisplayValue);
            break;

        default:
            wprintf(L"Counter type not found.\n");
            fSuccess = FALSE;
            break;
    }

cleanup:

    return fSuccess;
}



Не знаю, как запихнуть результат в листбокс .В функции DisplayCalculatedValue всё выводится через wprintf. Я ума не приложу , как это сделать .

Может Вы хоть как-то сможете помочь с этой задачей ? Пожалуйста , очень Вас прошу.
Re[13]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: Pavel Dvorkin Россия  
Дата: 10.05.14 13:57
Оценка:
Здравствуйте, NNN7, Вы писали:

NNN>Здравствуйте, Pavel Dvorkin. Можно к Вам обратиться ещё с вопросами ? разобрался с PDH функциями , но теперь нужно разобраться ещё и с функциями реестра .

NNN>Прочитал пример с msdn : http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178%28v=vs.85%29.aspx и для вывода http://msdn.microsoft.com/en-us/library/windows/desktop/aa371891%28v=vs.85%29.aspx . Это консольный вариант вывода значения счётчика , работает нормально, всё выводит .

NNN>Но как реализовать это в графическом варианте ? Чтобы вывело значение счётчика не в консоль , а в листбокс , например . Я всё пробую — никак не получается переделать программу.


Делать то же самое, что и там. Можно оформить как отдельную функцию, возвращающую int или DWORD или что там будет. После ее вызова вызывать sprintf или itoa и перевести в строку. Добавить строку в листбокс обычным образом.
With best regards
Pavel Dvorkin
Re[14]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 14:17
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, NNN7, Вы писали:


NNN>>Здравствуйте, Pavel Dvorkin. Можно к Вам обратиться ещё с вопросами ? разобрался с PDH функциями , но теперь нужно разобраться ещё и с функциями реестра .

NNN>>Прочитал пример с msdn : http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178%28v=vs.85%29.aspx и для вывода http://msdn.microsoft.com/en-us/library/windows/desktop/aa371891%28v=vs.85%29.aspx . Это консольный вариант вывода значения счётчика , работает нормально, всё выводит .

NNN>>Но как реализовать это в графическом варианте ? Чтобы вывело значение счётчика не в консоль , а в листбокс , например . Я всё пробую — никак не получается переделать программу.


PD>Делать то же самое, что и там. Можно оформить как отдельную функцию, возвращающую int или DWORD или что там будет. После ее вызова вызывать sprintf или itoa и перевести в строку. Добавить строку в листбокс обычным образом.


Я вот так пробую занести в ListBox :



#include <Windows.h>
#include "resource.h"
#include <string.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <strsafe.h>
using namespace std;
#pragma comment(lib, "pdh.lib")

// Contains the elements required to calculate a counter value.
typedef struct _rawdata
{
    DWORD CounterType;
    ULONGLONG Data;          // Raw counter data
    LONGLONG Time;           // Is a time value or a base value
    DWORD MultiCounterData;  // Second raw counter value for multi-valued counters
    LONGLONG Frequency;
}RAW_DATA, *PRAW_DATA;

#define INIT_OBJECT_BUFFER_SIZE 48928   // Initial buffer size to use when querying specific objects.
#define INIT_GLOBAL_BUFFER_SIZE 122880  // Initial buffer size to use when using "Global" to query all objects.
#define BUFFER_INCREMENT 16384          // Increment buffer size in 16K chunks.
#define MAX_INSTANCE_NAME_LEN      255  // Max length of an instance name.
#define MAX_FULL_INSTANCE_NAME_LEN 511  // Form is parentinstancename/instancename#nnn.
//прототипы:
LPBYTE GetPerformanceData(LPWSTR pwszSource, DWORD dwInitialBufferSize);
BOOL GetCounterValues(DWORD dwObjectIndex, DWORD dwCounterIndex, LPWSTR pInstanceName, RAW_DATA* pRawData);
BOOL GetValue(PERF_OBJECT_TYPE* pObject, PERF_COUNTER_DEFINITION* pCounter, PERF_COUNTER_BLOCK* pCounterDataBlock, PRAW_DATA pRawData);
PERF_COUNTER_BLOCK* GetCounterBlock(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName);
PERF_COUNTER_DEFINITION* GetCounter(PERF_OBJECT_TYPE* pObject, DWORD dwCounterToFind);
PERF_OBJECT_TYPE* GetObject(DWORD dwObjectToFind);
PERF_INSTANCE_DEFINITION* GetObjectInstance(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName);
DWORD GetSerialNo(LPWSTR pInstanceName);
BOOL GetFullInstanceName(PERF_INSTANCE_DEFINITION* pInstance, DWORD CodePage, WCHAR* pName);
BOOL ConvertNameToUnicode(UINT CodePage, LPCSTR pNameToConvert, DWORD dwNameToConvertLen, LPWSTR pConvertedName);
PERF_INSTANCE_DEFINITION* GetParentInstance(PERF_OBJECT_TYPE* pObject, DWORD dwInstancePosition);
BOOL DisplayCalculatedValue(RAW_DATA* pSample1, RAW_DATA* pSample2);
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM  );
//Global variables
LPBYTE g_pPerfDataHead = NULL;   // Head of the performance data.
HWND CB,LB,LB2,LB3, list;
 wchar_t str [51];  //буфер
wchar_t buf[2048];


 //главная функция 
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow)
{
 //создание диалогового окна главным окном 
int db;
db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc);
 }
 

BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar )
{
    RAW_DATA Sample1;
    RAW_DATA Sample2;
    BOOL fSuccess = FALSE;
    LB=GetDlgItem(hwnd,LIST);

  switch (uMsg)
 {
case WM_COMMAND:
               //Если нажата кнопка Quit, тозакрываем окно
               if (LOWORD(wpar)==QUIT)
                {  EndDialog(hwnd,NULL);
                   return TRUE;
                }
    break;
case WM_INITDIALOG:

//SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);

    LB=GetDlgItem(hwnd,LIST);
    RAW_DATA Sample1;
    RAW_DATA Sample2;
    BOOL fSuccess = FALSE;

    // Retrieve counter data for the Processor object.
    g_pPerfDataHead = (LPBYTE)GetPerformanceData(L"238", INIT_OBJECT_BUFFER_SIZE);
    if (NULL == g_pPerfDataHead)
    {    MessageBox(hwnd,(LPCWSTR)"GetPerformanceData failed",(LPCWSTR)"",MB_OK);
        goto cleanup;
    }

    // Then, sample the "% Processor Time" counter for instance "0" of the Processor object.
    fSuccess = GetCounterValues(238, 6, L"0", &Sample1);
    if (FALSE == fSuccess)
    {   MessageBox(hwnd,(LPCWSTR)"GetCounterValues failed",(LPCWSTR)"",MB_OK);
        goto cleanup;
    }

    // Display five data points for the counter.
    for (DWORD i = 0; i < 5; i++)
    {
        Sleep(1000);  // Wait one second before taking the next sample

        // Retrieve the object data again and get the next sample.
        g_pPerfDataHead = (LPBYTE)GetPerformanceData(L"238", INIT_OBJECT_BUFFER_SIZE);
        if (NULL == g_pPerfDataHead)
        {   MessageBox(hwnd,(LPCWSTR)"GetPerformanceData in loop failed",(LPCWSTR)"",MB_OK);
            goto cleanup;
        }

        fSuccess = GetCounterValues(238, 6, L"0", &Sample2);
        if (FALSE == fSuccess)
        {   MessageBox(hwnd,(LPCWSTR)"GetCounterValues failed",(LPCWSTR)"",MB_OK);
            goto cleanup;
        }

        // Calculate the value based on the two samples. For counter
        // types that do not use two samples, set the second parameter
        // to NULL.
        fSuccess = DisplayCalculatedValue(&Sample1, &Sample2);
        if (FALSE == fSuccess)
        {    MessageBox(hwnd,(LPCWSTR)"DisplayCalculatedValue failed",(LPCWSTR)"",MB_OK);
            goto cleanup;
        }

        // Sample2 becomes Sample1 for the next iteration.
        memcpy(&Sample1, &Sample2, sizeof(RAW_DATA));
        
        SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf);

    }

    


cleanup:

    if (g_pPerfDataHead)
        free(g_pPerfDataHead);


        return 0;
    }
  }

//Функции :
// Retrieve a buffer that contains the specified performance data.
// The pwszSource parameter determines the data that GetRegistryBuffer returns.
//
// Typically, when calling RegQueryValueEx, you can specify zero for the size of the buffer
// and the RegQueryValueEx will set your size variable to the required buffer size. However, 
// if the source is "Global" or one or more object index values, you will need to increment
// the buffer size in a loop until RegQueryValueEx does not return ERROR_MORE_DATA. 
LPBYTE GetPerformanceData(LPWSTR pwszSource, DWORD dwInitialBufferSize)
{
    LPBYTE pBuffer = NULL;
    DWORD dwBufferSize = 0;        //Size of buffer, used to increment buffer size
    DWORD dwSize = 0;              //Size of buffer, used when calling RegQueryValueEx
    LPBYTE pTemp = NULL;           //Temp variable for realloc() in case it fails
    LONG status = ERROR_SUCCESS; 

    dwBufferSize = dwSize = dwInitialBufferSize;

    pBuffer = (LPBYTE)malloc(dwBufferSize);
    if (pBuffer)
    {
        while (ERROR_MORE_DATA == (status = RegQueryValueEx(HKEY_PERFORMANCE_DATA, pwszSource, NULL, NULL, pBuffer, &dwSize)))
        {
            //Contents of dwSize is unpredictable if RegQueryValueEx fails, which is why
            //you need to increment dwBufferSize and use it to set dwSize.
            dwBufferSize += BUFFER_INCREMENT;

            pTemp = (LPBYTE)realloc(pBuffer, dwBufferSize);
            if (pTemp)
            {
                pBuffer = pTemp;
                dwSize = dwBufferSize;
            }
            else
            {
                free(pBuffer);
                pBuffer = NULL;
                goto cleanup;
            }
        }

        if (ERROR_SUCCESS != status)
        {
           
            free(pBuffer);
            pBuffer = NULL;
        }
    }
    

cleanup:

    RegCloseKey(HKEY_PERFORMANCE_DATA);

    return pBuffer;
}


// Use the object index to find the object in the performance data. Then, use the
// counter index to find the counter definition. The definition contains the offset
// to the counter data in the counter block. The location of the counter block 
// depends on whether the counter is a single instance counter or multiple instance counter.
// After finding the counter block, retrieve the counter data.
BOOL GetCounterValues(DWORD dwObjectIndex, DWORD dwCounterIndex, LPWSTR pInstanceName, RAW_DATA* pRawData)
{
    PERF_OBJECT_TYPE* pObject = NULL;
    PERF_COUNTER_DEFINITION* pCounter = NULL;
    PERF_COUNTER_BLOCK* pCounterDataBlock = NULL;
    BOOL fSuccess = FALSE;

    pObject = GetObject(dwObjectIndex);
    if (NULL == pObject)
    {
       
        goto cleanup;
    }

    pCounter = GetCounter(pObject, dwCounterIndex);
    if (NULL == pCounter)
    {
       
        goto cleanup;
    }

    // Retrieve a pointer to the beginning of the counter data block. The counter data
    // block contains all the counter data for the object.
    pCounterDataBlock = GetCounterBlock(pObject, pInstanceName);
    if (NULL == pCounterDataBlock)
    {
       
        goto cleanup;
    }

    ZeroMemory(pRawData, sizeof(RAW_DATA));
    pRawData->CounterType = pCounter->CounterType;
    fSuccess = GetValue(pObject, pCounter, pCounterDataBlock, pRawData);

cleanup:

    return fSuccess;
}


// Use the object index to find the object in the performance data.
PERF_OBJECT_TYPE* GetObject(DWORD dwObjectToFind)
{
    LPBYTE pObject = g_pPerfDataHead + ((PERF_DATA_BLOCK*)g_pPerfDataHead)->HeaderLength;
    DWORD dwNumberOfObjects = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->NumObjectTypes;
    BOOL fFoundObject = FALSE;

    for (DWORD i = 0; i < dwNumberOfObjects; i++)
    {
        if (dwObjectToFind == ((PERF_OBJECT_TYPE*)pObject)->ObjectNameTitleIndex)
        {
            fFoundObject = TRUE;
            break;
        }

        pObject += ((PERF_OBJECT_TYPE*)pObject)->TotalByteLength;
    }

    return (fFoundObject) ? (PERF_OBJECT_TYPE*)pObject : NULL;  
}

// Use the counter index to find the object in the performance data.
PERF_COUNTER_DEFINITION* GetCounter(PERF_OBJECT_TYPE* pObject, DWORD dwCounterToFind)
{
    PERF_COUNTER_DEFINITION* pCounter = (PERF_COUNTER_DEFINITION*)((LPBYTE)pObject + pObject->HeaderLength);
    DWORD dwNumberOfCounters = pObject->NumCounters;
    BOOL fFoundCounter = FALSE;

    for (DWORD i = 0; i < dwNumberOfCounters; i++)
    {
        if (pCounter->CounterNameTitleIndex == dwCounterToFind)
        {
            fFoundCounter = TRUE;
            break;
        }

        pCounter++;
    }

    return (fFoundCounter) ? pCounter : NULL;
}


// Returns a pointer to the beginning of the PERF_COUNTER_BLOCK. The location of the 
// of the counter data block depends on whether the object contains single instance
// counters or multiple instance counters (see PERF_OBJECT_TYPE.NumInstances).
PERF_COUNTER_BLOCK* GetCounterBlock(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName)
{
    PERF_COUNTER_BLOCK* pBlock = NULL;
    PERF_INSTANCE_DEFINITION* pInstance = NULL;

    // If there are no instances, the block follows the object and counter structures.
    if (0 == pObject->NumInstances || PERF_NO_INSTANCES == pObject->NumInstances) 
    {                                
        pBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pObject + pObject->DefinitionLength);
    }
    else if (pObject->NumInstances > 0 && pInstanceName)  // Find the instance. The block follows the instance
    {                                                     // structure and instance name.
        pInstance = GetObjectInstance(pObject, pInstanceName);
        if (pInstance)
        {
            pBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pInstance + pInstance->ByteLength);
        }
    }

    return pBlock;
}


// If the instance names are unique (there will never be more than one instance
// with the same name), then finding the same instance is not an issue. However, 
// if the instance names are not unique, there is no guarantee that the instance 
// whose counter value you are retrieving is the same instance from which you previously
// retrieved data. This function expects the instance name to be well formed. For 
// example, a process object could have four instances with each having svchost as its name.
// Since service hosts come and go, there is no way to determine if you are dealing with 
// the same instance. 
//
// The convention for specifying an instance is parentinstancename/instancename#nnn.
// If only instancename is specified, the first instance found that matches the name is used.
// Specify parentinstancename if the instance is the child of a parent instance.
PERF_INSTANCE_DEFINITION* GetObjectInstance(PERF_OBJECT_TYPE* pObject, LPWSTR pInstanceName)
{
    PERF_INSTANCE_DEFINITION* pInstance = (PERF_INSTANCE_DEFINITION*)((LPBYTE)pObject + pObject->DefinitionLength);
    BOOL fSuccess = FALSE;
    WCHAR szName[MAX_FULL_INSTANCE_NAME_LEN + 1];
    PERF_COUNTER_BLOCK* pCounterBlock = NULL;
    DWORD dwSerialNo = GetSerialNo(pInstanceName);
    DWORD dwOccurrencesFound = 0;
    DWORD dwNameLen = 0;
    DWORD dwInputNameLen = (DWORD)wcslen(pInstanceName);

    for (LONG i = 0; i < pObject->NumInstances; i++)
    {
        GetFullInstanceName(pInstance, pObject->CodePage, szName);
        if ((dwNameLen = (DWORD)wcslen(szName)) <= dwInputNameLen)
        {
            if (0 == _wcsnicmp(szName, pInstanceName, dwNameLen))  // The name matches
            {
                dwOccurrencesFound++;

                // If the input name does not specify an nth instance or
                // the nth instance has been found, return the instance.
                // It is 'dwSerialNo+1' because cmd#3 is the fourth occurrence.
                if (0 == dwSerialNo || dwOccurrencesFound == (dwSerialNo+1))
                {
                    return pInstance;
                }
            }
        }

        pCounterBlock = (PERF_COUNTER_BLOCK*)((LPBYTE)pInstance + pInstance->ByteLength);
        pInstance = (PERF_INSTANCE_DEFINITION*)((LPBYTE)pInstance + pInstance->ByteLength + pCounterBlock->ByteLength);
    }

    return NULL;
}


// Parses the instance name for the serial number. The convention is to use
// a serial number appended to the instance name to identify a specific
// instance when the instance names are not unique. For example, to specify
// the fourth instance of svchost, use svchost#3 (the first occurrence does
// not include a serial number).
DWORD GetSerialNo(LPWSTR pInstanceName)
{
    LPWSTR pSerialNo = NULL;
    DWORD dwLength = 0;
    DWORD value = 0;

    pSerialNo = wcschr(pInstanceName, '#');
    if (pSerialNo)
    {
        pSerialNo++;
        value = _wtoi(pSerialNo);
    }

    return value;
}


// Retrieve the full name of the instance. The full name of the instance includes
// the name of this instance and its parent instance, if this instance is a 
// child instance. The full name is in the form, "parent name/child name".
// For example, a thread instance is a child of a process instance. 
//
// Providers are encouraged to use Unicode strings for instance names. If 
// PERF_INSTANCE_DEFINITION.CodePage is zero, the name is in Unicode; otherwise,
// use the CodePage value to convert the string to Unicode.
BOOL GetFullInstanceName(PERF_INSTANCE_DEFINITION* pInstance, DWORD CodePage, WCHAR* pName)
{
    BOOL fSuccess = TRUE;
    PERF_INSTANCE_DEFINITION *pParentInstance = NULL;
    PERF_OBJECT_TYPE *pParentObject = NULL;
    DWORD dwLength = 0;
    WCHAR wszInstanceName[MAX_INSTANCE_NAME_LEN+1];
    WCHAR wszParentInstanceName[MAX_INSTANCE_NAME_LEN+1];

    if (CodePage == 0)  // Instance name is a Unicode string
    {
        // PERF_INSTANCE_DEFINITION->NameLength is in bytes, so convert to characters.
        dwLength = (MAX_INSTANCE_NAME_LEN < (pInstance->NameLength/2)) ? MAX_INSTANCE_NAME_LEN : pInstance->NameLength/2;
        StringCchCopyN(wszInstanceName, MAX_INSTANCE_NAME_LEN+1, (LPWSTR)(((LPBYTE)pInstance)+pInstance->NameOffset), dwLength);
        wszInstanceName[dwLength] = '\0';
    }
    else  // Convert the multi-byte instance name to Unicode
    {
        fSuccess = ConvertNameToUnicode(CodePage, 
            (LPCSTR)(((LPBYTE)pInstance)+pInstance->NameOffset),  // Points to string
            pInstance->NameLength,
            wszInstanceName);

        if (FALSE == fSuccess)
        {
           
            goto cleanup;
        }
    }

    if (pInstance->ParentObjectTitleIndex)
    {
        // Use the index to find the parent object. The pInstance->ParentObjectInstance
        // member tells you that the parent instance is the nth instance of the 
        // parent object.
        pParentObject = GetObject(pInstance->ParentObjectTitleIndex);
        pParentInstance = GetParentInstance(pParentObject, pInstance->ParentObjectInstance);

        if (CodePage == 0)  // Instance name is a Unicode string
        {
            dwLength = (MAX_INSTANCE_NAME_LEN < pParentInstance->NameLength/2) ? MAX_INSTANCE_NAME_LEN : pParentInstance->NameLength/2;
            StringCchCopyN(wszParentInstanceName, MAX_INSTANCE_NAME_LEN+1, (LPWSTR)(((LPBYTE)pParentInstance)+pParentInstance->NameOffset), dwLength);
            wszParentInstanceName[dwLength] = '\0';
        }
        else  // Convert the multi-byte instance name to Unicode
        {
            fSuccess = ConvertNameToUnicode(CodePage, 
                (LPCSTR)(((LPBYTE)pParentInstance)+pParentInstance->NameOffset),  //Points to string.
                pInstance->NameLength,
                wszParentInstanceName);

            if (FALSE == fSuccess)
            {
                
                goto cleanup;
            }
        }

        StringCchPrintf(pName, MAX_FULL_INSTANCE_NAME_LEN+1, L"%s/%s", wszParentInstanceName, wszInstanceName);
    }
    else
    {
        StringCchPrintf(pName, MAX_INSTANCE_NAME_LEN+1, L"%s", wszInstanceName);
    }

cleanup:

    return fSuccess;
}


// Converts a multi-byte string to a Unicode string. If the input string is longer than 
// MAX_INSTANCE_NAME_LEN, the input string is truncated.
BOOL ConvertNameToUnicode(UINT CodePage, LPCSTR pNameToConvert, DWORD dwNameToConvertLen, LPWSTR pConvertedName)
{
    BOOL fSuccess = FALSE;
    int CharsConverted = 0;
    DWORD dwLength = 0;

    // dwNameToConvertLen is in bytes, so convert MAX_INSTANCE_NAME_LEN to bytes.
    dwLength = (MAX_INSTANCE_NAME_LEN*sizeof(WCHAR) < (dwNameToConvertLen)) ? MAX_INSTANCE_NAME_LEN*sizeof(WCHAR) : dwNameToConvertLen;

    CharsConverted = MultiByteToWideChar((UINT)CodePage, 0, pNameToConvert, dwLength, pConvertedName, MAX_INSTANCE_NAME_LEN);
    if (CharsConverted)
    {
        pConvertedName[dwLength] = '\0';
        fSuccess = TRUE;
    }

    return fSuccess;
}


// Find the nth instance of an object.
PERF_INSTANCE_DEFINITION* GetParentInstance(PERF_OBJECT_TYPE* pObject, DWORD dwInstancePosition)
{
    LPBYTE pInstance = (LPBYTE)pObject + pObject->DefinitionLength;
    PERF_COUNTER_BLOCK* pCounter = NULL;

    for (DWORD i = 0; i < dwInstancePosition; i++)
    {
        pCounter = (PERF_COUNTER_BLOCK*)(pInstance + ((PERF_INSTANCE_DEFINITION*)pInstance)->ByteLength);
        pInstance += ((PERF_INSTANCE_DEFINITION*)pInstance)->ByteLength + pCounter->ByteLength;
    }

    return (PERF_INSTANCE_DEFINITION*)pInstance;
}


// Retrieve the raw counter value and any supporting data needed to calculate
// a displayable counter value. Use the counter type to determine the information
// needed to calculate the value.
BOOL GetValue(PERF_OBJECT_TYPE* pObject, 
    PERF_COUNTER_DEFINITION* pCounter, 
    PERF_COUNTER_BLOCK* pCounterDataBlock, 
    PRAW_DATA pRawData)
{
    PVOID pData = NULL;
    UNALIGNED ULONGLONG* pullData = NULL;
    PERF_COUNTER_DEFINITION* pBaseCounter = NULL;
    BOOL fSuccess = TRUE;

    //Point to the raw counter data.
    pData = (PVOID)((LPBYTE)pCounterDataBlock + pCounter->CounterOffset);

    //Now use the PERF_COUNTER_DEFINITION.CounterType value to figure out what
    //other information you need to calculate a displayable value.
    switch (pCounter->CounterType) {

    case PERF_COUNTER_COUNTER:
    case PERF_COUNTER_QUEUELEN_TYPE:
    case PERF_SAMPLE_COUNTER:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;
        if (PERF_COUNTER_COUNTER == pCounter->CounterType || PERF_SAMPLE_COUNTER == pCounter->CounterType)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    case PERF_OBJ_TIME_TIMER:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = pObject->PerfTime.QuadPart;
        break;

    case PERF_COUNTER_100NS_QUEUELEN_TYPE:
        pRawData->Data = *(UNALIGNED ULONGLONG *)pData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime100nSec.QuadPart;
        break;

    case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
        pRawData->Data = *(UNALIGNED ULONGLONG *)pData;
        pRawData->Time = pObject->PerfTime.QuadPart;
        break;

    case PERF_COUNTER_TIMER:
    case PERF_COUNTER_TIMER_INV:
    case PERF_COUNTER_BULK_COUNT:
    case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
        pullData = (UNALIGNED ULONGLONG *)pData;
        pRawData->Data = *pullData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;
        if (pCounter->CounterType == PERF_COUNTER_BULK_COUNT)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    case PERF_COUNTER_MULTI_TIMER:
    case PERF_COUNTER_MULTI_TIMER_INV:
        pullData = (UNALIGNED ULONGLONG *)pData;
        pRawData->Data = *pullData;
        pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime.QuadPart;

        //These counter types have a second counter value that is adjacent to
        //this counter value in the counter data block. The value is needed for
        //the calculation.
        if ((pCounter->CounterType & PERF_MULTI_COUNTER) == PERF_MULTI_COUNTER)
        {
            ++pullData;
            pRawData->MultiCounterData = *(DWORD*)pullData;
        }
        break;

    //These counters do not use any time reference.
    case PERF_COUNTER_RAWCOUNT:
    case PERF_COUNTER_RAWCOUNT_HEX:
    case PERF_COUNTER_DELTA:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pRawData->Time = 0;
        break;

    case PERF_COUNTER_LARGE_RAWCOUNT:
    case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
    case PERF_COUNTER_LARGE_DELTA:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pRawData->Time = 0;
        break;
    
    //These counters use the 100ns time base in their calculation.
    case PERF_100NSEC_TIMER:
    case PERF_100NSEC_TIMER_INV:
    case PERF_100NSEC_MULTI_TIMER:
    case PERF_100NSEC_MULTI_TIMER_INV:
        pullData = (UNALIGNED ULONGLONG*)pData;
        pRawData->Data = *pullData;
        pRawData->Time = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfTime100nSec.QuadPart;

        //These counter types have a second counter value that is adjacent to
        //this counter value in the counter data block. The value is needed for
        //the calculation.
        if ((pCounter->CounterType & PERF_MULTI_COUNTER) == PERF_MULTI_COUNTER)
        {
            ++pullData;
            pRawData->MultiCounterData = *(DWORD*)pullData;
        }
        break;

    //These counters use two data points, this value and one from this counter's
    //base counter. The base counter should be the next counter in the object's 
    //list of counters.
    case PERF_SAMPLE_FRACTION:
    case PERF_RAW_FRACTION:
        pRawData->Data = (ULONGLONG)(*(DWORD*)pData);
        pBaseCounter = pCounter+1;  //Get base counter
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = (LONGLONG)(*(DWORD*)pData);
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_LARGE_RAW_FRACTION:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(LONGLONG*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_PRECISION_SYSTEM_TIMER:
    case PERF_PRECISION_100NS_TIMER:
    case PERF_PRECISION_OBJECT_TIMER:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(LONGLONG*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }
        break;

    case PERF_AVERAGE_TIMER:
    case PERF_AVERAGE_BULK:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pBaseCounter = pCounter+1;
        if ((pBaseCounter->CounterType & PERF_COUNTER_BASE) == PERF_COUNTER_BASE)
        {
            pData = (PVOID)((LPBYTE)pCounterDataBlock + pBaseCounter->CounterOffset);
            pRawData->Time = *(DWORD*)pData;
        }
        else
        {
            fSuccess = FALSE;
        }

        if (pCounter->CounterType == PERF_AVERAGE_TIMER)
        {
            pRawData->Frequency = ((PERF_DATA_BLOCK*)g_pPerfDataHead)->PerfFreq.QuadPart;
        }
        break;

    //These are base counters and are used in calculations for other counters.
    //This case should never be entered.
    case PERF_SAMPLE_BASE:
    case PERF_AVERAGE_BASE:
    case PERF_COUNTER_MULTI_BASE:
    case PERF_RAW_BASE:
    case PERF_LARGE_RAW_BASE:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;

    case PERF_ELAPSED_TIME:
        pRawData->Data = *(UNALIGNED ULONGLONG*)pData;
        pRawData->Time = pObject->PerfTime.QuadPart;
        pRawData->Frequency = pObject->PerfFreq.QuadPart;
        break;

    //These counters are currently not supported.
    case PERF_COUNTER_TEXT:
    case PERF_COUNTER_NODATA:
    case PERF_COUNTER_HISTOGRAM_TYPE:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;

    //Encountered an unidentified counter.
    default:
        pRawData->Data = 0;
        pRawData->Time = 0;
        fSuccess = FALSE;
        break;
    }

    return fSuccess;
}

// Use the CounterType to determine how to calculate the displayable
// value. The case statement includes the formula used to calculate 
// the value.
BOOL DisplayCalculatedValue(RAW_DATA* pSample1, RAW_DATA* pSample2)
{
    BOOL fSuccess = TRUE;
    ULONGLONG numerator = 0;
    LONGLONG denominator = 0;
    double DisplayValue = 0;
    DWORD DisplayValue2 = 0;
    

    // If the counter type contains the PERF_DELTA_COUNTER flag, you need
    // two samples to calculate the value. 
    if (PERF_DELTA_COUNTER == (pSample1->CounterType & PERF_DELTA_COUNTER) &&
        NULL == pSample2)
    {
        wprintf(L"The counter type requires two samples but only one sample was passed.\n");
        fSuccess = FALSE;
        goto cleanup;
    }
    
    // Check for integer overflow or bad data from provider (the data from 
    // sample 2 must be greater than the data from sample 1).
    if (pSample2 != NULL && pSample1->Data > pSample2->Data)
    {                     
        // You would probably just drop the older sample and continue.                
        swprintf(buf, 2048, L"%I64u", pSample1->Data);
        fSuccess =TRUE;
        goto cleanup;
    }

    switch (pSample1->CounterType) 
    {
        case PERF_COUNTER_COUNTER:  //(N1 - N0)/((D1 - D0)/F)
        case PERF_SAMPLE_COUNTER:
        case PERF_COUNTER_BULK_COUNT:  
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue2 = (DWORD)(numerator/((double)denominator/pSample2->Frequency));
           
            wprintf(L"Display value is %u%s\n", DisplayValue2,
            (pSample1->CounterType == PERF_SAMPLE_COUNTER) ? L"." : L"/sec.");
            break;

        case PERF_COUNTER_QUEUELEN_TYPE:  //(N1 - N0)/(D1 - D0)
        case PERF_COUNTER_100NS_QUEUELEN_TYPE:  
        case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
        case PERF_COUNTER_LARGE_QUEUELEN_TYPE:  
        case PERF_AVERAGE_BULK:  //don't display
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)numerator/denominator;
            if (pSample1->CounterType != PERF_AVERAGE_BULK)
                wprintf(L"Display value is %f.\n", DisplayValue);
            break;

        case PERF_OBJ_TIME_TIMER:  // 100*(N1 - N0)/(D1 - D0)
        case PERF_COUNTER_TIMER:  
        case PERF_100NSEC_TIMER:
        case PERF_PRECISION_SYSTEM_TIMER: 
        case PERF_PRECISION_100NS_TIMER:
        case PERF_PRECISION_OBJECT_TIMER:
        case PERF_SAMPLE_FRACTION:  // 100*(N1 - N0)/(B1 - B0)
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)(100*numerator)/denominator;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_TIMER_INV:  // 100*(1- ((N1 - N0)/(D1 - D0)))
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(1 - ((double)numerator/denominator));
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_100NSEC_TIMER_INV:  // 100*(1- (N1 - N0)/(D1 - D0))
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(1 - (double)numerator/denominator);
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_MULTI_TIMER:  // 100*((N1 - N0)/((D1 - D0)/TB))/B1
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            denominator /= pSample2->Frequency;
            DisplayValue = 100*((double)numerator/denominator)/pSample2->MultiCounterData;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_100NSEC_MULTI_TIMER:  // 100*((N1 - N0)/(D1 - D0))/B1
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*((double)numerator/denominator)/pSample2->MultiCounterData;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_MULTI_TIMER_INV:  // 100*(B1- ((N1 - N0)/(D1 - D0)))
        case PERF_100NSEC_MULTI_TIMER_INV:
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = 100*(pSample2->MultiCounterData - ((double)numerator/denominator));
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_COUNTER_RAWCOUNT:  // N as decimal
        case PERF_COUNTER_LARGE_RAWCOUNT:
            wprintf(L"Display value is %I64u.\n", pSample1->Data);
            break;

        case PERF_COUNTER_RAWCOUNT_HEX:  // N as hexadecimal
        case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
            wprintf(L"Display value is %I64x.\n", pSample1->Data);
            break;

        case PERF_COUNTER_DELTA:  // N1 - N0
        case PERF_COUNTER_LARGE_DELTA:
            DisplayValue = (double)(pSample2->Data - pSample1->Data);
            wprintf(L"Display value is %I64u.\n", DisplayValue);
            break;

        case PERF_RAW_FRACTION:  // 100*N/B
        case PERF_LARGE_RAW_FRACTION:
            DisplayValue = (double)100*pSample1->Data/pSample1->Time;
            wprintf(L"Display value is %f%%.\n", DisplayValue);
            break;

        case PERF_AVERAGE_TIMER:  // ((N1 - N0)/TB)/(B1 - B0)
            numerator = pSample2->Data - pSample1->Data;
            denominator = pSample2->Time - pSample1->Time;
            DisplayValue = (double)numerator/pSample2->Frequency/denominator;
            wprintf(L"Display value is %f in seconds.\n", DisplayValue);
            break;

        case PERF_ELAPSED_TIME:  //(D0 - N0)/F
            DisplayValue = (double)(pSample1->Time - pSample1->Data)/pSample1->Frequency;
            wprintf(L"Display value is %f in seconds.\n", DisplayValue);
            break;

        default:
            wprintf(L"Counter type not found.\n");
            fSuccess = FALSE;
            break;
    }

cleanup:

    return fSuccess;
}



Но всё безуспешно . Не заносится . Посмотрите , пожалуйста , что не так может быть ? Сил уже нету с этими счётчиками бороться
Re[8]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 15:52
Оценка:
Здравствуйте, Pavel Dvorkin . Вот пытался ещё вот так преобразовать :


if (pSample2 != NULL && pSample1->Data > pSample2->Data)
    {                    
        // You would probably just drop the older sample and continue.   
         swprintf(buf, 2048, L"%I64u", __int64(pSample2->Data - pSample1->Data)); // дельта
         fSuccess = TRUE;
        goto cleanup;
    }
Re[14]: Непонятный ключ HKEY_PERFORMANCE_DATA
От: NNN7 Украина  
Дата: 10.05.14 20:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, NNN7, Вы писали:


NNN>>Здравствуйте, Pavel Dvorkin. Можно к Вам обратиться ещё с вопросами ? разобрался с PDH функциями , но теперь нужно разобраться ещё и с функциями реестра .

NNN>>Прочитал пример с msdn : http://msdn.microsoft.com/en-us/library/windows/desktop/aa373178%28v=vs.85%29.aspx и для вывода http://msdn.microsoft.com/en-us/library/windows/desktop/aa371891%28v=vs.85%29.aspx . Это консольный вариант вывода значения счётчика , работает нормально, всё выводит .

NNN>>Но как реализовать это в графическом варианте ? Чтобы вывело значение счётчика не в консоль , а в листбокс , например . Я всё пробую — никак не получается переделать программу.


PD>Делать то же самое, что и там. Можно оформить как отдельную функцию, возвращающую int или DWORD или что там будет. После ее вызова вызывать sprintf или itoa и перевести в строку. Добавить строку в листбокс обычным образом.


Всё, вывести у меня получилось . Только проблема с отображением листбокса и кнопки . Почему они дублируются ? p.s. работает только одна кнопка
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.