2010-12-14 47 views
0

J'ai parfois un problème lorsque mon code fonctionne correctement, mais d'autres fois, il échoue.Le premier appel à Windows Performance Counters (PDH) échoue parfois

Ceci est le premier bit de code lié PDH que je lance:

const std::wstring pidWildcardPath = L"\\Process(*)\\ID Process"; 
DWORD bufferSize = 0; 
LPTSTR paths = NULL; 

PDH_STATUS status = PdhExpandCounterPath(
    pidWildcardPath.c_str(), 
    paths, 
    &bufferSize); 
checkPDHStatus(status, PDH_MORE_DATA, L"Expected request for more data."); 

Le résultat de l'appel de la fonction PdhExpandCounterPath est 0x800007D0 (PDH_CSTATUS_NO_MACHINE). La fonction checkPDHStatus est une fonction simple que j'ai écrit qui affirme que le statut est égal au deuxième paramètre. Dans ce cas, je m'attends à ce que le résultat soit PDH_MORE_DATA car paths est NULL et bufferSize est 0. Le but de cet appel est de déterminer la taille du tampon que je dois allouer pour stocker tous les résultats pour un appel ultérieur à PdhExpandCounterPath. Ceci est décrit dans le PDH documentation sous la section Remarques.

Le list of PDH error codes décrit PDH_MORE_DATA comme "Impossible de se connecter à l'ordinateur spécifié ou l'ordinateur est hors ligne". Comme vous pouvez le voir par le chemin du compteur de performance dans le code ci-dessus, je n'essaie même pas de me connecter à un autre ordinateur que le mien.

Il est intéressant de voir comment ce code échoue. Parfois, cela fonctionne bien et d'autres fois, il échouera sur plusieurs exécutions dos-à-dos de mon application. Je #include <pdh.h> dans mon dossier d'en-tête et j'ai une section dans ma feuille de propriétés pour cette DLL qui ressemble à ceci:

<Tool 
    Name="VCLinkerTool" 
    AdditionalDependencies="pdh.lib" 
/> 

Je ne sais pas si ce qui compte, mais ce programme est construit par Visual Studio 2005 et fonctionne sur Windows XP. Est-ce que je fais quelque chose de mal?


Je suis un collègue de Dave et ont découvert ce qui suit au cours de mon enquête:

le code passe au-dessus bien lorsqu'il est exécuté à partir d'une connecté session interactive le code fonctionne très bien quand initié en tant que tâche planifiée ET que l'utilisateur est connecté au moment où la tâche planifiée est déclenchée le code FAILS uniquement lorsqu'il est exécuté en tant que tâche planifiée ET que l'utilisateur n'est PAS connecté au moment où la tâche démarre le code continue d'échouer si l'utilisateur se connecte après que la tâche défaillante a démarré mais pendant qu'elle est en cours d'exécution (parce qu'elle est en boucle "indéfiniment" jusqu'à ce qu'elle obtienne une statistique PDH_MORE_DATA nous de retour). Dans les instances défaillantes, les variables d'environnement suivantes n'ont pas été établies/définies pour le programme: APPDATA, HOMEDRIVE et HOMEPATH ... Je ne pense pas que ce soit un problème. Cependant, le programme défaillant ne dispose pas non plus de SeCreateGlobalPrivilege à partir de son jeton; les programmes qui passent ont tous ce privilège dans le jeton et PERFMON le montre comme "Default Enabled". L'autre différence est que le programme défaillant a le groupe d'utilisateurs NT_AUTH \ BATCH dans le jeton, alors que le programme passant a NT_AUTH \ INTERACTIVE à la place ... tous les autres groupes d'utilisateurs et privilèges sont les mêmes dans les deux cas. Je pense que le privilège global provient de la connexion interactive, mais je ne sais pas si cela a une incidence sur l'opération PDH.

Je ne trouve rien dans la documentation du compteur de performance/PDH qui parle d'avoir besoin d'autorisations spéciales ou de privilèges pour que cette fonctionnalité réussisse. Le privilège global est-il requis pour utiliser les compteurs de performance? Ou existe-t-il d'autres différences de contexte/d'environnement entre l'exécution de tâches planifiées (en tant qu'utilisateur spécifique) lorsque cet utilisateur est/n'est pas connecté au démarrage de la tâche, ce qui rendrait l'appel PDH réussi/échoué respectivement ?

+0

Pouvez-vous essayer ce "\\\\ nom de votre ordinateur \\ Process (*) \\ Processus d'ID" et voir si vous avez la même erreur. Vérifiez également les autorisations du code en cours d'exécution. –

+0

@Simon Mourier: Le fait que ça ne marche que parfois m'amène à croire que ce n'est pas un problème de permissions. Je ne sais pas non plus comment vérifier les permissions du code. – Dave

Répondre

0

Essayez ce format, indiquant l'ordinateur local:

const std :: wstring pidWildcardPath = L "\\ \ Processus (*) \ ID processus";