是否有一种方法可以通过Win32 App检测Windows 10中的Focus Assist(以前的安静时间)中的更改 [英] Is there a way to detect changes in Focus Assist (formerly Quiet Hours) in Windows 10 from a Win32 App

查看:275
本文介绍了是否有一种方法可以通过Win32 App检测Windows 10中的Focus Assist(以前的安静时间)中的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在打开对焦辅助"后将应用程序中的状态自动更改为DND.

I'd like to change the presence state in an App automatically to DND when Focus Assist is turned on.

所以基本上有两个问题:

So two questions basically:

  • 是否可以通过例如Windows 10 SDK?

  • Is it possible to check Focus Assist state through e.g. Windows 10 SDK?

对于Windows 8中的安静时间",这里有一个类似的问题:

There is a similar question for Quiet Hours in Windows 8 here: Get windows Quiet hours from Win32 or C# API, though it's not clear whether it also still applies to "Focus Assist" since this is no longer a true or false value. Quiet hours had only ON/OFF state while Focus Assist can be OFF/PRIORITY/ALARMS.

但是,一个更有趣的问题在上面的文章中没有得到回答:我是否可以注册一个事件,以获取有关状态更改的通知?

The more interesting question though, which is not answered in the post mentioned above: is there an event I could register to, to get notified about state changes?

目标是在Focus Assist状态更改时立即获得通知,而不必定期查询注册表.

The goal is to get notified right away, when Focus Assist status changes in order to not have to query the registry on a regular basis.

推荐答案

据我所知,没有正式记录的获取焦点协助"状态的方法.

As far as I know there is no officially documented way of getting the Focus assist status.

仍可以通过查询 WNF状态来访问的功能,尽管此功能尚未完全记录,也未得到官方支持.

It still can be accessed by querying the WNF State of the feature, although this is completely undocumented and not officially supported.

WNF数据的各种状态为 ,因此用于Focus Assist的是WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED.

The various states for WNF Data have been reverse engineered, so the one for Focus Assist is WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED.

下面的C ++示例显示了如何获取Focus Assist功能的状态(主要是offpriority_onlyalarm_only).

The C++ sample below shows how to get the state of Focus Assist feature (mostly off, priority_only and alarm_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;
}

这篇关于是否有一种方法可以通过Win32 App检测Windows 10中的Focus Assist(以前的安静时间)中的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆