How do I prevent print screen
Asked Answered
H

15

11

I have a requirement that an application I am working on prevent the user from being able to easily capture the contents of the screen.

I have communicated that there is no feasible way to completely prevent this from happening, but I'm looking for methods to introduce some hurdles to the process.

I'm using C#/.NET 2.0 and WinForms

Hoard answered 15/1, 2009 at 19:25 Comment(7)
lol. Client requests are always so good ;)Grayce
Jab a screw driver into the print screen button on the user's keyboards. :) i keed, i keed!Bartolomeo
Perhaps this article might be of use: Disabling Print Screen, Calling Derived Destructors and MoreViradis
What an idiotic request - just say it's not possible and any "hurdles" are a waste of timeMalleus
Hire a force of intimidating fellows to stand behind your users while holding baseball bats. That should prevent them from doing anything undesirable with your application.Toratorah
What industry is the client in?Agape
It's possible and not too complicated at all. check my answerBartolomeo
C
23

You can't.

The best you can do is render to a hardware accelerated device on an overlay, similar to what video players used to do. Basically, you paint your entire window blue, and render your graphics onto the video card, and internally the video card will replace the blue with the graphics. The downside to this is you have to give up using winforms controls, and I don't know of any way to do this with .NET easily. I think if you use DirectShow.NET, one of their samples is putting your own graphics into a stream.

Even after doing all of that, it's still possible to get a screenshot. Just take a picture of the screen with a digital camera.

Copolymerize answered 15/1, 2009 at 19:35 Comment(4)
+1 for the digital camera. The user could have an old polaroid somewhere in the attic. Bonus points for users capturing the screen with an etch-a-sketch :-)Khalif
would this prevent me taking a screenshot from a machine emulating another with the program?Uribe
I assume you mean a virtual machine. I don't know how those are implemented. It's possible it would work, but I doubt it. Also, it seems like the windows 7 rendering mode means that this isn't possible anymore.Copolymerize
At least the answers below provide relatively clear means of making screen capture harder.Compost
D
9

From here:

A. Windows implements Print Screen using a registered hotkey. Windows uses the predefined hotkeys IDHOT_SNAPDESKTOP and IDHOT_SNAPWINDOW to handle Print Screen. These correspond to Print Screen, which captures the entire screen, and Alt+Print Screen, which captures only the active window. To disable these functions all you have to do is register the hotkeys, which causes Windows to send your app a WM_HOTKEY message when the user presses either hotkey. Your implementation can ignore the message to bypass the default screen-capture behavior. A good place to do it is in your mainframe class.

Dorking answered 15/1, 2009 at 19:31 Comment(5)
Would not work. Most screenshot capture utils define their own hotkeys alsoShowroom
Would it stop the built-in print screen from working? Is that good enough?Toratorah
That's pretty much along my thoughts. Disabling print screen would remove a good majority of screen captures. Heck, if they REALLY wanted to capture the screen, they can easily take a digital camera and get it that way.Dorking
I tested with slimKEYS, mapping PrintScreen to something else (open notepad), and it worked. That means that calling RegisterHotkey with the PrintScreen vkey code WILL WORK for you. I also tested Alt-PrintScreen. You'll have to register both, but it won't prevent other apps from capturing...Centi
Anyone can provide code sample for this? I'm trying to do this but I don't really know how.Kho
B
2

FWIW, it is possible. Here's some code:

This would be a dll that you create, then call the HookKeyboard method from your application. I've tested it and it works. Granted, if someone takes a picture with a camera it can't help, but, point made. NYAH!

    namespace KeyboardHook
    {
        public class Hooker
        {

            [StructLayout(LayoutKind.Sequential)]
            public struct KBDLLHOOKSTRUCT
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time

;
            public int extraInfo;
        }

        public delegate int HookProc(int nCode, int wParam, IntPtr ptrKBDLLHOOKSTRUCT);


        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc callBack, IntPtr hMod, int threadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int CallNextHookEx(IntPtr hhk, int nCode, int wParam, IntPtr lParam);

        private static IntPtr kbh_Handle;
        private static HookProc kbh_HookProc;

        private const int VK_SNAPSHOT = 0x2C;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_SYSKEYDOWN = 0x0104;
        private const int WH_KEYBOARD_LL = 13;

        private static int LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode < 0)
            {
                CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
                return 0;
            }

            if (wParam == WM_KEYDOWN)
            {
                IntPtr kbdll = lParam;
                KBDLLHOOKSTRUCT kbdllstruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(kbdll, typeof(KBDLLHOOKSTRUCT));

                if (kbdllstruct.vkCode == VK_SNAPSHOT)
                    return -1;

            }

            return CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
        }

        public static void HookKeyboard()
        {
            try
            {
                kbh_HookProc = LowLevelKeyboardProc;

                kbh_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, kbh_HookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

                if (kbh_Handle != IntPtr.Zero)
                    System.Diagnostics.Debug.WriteLine(String.Format("It worked! HookHandle: {0}", kbh_Handle));
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("ERROR: {0}", ex.Message));
            }
        }
    }
}
Bartolomeo answered 15/1, 2009 at 19:44 Comment(4)
Of course absolutely no use against any of the 1,000,000 screen-grabber applications (including the Windows 7 built-in one), and likely to get your application flagged by paranoid AVs as a keylogger. So that's nice.Flogging
"I'm looking for methods to introduce some hurdles to the process." This would be a hurdle and would require installing additional software.Bartolomeo
"I have a requirement that an application I am working on prevent the user from being able to easily capture the contents of the screen." -- it's still "easy" to capture the screen.Copolymerize
Wait... did you just name your class "Hooker"?Nijinsky
B
2

You can try using IpcProtectWindow provided in msipc.dll.

[DllImport("msipc.dll", SetLastError = false, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int IpcProtectWindow([In] IntPtr hwnd);

Download the SDK from Microsoft

Call the function above and provide the handle of the form you would like to protect. (Form.Handle property)

Bearberry answered 9/9, 2015 at 7:57 Comment(0)
M
1

You'll have two cases here that you need to worry about. One, when your window/application has focus, the other when it doesn't have focus.

When it doesn't have focus, there's not a whole lot you can do, i.e. if the user clicks off of your app and onto the desktop, keys aren't sent to your app so you'll never see them. In that case, you can minimize to the tray when your app loses focus (or, perhaps, place a "blank" panel over the form to prevent users from seeing anything on it which will also prevent a print-screen from being useful).

In the other case, when you have focus, capture keystrokes and examine them. If the Alt key is down and the PrintScreen key is down, reset the value so that a print-screen doesn't occur. (Come to think of it, that may not work. I'd need to test it to be sure.)

Midrash answered 15/1, 2009 at 19:34 Comment(1)
I have downvoted this because the information is misleading -- even though you are correct in that the application thread or its windows won't receive directed key events while the windows are out of focus, the documented WinAPI procedure RegisterHotKey allows caller to capture keys regardless of focus -- i.e. "system wide", which should be OPs primary interest. In other words, whether the windows are in out of focus are of little practical consequence here and certainly nothing OP should worry about.Crossquestion
C
1

You could look into what movie players do. I believe they render directly to a hardware surface (via DirectX). I suspect that you'd need to do this.

Cranford answered 15/1, 2009 at 19:35 Comment(0)
E
1

This doesn't really answer the questions, but keep in mind that there exists tools to capture screen, and that a simple camera breaks everything.

I mean ok you "have to", but I would (but I'm young and still student, so I don't know much about what can be said) answer that this is just stupid.

Epileptic answered 15/1, 2009 at 23:28 Comment(0)
I
1

Check out the new tech - sivizion.com, they prevent print screen all together - no way to bypass it. If anyone will figure out a way how to hack it, please post here, I couldn't. I think they also license their tech, not sure, check it out.

Igenia answered 11/8, 2010 at 10:48 Comment(1)
Interesting, but what a pain in the butt.Salado
M
0

Well, you could try capturing the button, but I'm not sure how well that will work.

One thing that always annoyed me was that whenever I played a movie, it would never take screenshots of it. If you can render through a separate context, it would make it really annoying to take a picture of it. Perhaps you can send your screen output through something like that?

Marquess answered 15/1, 2009 at 19:31 Comment(0)
K
0

There are applications that can capture the screen from OpenGL and DirectX apps ! (depending (they are used for recording game movies) ps. windows aero is DirectX

http://www.fraps.com/ i think thats the application

Katheleenkatherin answered 20/12, 2009 at 12:43 Comment(0)
K
0

You can make any casual Print Screen useless using Visual Cryptography and taking advantage of retinal persistence (see this article for details, and bit.ly/vcrypto for a web demo).

The idea is to alternate at high frequency between two or more random noise images, that will combine through persistence of vision to reveal the content. A screen capture will only grab one image, with meaningless random noise.

This comes at the cost of flickering and inducing user headaches, can be defeated by a camera taking a picture of the screen, or by a less casual user that knows photoshop, but will defeat any kind of casual screen capture or frame grabbing.

Might occasionally be useful, in an academic meaning of the term!

Koweit answered 1/8, 2012 at 7:57 Comment(0)
B
0

It is too late but there is a quick work around, Simply use it in MDI form
Set TopMost Property of form True, then write below event private void frmMDI_Deactivate(object sender, EventArgs e){Clipboard.Clear();}

after taking print screen user have to minimize the application, the moment user minimize the app, we are clearing clipboard.

you can use this in logout function or when screen move or resize or any other form event as required :)

Snipping tool also can't copy screens by this if TopMost Property is true.

Yes we can't stop user from capturing screen from external device like phone or cam.

Boyes answered 28/8, 2018 at 14:48 Comment(0)
M
0

In windows form application, Use this code in form keyup event,

   if (e.KeyCode == Keys.PrintScreen)
                {
                    Clipboard.Clear();
                }

Form keypreview should be TRUE

Morvin answered 30/5, 2019 at 4:29 Comment(0)
G
0

Microsoft has been developed an API named SetWindowDisplayAffinity to support the window content protection. This feature enables applications to protect application content from being captured or copied through a specific set of public operating system features and APIs
SetWindowDisplayAffinity(hWnd, WDA_MONITOR);

Germany answered 15/10, 2021 at 11:50 Comment(0)
D
-3

I solved it using a Timer object and Clipboard.Clear() method.

First add a Timer to your main form with Interval=1 (Very fast), then add the following code in its event:

Clipboard.Clear();
Dixiedixieland answered 18/9, 2012 at 14:10 Comment(3)
This looks like a very inefficient solution. An interval=1 will trigger 1000 times per second. Apart from rendering standard copy and paste functions useless, this will hog the system resources.Forgetmenot
Some Times It's very important to prevent screen capture and you have to determine whether or not consume system resource or waste some thing valuable in screen !!!Dixiedixieland
I don't doubt that preventing screen capture can be important. But there are definitely more efficient ways to do it. Even setting the interval to 1500 would be a significant improvement to your code, although I still feel your approach lacks finesse.Forgetmenot

© 2022 - 2024 — McMap. All rights reserved.