Disabling screenshot functionality in a Windows Phone app

Update: Kudos to Murat and Rudy Huyn for pointing me out on a missing return; that would cause the NotSupportedException to be raised all the time… I’ve fixed the code by inverting the if condition.

Update 2: Just noticed that GDR2 is also supported, as the code below will also work in devices with it! :)

Windows Phone 8 made it possible to take a screenshot of your screen at any time, just by pressing the Windows and Power button at the same time.

Sure, this is a really cool feature and can be quite handy from time to time, but it can become a security concern for some specific scenarios, not to mention a way to copy someone else’s graphical designs!

Since Windows Phone 8 update 3 (GDR2) there is now a hidden feature that allows you to disable the Screenshot functionality on a page by page basis: the PhoneApplicationPage.IsScreenCaptureEnabled!

This is a hidden property that requires Reflection in order to access and modify it’s state. The following extension methods will help you with that:

public static class PhoneApplicationPageExtensionMethods
{
    public static bool CanSetScreenCaptureEnabled(this PhoneApplicationPage page)
    {
        return Environment.OSVersion.Version >= new Version(8, 0, 10322);
    }

    public static void SetScreenCaptureEnabled(this PhoneApplicationPage page, bool enabled)
    {
        var propertyInfo = typeof(PhoneApplicationPage).GetProperty("IsScreenCaptureEnabled");

        if (propertyInfo == null)
        {
            throw new NotSupportedException("Not supported in this Windows Phone version!");
        }

        propertyInfo.SetValue(page, enabled);
    }

    public static bool GetScreenCaptureEnabled(this PhoneApplicationPage page)
    {
        var propertyInfo = typeof(PhoneApplicationPage).GetProperty("IsScreenCaptureEnabled");

        if (propertyInfo == null)
        {
            throw new NotSupportedException("Not supported in this Windows Phone version!");
        }

        return (bool)propertyInfo.GetValue(page);
    }
}

The first step is to call CanSetScreenCaptureEnabled() from inside your PhoneApplicationPage to check if the Windows Phone version is at least Windows Phone 8 update 3 (version 8.0.10322) as that is the minimum required version for this to work!

If it is, we can then use the GetScreenCaptureEnabled() and SetScreenCaptureEnabled() extension methods to change the property value!

Here is a sample usage code to disable screenshot functionality:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        if (this.CanSetScreenCaptureEnabled())
        {
            this.SetScreenCaptureEnabled(false);
        }
    }
}

If you do try to take a screenshot after that code, this is what will happen:

Application screenshot functionality disabled

The same result will happen from the application switcher screen:

Task switcher screenshot functionality disabled

Nowadays, privacy has become the #1 concern in everything we do, and I’m sure this is a really useful information for a bunch of apps out there (looking at you 6snap and all other Snapchat apps ;) )

  • Wesley Cabus

    From a security point of view, this is of course very handy to have. However, by changing the property using reflection, your app might break when the next update for Windows Phone appears.

    • http://www.pedrolamas.com/ Pedro Lamas

      Indeed, that is a really good point! But one can improve the CanSetScreenCaptureEnabled to check for the property existance before even trying to change it, or just encapsulate everything in a try…catch code block!

      • Jeremy

        In my unreleased Snapchat app, I do something similar to check whether the Sound property for the Toast notifications exists. I essentially enumerate through the GetProperties collection and check whether the property exists or not and go forward from there

    • Jeremy

      From what I’ve seen, Microsoft has only added properties between the first version through GDR3. They haven’t removed or changed any property names. Most of the big changes have been in the native system dlls

  • Jeremy

    Great write up! I ran across that method a few months ago after pulling the Microsoft.Phone.dll from my phone and doing a diff between it and the GDR2 dll. Never had a chance to test it, but I’m glad someone did :)

  • http://PauloMorgado.NET/ Paulo Morgado

    Now, there’s a great idea for a Cimbalino XAML behavior.

    • http://www.pedrolamas.com/ Pedro Lamas

      I’ll be adding it quite soon, as a service and/or behavior! ;)

  • http://www.mrtgr.com/ Murat

    Great post, I think there is a missing return; after propertyInfo.SetValue(page, enabled);

    • http://www.pedrolamas.com/ Pedro Lamas

      Well spotted!! I’ve fixed it now! Thanks! :)

  • Pingback: Weekend Links 01/19 - Game Words 777 - Site Home - MSDN Blogs

  • http://www.adamdawes.com AdamDawes

    I wonder how that interacts with apps like Beamer?

    • http://www.pedrolamas.com/ Pedro Lamas

      Just tested and apparently, Nokia Beamer is unafected so you can still see all screens in a remote device! :

  • Mark Monster

    Nice article Pedro!

  • robertmclaws

    Thanks for this technique, Pedro! I hope you don’t mind, but as soon as I read this I knew I had to turn it into an Attached Property. So I took it a step further and made a few minor usability modifications along the way. For example, if you want to know “IsScreenCaptureEnabled” on GDR1, technically the answer is yes, even though the property is not present, because WP8 RTM and later can take screenshots. In that instance, I didn’t see a need to throw an exception. I also eliminated exceptions from the Set method, because of the next change I made.

    You don’t want the call to DisplayHelper.ScreenCaptureEnabled=”false” in XAML to crash the designer, so I made the setter fail gracefully if setting the value isn’t possible. Then I changed the Extension Methods to EnableScreenshots() and DisableScreenshots(), which I found to be slightly more intuitive to the developer, and made them call the same methods that the Attached Property does.

    Anyway, you can see the changes here: https://github.com/advancedrei/XamlEssentials/commit/3e6be9c2866e80694f8d60dee6aa943b2a9bc825 (to which you are credited throughout), and which was just released in XamlEssentials 3.6 on NuGet. Feel free to use any of my changes in your Cimbalino version, as well as anything else you find in there. And thanks again for finding this!

    • http://www.pedrolamas.com/ Pedro Lamas

      Nice one Robert! I’ll be adding this on Cimbalino later this week, probably as a Blend Behavior and/or a MVVM Service! :)

  • Pingback: Disabling screenshot functionality in a Windows Phone app

  • Pingback: New API in Windows Phone 8 GDR3 « Martin Suchan – BloQ

  • Pingback: Windows App Developer Links – 2014-01-30 | Dan Rigby