winapi - 有没有办法从 Win32 应用程序检测 Windows 10 中 Focus Assist(以前称为 Quiet Hours)的变化

标签 winapi notifications windows-10 integration

我想在打开焦点辅助时自动将应用程序中的状态更改为免打扰。
所以基本上有两个问题:

  • 是否可以通过例如检查焦点辅助状态Windows 10 SDK?
    Windows 8 中的安静时间也有类似的问题:Get windows Quiet hours from Win32 or C# API ,虽然不清楚它是否也适用于“焦点辅助”,因为这不再是一个真值或假值。
    安静时间只有 ON/OFF 状态,而 Focus Assist 可以是 OFF/PRIORITY/ALARMS。
  • 不过,更有趣的问题是,上面提到的帖子中没有回答:是否有我可以注册的事件,以获取有关状态更改的通知?
    目标是在 Focus Assist 状态更改时立即获得通知,以便不必定期查询注册表。
  • 最佳答案

    据我所知,没有官方记录的获取 Focus 辅助状态的方法。

    仍然可以通过查询 WNF State 访问它功能,尽管这完全没有记录并且没有得到官方支持。

    WNF 数据的各种状态为 reverse engineered ,所以 Focus Assist 是 WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED .

    下面的 C++ 示例显示了如何获取焦点辅助功能的状态(主要是 offpriority_onlyalarm_only )。

    再次提醒,这是 未正式支持 微软:

    #include <Windows.h>
    #include <iostream>
    #include <string>
    #include <map>
    
    // from ntdef.h
    #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
    
    // from ntdef.h
    typedef struct _WNF_STATE_NAME
    {
        ULONG Data[2];
    } WNF_STATE_NAME;
    
    typedef struct _WNF_STATE_NAME* PWNF_STATE_NAME;
    typedef const struct _WNF_STATE_NAME* PCWNF_STATE_NAME;
    
    typedef struct _WNF_TYPE_ID
    {
        GUID TypeId;
    } WNF_TYPE_ID, *PWNF_TYPE_ID;
    
    typedef const WNF_TYPE_ID* PCWNF_TYPE_ID;
    
    typedef ULONG WNF_CHANGE_STAMP, *PWNF_CHANGE_STAMP;
    
    
    enum FocusAssistResult
    {
        not_supported = -2,
        failed = -1,
        off = 0,
        priority_only = 1,
        alarms_only = 2
    };
    
    std::map<int, std::string> result_map = {
        {-2, "Not Supported"},
        {-1, "Failed"},
        {0, "Off"},
        {1, "Priority Only"},
        {2, "Alarm Only"}
    };
    
    typedef NTSTATUS (NTAPI *PNTQUERYWNFSTATEDATA)(
        _In_ PWNF_STATE_NAME StateName,
        _In_opt_ PWNF_TYPE_ID TypeId,
        _In_opt_ const VOID* ExplicitScope,
        _Out_ PWNF_CHANGE_STAMP ChangeStamp,
        _Out_writes_bytes_to_opt_(*BufferSize, *BufferSize) PVOID Buffer,
        _Inout_ PULONG BufferSize);
    
    int main(int argc, CHAR** argv)
    {
        // note: ntdll is guaranteed to be in the process address space.
        const auto h_ntdll = GetModuleHandle(_T("ntdll"));
    
        // get pointer to function
        const auto pNtQueryWnfStateData = PNTQUERYWNFSTATEDATA(GetProcAddress(h_ntdll, "NtQueryWnfStateData"));
        if (!pNtQueryWnfStateData)
        {
            std::cerr << "[-] Error: couldn't get pointer to NtQueryWnfStateData() function." << std::endl;
            return -1;
        }
    
        // state name for active hours (Focus Assist)
        WNF_STATE_NAME WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED{0xA3BF1C75, 0xD83063E};
    
        // note: we won't use it but it's required
        WNF_CHANGE_STAMP change_stamp = {0};
    
        // on output buffer will tell us the status of Focus Assist
        DWORD buffer = 0;
        ULONG buffer_size = sizeof(buffer);
    
        if (NT_SUCCESS(pNtQueryWnfStateData(&WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, nullptr, nullptr, &change_stamp, 
            &buffer, &buffer_size)))
        {
            // check if the result is one of FocusAssistResult
            if (result_map.count(buffer) == 0)
            {
                std::cout << "Focus Assist result is unknown." << std::endl;
            }
            else
            {
                std::cout << "Focus assist state: " << result_map[buffer] << std::endl;
            }
        }
        else
        {
            std::cerr << "[-] Error while calling NtQueryWnfStateData." << std::endl;
            return -1;
        }
    
        return 0;
    }
    

    关于winapi - 有没有办法从 Win32 应用程序检测 Windows 10 中 Focus Assist(以前称为 Quiet Hours)的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53407374/

    相关文章:

    ruby - 尝试通过 RubyMine 2019.1 执行 Ruby 程序时出现权限被拒绝 @ rb_sysopen (Errno::EACCES) 错误

    vb.net - 如何在 VB.NET 中激活、移动和调整窗口大小

    c++ - 如果 MessageBox()/related 是同步的,为什么我的消息循环不卡住?

    android - 通知操作图标未显示

    ios - Swift 区域监控本地通知触发器

    windows-10 - 从 PowerShell 调用 Windows Shell 函数?

    windows-10 - 如何获取 Windows 10 中文件的路径?

    windows - 无需锁定的优雅文件读取

    计算 WCHAR 字符串中的字符数

    xamarin - 本地通知插件 - 图像/ Logo