使用性能计数器获得正常运行时间的权限问题

Posted

技术标签:

【中文标题】使用性能计数器获得正常运行时间的权限问题【英文标题】:Permission issue getting uptime with performance counters 【发布时间】:2011-06-15 06:31:47 【问题描述】:

我正在尝试使用 C++ 中的性能计数器读取系统正常运行时间。我希望至少同时支持 XP 和 Windows 7。

以下代码在 Windows XP 上运行良好...

HQUERY hQuery; HCOUNTER hCounter;
PDH_FMT_COUNTERVALUE Value;
int ret = 0;

if (PdhOpenQuery(NULL, 0, &hQuery) == ERROR_SUCCESS) 
  if ((status = PdhAddCounter(hQuery, queryURI, 0, &hCounter)) == ERROR_SUCCESS) 
    if ((status = PdhCollectQueryData(hQuery)) == ERROR_SUCCESS) 
      if ((status = PdhGetFormattedCounterValue(hCounter, PDH_FMT_LARGE, NULL, &Value)) == ERROR_SUCCESS) 
        ret = (DWORD)(Value.largeValue);
      
    
    PdhRemoveCounter(hCounter);
  
  PdhCloseQuery(hQuery);

return ret;

..但它在 Windows 7 上失败。具体来说,PdhCollectQueryData 返回 PDH_NO_DATA 无论我是否以管理员身份运行。

如何在 Windows 7 和 XP 上获得系统正常运行时间?我预计时间会比 GetTickCount 的 49 天溢出大得多,如果可能的话,我宁愿没有单独的 XP 的 PDH 版本和 7 的 GetTickCount64 版本......

【问题讨论】:

【参考方案1】:

因此,PdhCollectQueryData 的帮助表明,如果执行查询的进程缺少允许查询的适当提升令牌,则可以返回 PDH_NO_DATA。看看您是否可以准确检查进程本身已分配的用户权限,无论您是否以管理员身份登录。 Windows 7 对这个概念有很多细化,尤其是在打开 UAC 的情况下。使用操作系统创建的本地管理员帐户和管理员组的成员之间在帐户最终获得的权限方面也可能存在区别,尽管我在性能计数器上没有遇到特定的权限。

例如,在进程中尝试明确的“以管理员身份运行”,并确保您使用的管理员帐户确实具有该权限(我不确定您是否已经尝试过此操作) .尝试性能日志用户组中的用户帐户。尝试安装操作系统时创建的帐户。尝试关闭 UAC。希望这些有助于确定问题的根源。

来自Microsoft help on the subject:

只有计算机管理员或性能日志用户组中的用户才能记录和查看计数器数据。只有当他们用于记录和查看计数器数据的工具是从以管理员身份运行...打开的命令提示符窗口启动时,管理员组中的用户才能记录和查看计数器数据。性能监控用户组中的用户可以查看计数器数据。

【讨论】:

这一定是问题所在,但我似乎仍然无法解决它。我将我的用户添加到性能日志用户组,禁用 UAC,无论是否我正常运行二进制文件,以管理员身份或从提升的命令提示符运行它。 对于迟到的回复深表歉意,但我最近遇到了一些可能有帮助的东西。您可能需要明确请求您的流程的许可。有关详细信息,请参阅msdn.microsoft.com/en-us/library/aa446619.aspx。您使用调整权限打开一个进程令牌 (OpenProcessToken),然后使用调用 AdjustTokenPrivileges 的代码调整令牌的权限。我必须这样做才能拥有一个以管理员权限运行的进程来调整当前系统时区。

以上是关于使用性能计数器获得正常运行时间的权限问题的主要内容,如果未能解决你的问题,请参考以下文章

为运行Microsoft Dynamics CRM 异步处理服务指定账户没有性能计数器权限

在 Windows 上读取性能数据计数器是不是需要任何特殊的安全权限?

获取 C 中的进程性能计数器

使用 powershell 获得计数器性能

增加性能计数器所需的权限

为啥我的 ASP.NET MVC 多实例性能计数器不起作用