| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|||||||
| Visual C++ Programming Ask questions about Windows programming with Visual C++ and help others by answering their questions. |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Trying to Use pdh.h
I am trying to incorporate pdh.h into an ATL project. Here is an example of the code I am using
// reader.cpp : Implementation of Creader #include "stdafx.h" #include "Perfreader.h" #include "reader.h" #define UNICODE #define _UNICODE #include <windows.h> #include <stdio.h> #include <malloc.h> #include <tchar.h> #include <pdhmsg.h> #include <pdh.h> ///////////////////////////////////////////////////////////////////////////// // Creader // Not the best of programming practice but // I've had better luck with static buffers // than getting buffer length information // from PDH functions. Often times a function, // when passing NULL pointer to request // the buffer size it would return the // wrong amount #define MACHINE_LIST_SIZE 1024 #define OBJECT_LIST_SIZE 4096 #define COUNTER_LIST_SIZE 8192 #define INSTANCE_LIST_SIZE 8192 #define PATH_BUFF_SIZE 256 #define TITLE_SIZE 512 // command codes of get_cmd_args /* #define GCA_PARSE_ERROR 0 #define GCA_ENUM 1 #define GCA_DUMP 2 // prototypes of functions implemented in this source void enum_perflog_items( LPCTSTR lpszLogFile ); void perf_log_dump( LPTSTR lpszLogFile, LPTSTR lpszObj, LPTSTR lpszCntr, LPTSTR lpszInst); void load_stack(DWORD dwVal); void print_usage(TCHAR *szAppname); void print_copyright(void); DWORD get_cmd_args( int argc, TCHAR **argv, LPTSTR *lppszLogFile, LPTSTR *lppszObj, LPTSTR *lppszCntr, LPTSTR *lppszInst ); void print_pdh_error( LPTSTR lpszFuncName, PDH_STATUS pdhStatus ); */ void enum_perflog_items( LPCTSTR lpszLogFile ) { PDH_STATUS pdhStatus = 0; HLOG hLog = NULL; DWORD dwCharsNeeded = 0; TCHAR mszMachines[MACHINE_LIST_SIZE]; TCHAR mszObjects[OBJECT_LIST_SIZE]; TCHAR mszCounters[COUNTER_LIST_SIZE]; TCHAR mszInstances[INSTANCE_LIST_SIZE]; TCHAR szTitle[TITLE_SIZE]; PDH_TIME_INFO pdhTimeInfo; SYSTEMTIME stStart, stEnd; DWORD dwBufferSize = 0; DWORD dwNumEntries = 0; DWORD dwItemIndex = 0; LPTSTR lptrObj = NULL; LPTSTR lpszMachine = NULL; memset(mszMachines, 0, MACHINE_LIST_SIZE * sizeof(TCHAR)); memset(mszObjects, 0, OBJECT_LIST_SIZE * sizeof(TCHAR)); memset(mszCounters, 0, COUNTER_LIST_SIZE * sizeof(TCHAR)); memset(mszInstances, 0, INSTANCE_LIST_SIZE * sizeof(TCHAR)); memset(szTitle, 0, TITLE_SIZE * sizeof(TCHAR)); memset(&pdhTimeInfo, 0, sizeof(dwBufferSize)); // enumerate machines in the log file dwCharsNeeded = MACHINE_LIST_SIZE; pdhStatus = PdhEnumMachines(lpszLogFile, mszMachines, &dwCharsNeeded); if (IsErrorSeverity(pdhStatus)) { //print_pdh_error(TEXT("PdhEnumObjects"), pdhStatus); return; } // output multistring enumeration lpszMachine = mszMachines; //_tprintf(TEXT("%s contains info from the following machine names\n"), // lpszLogFile); while (*lpszMachine) { // _tprintf(TEXT("%s\n"), lpszMachine); lpszMachine = lpszMachine + lstrlen(lpszMachine) + 1; // next string } //_tprintf(TEXT("\n")); // typically you would enumerate objects/counters for each // machine but in this example I only enumerate the such for // the first machine. lpszMachine = mszMachines; dwCharsNeeded = OBJECT_LIST_SIZE; pdhStatus = PdhEnumObjects( lpszLogFile, lpszMachine, mszObjects, &dwCharsNeeded, PERF_DETAIL_WIZARD, TRUE); if (IsErrorSeverity(pdhStatus)) { // print_pdh_error(TEXT("PdhEnumObjects"), pdhStatus); return; } // Here's a funky thing to note. // If lpszLogFile refers to a perfmon type log, and // if the buffer is not large enough for object titles, // this function will succeed in return object indexes // This is also true for PdhEnumObjectItems. // iterate through objects and get items for each lptrObj = mszObjects; while (*lptrObj) { DWORD dwCntrCharsNeeded; DWORD dwInstCharsNeeded; LPTSTR lptrItem, lptrItem2; LPTSTR counter; dwCntrCharsNeeded = COUNTER_LIST_SIZE; dwInstCharsNeeded = INSTANCE_LIST_SIZE; pdhStatus = PdhEnumObjectItems( lpszLogFile, lpszMachine, lptrObj, mszCounters, &dwCntrCharsNeeded, mszInstances, &dwInstCharsNeeded, PERF_DETAIL_WIZARD, 0); if (IsErrorSeverity(pdhStatus)) { // print_pdh_error(TEXT("PdhEnumObjectItems"), pdhStatus); break; } //_tprintf(TEXT("Items for %s\n================\n"), lptrObj); // enumerate counter items //_tprintf(TEXT("Counters\n")); lptrItem = mszCounters; while (*lptrItem) { // _tprintf(TEXT("\t%s\n"), lptrItem); counter = lptrItem; // not all objects have instances // dwInstCharsNeeded will be zero if no instances if (dwInstCharsNeeded) { lptrItem2 = mszInstances; // _tprintf(TEXT("Instances\n")); while (*lptrItem2) { // _tprintf(TEXT("\t%s\n"), lptrItem2); //call dump log with timing info // perf_log_dump(lpszLogFile, lptrObj, counter, lptrItem2); lptrItem2 += lstrlen(lptrItem2) + 1; // get next string } //_tprintf(TEXT("\n\n")); } else { //perf_log_dump(lpszLogFile, lptrObj, counter, NULL); } lptrItem += lstrlen(lptrItem) + 1; // get next string } //_tprintf(TEXT("\n")); lptrObj += lstrlen(lptrObj) + 1; // get next object } // while (*lptrObj) // todo: add code to display the data query range dwBufferSize = sizeof(PDH_TIME_INFO); pdhStatus = PdhGetDataSourceTimeRange(lpszLogFile, &dwNumEntries, &pdhTimeInfo, &dwBufferSize); if (IsErrorSeverity(pdhStatus)) { //print_pdh_error(TEXT("PdhGetDataSourceTimeRange"), pdhStatus); return; } FileTimeToSystemTime((LPFILETIME)&(pdhTimeInfo.StartTime), &stStart); FileTimeToSystemTime((LPFILETIME)&(pdhTimeInfo.EndTime), &stEnd); //_tprintf(TEXT("Time range of %s\n"), lpszLogFile); //_tprintf(TEXT("Start Time: %2d/%2d/%4d %2d:%2d:%2d\n"), // stStart.wMonth, stStart.wDay, stStart.wYear, // stStart.wHour, stStart.wMinute, stStart.wSecond); //_tprintf(TEXT(" End Time: %2d/%2d/%4d %2d:%2d:%2d\n"), // stEnd.wMonth, stEnd.wDay, stEnd.wYear, // stEnd.wHour, stEnd.wMinute, stEnd.wSecond); //_tprintf(TEXT("Contains %d data samplings\n"), pdhTimeInfo.SampleCount); } STDMETHODIMP Creader::getPerfmonData(BSTR *logfile, BSTR *startTime, BSTR *endTime, BSTR *connStr) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) return S_OK; } When I compile this as a console project it works fine. When I put this code into a MFC or ATL project I get the following errors With the #define UNICODE & #define _UNICODE statements: D:\Source\perfreader\reader.cpp(107) : error C2664: 'PdhEnumMachinesW' : cannot convert parameter 1 from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast D:\Source\perfreader\reader.cpp(139) : error C2664: 'PdhEnumObjectsW' : cannot convert parameter 1 from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast D:\Source\perfreader\reader.cpp(176) : error C2664: 'PdhEnumObjectItemsW' : cannot convert parameter 1 from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast D:\Source\perfreader\reader.cpp(229) : error C2664: 'PdhGetDataSourceTimeRangeW' : cannot convert parameter 1 from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Error executing cl.exe. without the #define UNICODE & #define _UNICODE statements: reader.obj : error LNK2001: unresolved external symbol _PdhGetDataSourceTimeRangeA@16 reader.obj : error LNK2001: unresolved external symbol _PdhEnumObjectItemsA@36 reader.obj : error LNK2001: unresolved external symbol _PdhEnumObjectsA@24 reader.obj : error LNK2001: unresolved external symbol _PdhEnumMachinesA@12 Debug/perfreader.dll : fatal error LNK1120: 4 unresolved externals My system information is Windows 2000 Advanced Server Thank you in advance |
![]() |
| Bookmarks |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|