如何防止打印屏幕

时间:2009-01-15 19:25:28

标签: c# .net winforms .net-2.0 c#-2.0

我要求我正在处理的应用程序阻止用户轻松捕获屏幕内容。

我已经说过没有可行的方法可以完全防止这种情况发生,但我正在寻找方法来为这个过程引入一些障碍。

我正在使用C#/ .NET 2.0和WinForms

15 个答案:

答案 0 :(得分:23)

你不能。

您可以做的最好的事情是渲染到叠加层上的硬件加速设备,类似于视频播放器过去做的事情。基本上,您将整个窗口绘制为蓝色,并将图形渲染到视频卡上,并且内部视频卡将用图形替换蓝色。这样做的缺点是你必须放弃使用winforms控件,我不知道有什么方法可以轻松地使用.NET。我想如果您使用DirectShow.NET,他们的一个示例就是将您自己的图形放入流中。

即使完成了所有这些操作,仍然可以获得截图。只需用数码相机拍摄屏幕照片即可。

答案 1 :(得分:9)

来自here:

  

一个。 Windows使用注册的热键实现Print Screen。视窗   使用预定义的热键IDHOT_SNAPDESKTOP和IDHOT_SNAPWINDOW   处理打印屏幕。这些对应于捕获的打印屏幕   整个屏幕和Alt + Print Screen,仅捕获   活动窗口。要禁用这些功能,您所要做的就是   注册热键,这会导致Windows发送您的应用程序   用户按任一热键时的WM_HOTKEY消息。您的   实现可以忽略该消息绕过默认值   屏幕捕获行为。一个好的地方就是你的大型机   类。

答案 2 :(得分:1)

这里有两个你需要担心的案例。一,当你的窗口/应用程序有焦点时,另一个当它没有焦点时。

当它没有焦点时,你可以做很多事情,即如果用户点击你的应用程序并进入桌面,则密钥不会发送到你的应用程序,所以你永远不会看到它们。在这种情况下,当您的应用程序失去焦点时,您可以最小化到托盘(或者,可能在表单上放置一个“空白”面板,以防止用户看到任何内容,这也会阻止打印屏幕的使用)。

在另一种情况下,当你有焦点时,捕捉击键并检查它们。如果Alt键关闭且PrintScreen键关闭,请重置该值,以便不会出现打印屏幕。 (想想看,它可能不起作用。我需要测试它才能确定。)

答案 3 :(得分:1)

你可以看看电影播放器​​的作用。我相信它们直接渲染到硬件表面(通过DirectX)。我怀疑你需要这样做。

答案 4 :(得分:1)

答案 5 :(得分:1)

FWIW,这是可能的。这是一些代码:

这将是您创建的dll,然后从您的应用程序中调用HookKeyboard方法。我测试了它,它的工作原理。当然,如果有人用相机拍照,它无能为力,但是,点了点。 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));
            }
        }
    }
}

答案 6 :(得分:1)

这并没有真正回答问题,但请记住,存在捕获屏幕的工具,而简单的相机会破坏所有内容。

我的意思是你“必须”,但我会(但我还年轻,仍然是学生,所以我不知道可以说什么)回答这只是愚蠢。

答案 7 :(得分:1)

查看新技术 - sivizion.com,它们会阻止所有打印屏幕 - 无法绕过它。如果有人想出办法如何破解它,请在这里发帖,我不能。我认为他们也许可他们的技术,不确定,检查出来。

答案 8 :(得分:1)

您可以尝试使用msipc.dll中提供的IpcProtectWindow。

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

下载SDK from Microsoft

调用上面的函数并提供您要保护的表单句柄。 (Form.Handle属性)

答案 9 :(得分:0)

好吧,你可以尝试捕捉按钮,但我不确定它会有多好用。

总是让我烦恼的一件事是每当我播放一部电影时,它都不会截取它的截图。如果你可以通过一个单独的上下文进行渲染,那么拍摄它就会非常烦人。也许您可以通过类似的方式发送屏幕输出?

答案 10 :(得分:0)

有些应用程序可以从OpenGL和DirectX应用程序中捕获屏幕! (取决于(它们用于录制游戏电影) PS。 Windows aero是DirectX

http://www.fraps.com/ 我认为那是应用程序

答案 11 :(得分:0)

您可以使用视觉密码术并利用视网膜持久性使任何休闲打印屏幕无效(有关详细信息,请参阅此article;有关网络演示,请参阅bit.ly/vcrypto)。

这个想法是在两个或多个随机噪声图像之间以高频率交替,这将通过持久的视觉结合来揭示内容。屏幕截图只会抓取一张图像,并且会产生毫无意义的随机噪音。

这是以闪烁和引起用户头痛为代价的,可以通过拍摄屏幕照片的相机,或者通过不太随意的用户知道photoshop来击败,但会击败任何类型的随意屏幕捕获或帧抓取

在术语的学术意义上偶尔可能有用!

答案 12 :(得分:0)

为时已晚,但是可以快速解决, 只需以MDI形式使用它
设置表单 True TopMost 属性,然后在事件下方写入 私人无效frmMDI_Deactivate(object sender,EventArgs e){Clipboard.Clear();}

在获取打印屏幕后,用户必须最小化应用程序,一旦用户最小化应用程序,我们将清除剪贴板。

您可以在注销功能中使用此功能,也可以在需要时进行屏幕移动或调整大小或任何其他表单事件时使用它:)

如果TopMost属性为true,则截图工具也无法以此复制屏幕。

是的,我们不能阻止用户从手机或摄像头等外部设备捕获屏幕。

答案 13 :(得分:0)

在Windows窗体应用程序中,在窗体键入事件中使用此代码,

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

Form keypreview应该为TRUE

答案 14 :(得分:-3)

我使用Timer对象和Clipboard.Clear()方法解决了它。

首先使用Timer(非常快)向主表单添加Interval=1,然后在其事件中添加以下代码:

Clipboard.Clear();