2

So I'm currently trying to check if a user is using a screen reader on our site. The reason I would like to check if they are is because our site provides a training module in which if they are using a screen reader, I would like to show a button that would allow them to download a printable version of the training.

Here is what I have tried so far:

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;
            }
        }
    }

I snagged this code from the following StackOverflow thread: C# : How to detect if screen reader is running?

The method I'm using apparently works for some as you can see on this thread, but I'm currently always getting "false" when calling ScreenReader.IsRunning. I'm storing the ScreenReader.IsRunning value in a ViewBag and then in my view I'm using razor syntax to show a button if that value is true. Not really sure why its always false. I have tested this using JAWS as well as Narrator that comes on everyone's computer if you are using Windows 10 I think. Any help would be much appreciated. Thank you all!

Chet_Steadman
  • 95
  • 2
  • 15
  • 6
    I don't have a solution for you, but I'll tell you why this doesn't work as you expect. You're checking to see if the server running your application has a screenreader running. This doesn't tell you anything about the client. This is server side code, and you're performing server side checks. – AaronLS Sep 19 '18 at 19:27
  • Why not simply show the download button to everyone? Non-visually impaired users may find it helpful as well. – Dan Wilson Sep 19 '18 at 19:28
  • Hey @Dan Wilson, this is a request from the client as the client wants as many people as possible taking the training via the web and is worried people would download the PDF and take the test instead of using the web if we provide this option to everyone. – Chet_Steadman Sep 19 '18 at 19:32
  • @AaronLS It may not be a solution, but it at least points me in the right, or should I say "different", direction. Thanks for the reply. – Chet_Steadman Sep 19 '18 at 19:47
  • Is the online training not accessible? Perhaps that's where you should focus. If you provide a PDF for training, make sure the PDF is tagged so that a screen reader knows the organization of the document - https://helpx.adobe.com/acrobat/using/create-verify-pdf-accessibility.html – slugolicious Sep 19 '18 at 20:16
  • This is an exercise in futility. It cannot be done reliably, and the responsible thing to do is say no to your client's request. Do they make money from the training, the test, or both? The easiest approach is to make all trainng fornats available to everyone, and let them choose which one suits them best.. It's okay to charge money for a PDF download, and all formats could be made available for one all-inclusive fee. – andrewmacpherson Sep 20 '18 at 03:25
  • 1
    @andrewmacpherson I completely agree and from what I've researched, this is a fools errand to try to get this to work. I think what I may do is just provide a "hidden" link that will not be seen but read by screen readers so that people may download the training that way should they need that functionality. But they don't really make money off of the training. Its more of a compliance requirement and taking the training via the web allows our application to grade their training performance at the very end of the training rather than the PDF version having to be manually graded. Time is money – Chet_Steadman Sep 20 '18 at 04:07
  • 1
    @Chet_Steadman beware of using visually hidden links, they are a big problem for sighted people using a keyboard. They must satisfy WCAG [Focus Visible](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-focus-visible.html). Otherwise, a keyboard user can accidentally focus and activate a link which they can't read, – andrewmacpherson Sep 24 '18 at 13:20
  • @andrewmacpherson gotcha. Hey thanks for the comments. Will definitely take everything into consideration. 508-compliance is something I'm newer to so going forward I'll chalk this up as a lesson learned, haha. – Chet_Steadman Sep 25 '18 at 00:54

3 Answers3

1

It's not possible to detect whether a user is running a screenreader. If it were possible, it would open a door for unscrupulous types to home in on people with disabilities, or for a totally different "accessible" browser experience to be delivered, rather than building interfaces that are inclusive by design.

You could create a button that's placed off-screen but still in the tab order, and make it visible when it receives focus. Then blind users could find it, and sighted keyboard users wouldn't think something strange had happened when the button received focus.

a11y_guru
  • 220
  • 3
  • 9
0

I think you can only check if user has a chrome extensions or something like that working on client side with javascript.

Idea: You can create an exe or a bath file for check users system and send information about this to your server. If user download this file and there is no screen reader then load the page. Otherwise give error about the screen reader. And when response come from user computer maybe you can use SignalR for show content to user. You can make this file a must works in users system and start downloading this file when user load the page. Its not a good way but maybe you can check this with this way.

Mustafa Alan
  • 386
  • 3
  • 17
0

The HttpRequest.Browser property returns a HttpBrowserCapabilities object that enlists the capabilities of the device that has made the request. Bear in mind that ASP.NET uses the User-Agent string sent as part of the HTTP request to identify a client. Then to populate the HttpBrowserCapabilities properties, ASP.NET processes the user-agent string using a set of pre-installed browser files, which are contained in the following location: %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\CONFIG\Browsers

HttpBrowserCapabilities Class

There are also third-parties which are far more detailed and updated with detecting device info, i.e. 51Degrees

Angel Dinev
  • 399
  • 4
  • 13