У меня проблема с тем, что иногда мой код будет работать правильно, но в других случаях он не будет работать.
Это первый бит кода, связанного с PDH, который я запускаю:
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.");
Результат вызова функции PdhExpandCounterPath равен 0x800007D0
(PDH_CSTATUS_NO_MACHINE
). Функция checkPDHStatus
- это простая функция, которую я написал, которая утверждает, что статус равен второму параметру. В этом случае я ожидаю, что результатом будет PDH_MORE_DATA, потому что paths
равен NULL
, а bufferSize
равен 0
. Цель этого вызова - определить размер буфера, который я должен выделить для хранения всех результатов для последующего вызова PdhExpandCounterPath
. Это описано в документации PDH в разделе Примечания .
В списке кодов ошибок PDH описывается PDH_MORE_DATA
как «Невозможно подключиться к указанному компьютеру или компьютер отключен». Как видно из приведенного выше кода счетчика производительности, я даже не пытаюсь подключиться к компьютеру, отличному от моего.
Интересно, что этот код не работает. Иногда он работает нормально, а затем в других случаях он не будет работать при множественном параллельном выполнении моего приложения. У меня есть #include <pdh.h>
в моем заголовочном файле, и у меня есть раздел на листе свойств для этой DLL, который выглядит следующим образом:
<Tool
Name="VCLinkerTool"
AdditionalDependencies="pdh.lib"
/>
Я не уверен, имеет ли это значение, но эта программа построена на Visual Studio 2005 и работает на Windows XP. Я что-то делаю неправильно?
Я сотрудник Дейва и обнаружил следующее во время моего расследования:
приведенный выше код работает нормально при запуске из вошедшего в систему интерактивного сеанса
код работает нормально, когда инициируется как запланированная задача, и пользователь входит в систему во время запуска запланированной задачи
код НЕ ВЫПОЛНЯЕТСЯ только при запуске в качестве запланированной задачи, и пользователь НЕ вошел в систему во время запуска задачи
код продолжает давать сбой, если пользователь входит в систему после запуска сбойной задачи, но пока она еще выполняется (потому что он «зацикливается» до тех пор, пока не получит обратно статус PDH_MORE_DATA).
В случае сбоя следующие переменные среды не были установлены / установлены для программы: APPDATA, HOMEDRIVE и HOMEPATH ... Я не думаю, что это проблема. Тем не менее, в сбойной программе также отсутствует SeCreateGlobalPrivilege из ее токена; все программы, проходящие мимо, имеют эту привилегию в токене, и PERFMON показывает ее как «по умолчанию включено». Другое отличие состоит в том, что у программы, в которой произошел сбой, в маркере есть группа пользователей NT_AUTH \ BATCH, а у программы-участника вместо нее NT_AUTH \ INTERACTIVE ... все остальные группы пользователей и привилегии одинаковы для обоих случаев. Я думаю, что глобальная привилегия исходит от интерактивного входа в систему, но я не знаю, имеет ли это какое-либо отношение к работе PDH.
Я не могу найти в документации Performance Counter / PDH ничего, что говорило о необходимости каких-либо специальных разрешений или привилегий для успешной работы этой функции. Требуется ли глобальная привилегия для использования счетчиков производительности?
Или есть какая-то другая разница контекста / среды между выполнением запланированных задач (как определенного пользователя), когда этот пользователь вошел в систему / не вошел в нее во время запуска задачи, что будет учитывать, соответственно, успешный / неудачный вызов PDH