C#:如何检测屏幕阅读器是否正在运行?

Jev*_*sov 5 c# accessibility screen-readers ui-automation jaws-screen-reader

如何检测屏幕阅读器是否正在运行(JAWS)?

正如我在.NET 4的理解,我们可以使用AutomationInteropProvider.ClientsAreListeningSystem.Windows.Automation.Provider命名空间,但如果我必须做的.NET 2.0是什么?

我试图检查ClientsAreListening源代码,它RawUiaClientsAreListening从UIAutomationCore.dll库调用外部方法.

您对如何在.NET 2.0中实现JAWS检测有任何想法吗?

Jus*_*tin 4

使用传递 a of 的SystemParametersInfo函数uiActionSPI_GETSCREENREADER

为此,您需要使用P/Invoke,例如:

internal class UnsafeNativeMethods
{
    public const uint SPI_GETSCREENREADER = 0x0046;

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref bool pvParam, uint fWinIni);
}

public static class ScreenReader
{
    public static bool IsRunning
    {
        get
        {
            bool returnValue = false;
            if (!UnsafeNativeMethods.SystemParametersInfo(UnsafeNativeMethods.SPI_GETSCREENREADER, 0, ref returnValue, 0))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(), "error calling SystemParametersInfo");
            }
            return returnValue;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能比使用该ClientsAreListening属性更好,因为该属性似乎对任何自动化客户端(而不仅仅是屏幕阅读器)返回 true。

另请参阅:

您还应该侦听消息WM_SETTINGCHANGE以检测屏幕阅读器是否开始/停止运行。


更新(回应 BrendanMcK 的评论):

尽管这从未以尽可能多的文字明确记录,但查看该标志的描述我认为该标志的目的相对明确:

确定屏幕检查器实用程序是否正在运行。屏幕查看器实用程序将文本信息定向到输出设备,例如语音合成器或盲文显示器。设置此标志后,应用程序应在原本以图形方式呈现信息的情况下提供文本信息。

这意味着,每当应用程序希望 UI 表现得像屏幕阅读器正在运行时,应用程序都会设置此标志,无论该应用程序实际上是否是屏幕阅读器

响应此标志的合适做法是添加文本,以便向用户“读取”原本直观的 UI 状态。如果需要进行根本性的更改才能使您的 UI 屏幕阅读器易于访问,那么您的 UI 对于签名用户来说可能也不是那么直观,可能需要重新思考。