我正在构建一个 C# WPF 应用程序,并且希望能够以编程方式启用和禁用 Windows 系统功能
Focus Assist
。
我尝试研究如何以编程方式控制此功能,但看不到任何内容(可能是因为它是一个新的系统功能)。我看过有关使用
Windows.System
库的注释,但是焦点辅助似乎并不属于其中
有人能指出我正确的方向吗?
这两个命令可能对您有用:
using Windows.System;
await SystemSetting.RequestEnableAsync(SystemSettingKind.FocusAssist);
// ...
await SystemSetting.RequestDisableAsync(SystemSettingKind.FocusAssist);
我想出了以下内容。在 Windows 10 22H2 19045.3803 中测试。
备注:
在 Windows Focus Assist 设置下,“当我复制显示器时”或“当我玩游戏时”必须设置为 ON,具体取决于您打算以编程方式激活的模式。
Windows 似乎会跟踪哪个进程/应用程序负责激活 Focus Assist。如果这不是您的应用程序,则无法将其关闭(如果您找到解决方法,请告诉我)。
要打开聚焦辅助,您必须首先发出将其关闭的命令,然后再发出将其打开的命令。不知道为什么。
using System.Runtime.InteropServices;
while(true)
{
var focusAssistMode = Console.ReadLine() == "on" ? FocusAssistMode.Fullscreen : FocusAssistMode.Off;
var result = FocusAssistHelper.SetFocusAssistMode(focusAssistMode);
if (result == 0)
{
Console.WriteLine("Success");
}
else
{
Console.WriteLine($"Failed with error code {result}");
};
}
public static class FocusAssistHelper
{
[DllImport("ntdll.dll", SetLastError = true)]
static extern int ZwUpdateWnfStateData(
ref ulong StateName,
IntPtr Buffer,
int Length,
Guid TypeId,
IntPtr ExplicitScope,
uint MatchingChangeStamp,
bool CheckStamp
);
const ulong WNF_SHEL_QUIET_MOMENT_SHELL_MODE_CHANGED = 0xd83063ea3bf5075UL;
public static int SetFocusAssistMode(FocusAssistMode mode)
{
var modeAsByteArray = BitConverter.GetBytes((uint)mode);
var bufferPtr = Marshal.AllocHGlobal(modeAsByteArray.Length);
try
{
Marshal.Copy(modeAsByteArray, 0, bufferPtr, modeAsByteArray.Length);
var stateName = WNF_SHEL_QUIET_MOMENT_SHELL_MODE_CHANGED;
return ZwUpdateWnfStateData(ref stateName, bufferPtr, modeAsByteArray.Length, Guid.Empty, IntPtr.Zero, 0, false);
}
finally
{
Marshal.FreeHGlobal(bufferPtr);
}
}
}
public enum FocusAssistMode : uint
{
Off = 0,
Game = 1,
Fullscreen = 2,
}