You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过PID为进程开启EcoQoS(效率模式)及任务管理器验证问题

问题描述

我正尝试通过进程ID(PID)为指定进程开启效率模式(EcoQoS),参考相关内容后仍遇问题:日志显示EcoQoS已开启,但任务管理器未体现该状态。当前目标是在Windows 11的Visual Studio 2022中,通过C++控制台程序实现该功能,后续计划集成到.NET C#编写的大型UWP应用中。

测试代码

#include <iostream>
#include <windows.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <tchar.h>
#include <sstream>

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

// Enables EcoQoS (power throttling) for a specific process by its PID
void enable_ecoqos_for_pid(DWORD pid) {
    // Open a handle to the target process with the required access rights
    HANDLE hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, pid);
    if (hProcess == NULL) {
        // Log an error message if the process handle cannot be obtained
        std::cerr << "Failed to open process. Error: " << GetLastError() << std::endl;
        return;
    }

    // Initialize the power throttling state structure
    PROCESS_POWER_THROTTLING_STATE powerThrottlingState = {};
    powerThrottlingState.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
    powerThrottlingState.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
    powerThrottlingState.StateMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;

    // Apply the power throttling settings to the target process
    if (!SetProcessInformation(hProcess, ProcessPowerThrottling, &powerThrottlingState, sizeof(powerThrottlingState))) {
        // Log an error message if setting the power throttling information fails
        std::cerr << "Failed to enable power throttling for PID " << pid << ". Error: " << GetLastError() << std::endl;
    } else {
        // Log a success message if the power throttling settings are applied successfully
        std::cout << "Power throttling enabled successfully for PID " << pid << "." << std::endl;
    }

    // Close the handle to the process to free resources
    CloseHandle(hProcess);
}

int main() {
    // Define the process ID for which EcoQoS should be enabled
    DWORD pid = 16196;

    // Enable EcoQoS for the specified process ID
    enable_ecoqos_for_pid(pid);

    // Print a message indicating the end of the program
    std::cout << "Hello World!" << std::endl;

    // Return 0 to indicate successful program termination
    return 0;
}

疑问

  1. 我的代码是否正确为指定PID开启了效率模式?
  2. 当任务管理器不显示时,如何验证进程已开启效率模式?

补充信息:使用Visual Studio 2022,目标集成应用是.NET C#编写的UWP应用,启用效率模式的相关文档较少,需要技术建议。


解答

1. 代码正确性分析

核心逻辑是正确的,但需注意几个关键细节:

  • 权限要求:OpenProcess使用PROCESS_SET_INFORMATION权限符合要求,但如果目标是系统进程、高权限进程(如管理员运行的进程),控制台程序必须以管理员身份启动,否则会返回错误码5(拒绝访问)。
  • 参数有效性:PROCESS_POWER_THROTTLING_STATE的版本、控制掩码和状态掩码设置正确——PROCESS_POWER_THROTTLING_EXECUTION_SPEED正是对应Windows 11效率模式的CPU限速逻辑。
  • 特殊进程限制:系统关键进程、受保护进程即使权限足够,也可能被阻止修改Power Throttling状态;若进程本身设置了实时优先级(REALTIME_PRIORITY_CLASS),效率模式可能不会生效,任务管理器也不会显示状态变更。

2. 效率模式验证方法(替代任务管理器)

方法1:通过API读取当前状态

编写验证函数,调用GetProcessInformation读取目标进程的Power Throttling状态:

bool is_ecoqos_enabled(DWORD pid) {
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (!hProcess) {
        return false;
    }

    PROCESS_POWER_THROTTLING_STATE state = {};
    state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
    state.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;

    bool result = false;
    if (GetProcessInformation(hProcess, ProcessPowerThrottling, &state, sizeof(state))) {
        // 检查StateMask是否包含效率模式标记
        result = (state.StateMask & PROCESS_POWER_THROTTLING_EXECUTION_SPEED) != 0;
    }

    CloseHandle(hProcess);
    return result;
}

调用该函数返回true,则表示效率模式已生效。

方法2:使用性能计数器

通过PDH(Performance Data Helper)读取进程计数器:

  • 计数器路径:\Process(*)\Power Throttling State,找到目标PID对应的进程实例,值为1表示开启效率模式。

方法3:使用Process Explorer

打开Sysinternals Process Explorer(v16.30及以上版本),找到目标进程后查看Power标签页,EcoQoS选项会直接显示当前状态。

3. 集成到.NET C# UWP应用的建议

UWP受沙箱限制,需做特殊处理:

  • 权限声明:在Package.appxmanifest中添加受限能力:
    <Package xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="rescap">
      <Capabilities>
        <rescap:Capability Name="processManagement" />
        <rescap:Capability Name="runFullTrust" />
      </Capabilities>
    </Package>
    
    runFullTrust用于允许调用桌面API,processManagement用于获取进程访问权限。
  • P/Invoke封装Win32 API:在C#中直接封装所需API,示例定义:
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool SetProcessInformation(IntPtr hProcess, PROCESS_INFORMATION_CLASS processInformationClass, IntPtr processInformation, uint processInformationLength);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool GetProcessInformation(IntPtr hProcess, PROCESS_INFORMATION_CLASS processInformationClass, IntPtr processInformation, uint processInformationLength);
    
    public enum PROCESS_INFORMATION_CLASS : uint
    {
        ProcessPowerThrottling = 13
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_POWER_THROTTLING_STATE
    {
        public uint Version;
        public uint ControlMask;
        public uint StateMask;
    }
    
    public const uint PROCESS_SET_INFORMATION = 0x0200;
    public const uint PROCESS_QUERY_INFORMATION = 0x0400;
    public const uint PROCESS_POWER_THROTTLING_EXECUTION_SPEED = 0x00000001;
    public const uint PROCESS_POWER_THROTTLING_CURRENT_VERSION = 1;
    
  • 桌面桥打包:若需操作其他进程或更高权限,建议通过桌面桥将UWP打包为MSIX应用,获得接近桌面应用的权限,规避沙箱限制。
  • C++/WinRT组件:将效率模式逻辑封装为C++/WinRT组件,在C# UWP中引用,可更安全地处理Win32 API调用和权限问题。

内容的提问来源于stack exchange,提问作者Shivam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:13:10