我有一个需求,希望我正在开发的应用程序可以防止用户轻易地截取屏幕内容。
我已经说明了完全防止此类情况发生是不可行的,但我正在寻找一些方法来增加一些障碍。
我正在使用C#/.NET 2.0和WinForms。
我有一个需求,希望我正在开发的应用程序可以防止用户轻易地截取屏幕内容。
我已经说明了完全防止此类情况发生是不可行的,但我正在寻找一些方法来增加一些障碍。
我正在使用C#/.NET 2.0和WinForms。
你做不到。
最好的方法是在叠加层上呈现硬件加速设备,类似于视频播放器所做的那样。基本上,你需要将整个窗口涂成蓝色,并将图形渲染到显卡上,内部显卡会用图形替换蓝色。这样做的缺点是你必须放弃使用winforms控件,且我不知道有任何一种简单的方式在.NET中实现这一点。我认为,如果你使用DirectShow.NET,他们的示例之一是将你自己的图形放入流中。
即使你做了所有这些工作,仍然可能会被截图。只需用数码相机拍摄屏幕即可。
来自这里:
A. Windows使用注册热键实现Print Screen。Windows使用预定义的热键IDHOT_SNAPDESKTOP和IDHOT_SNAPWINDOW来处理Print Screen。它们对应于Print Screen(捕获整个屏幕)和Alt+Print Screen(只捕获活动窗口)。要禁用这些功能,您只需注册热键即可,这会导致Windows在用户按下任一热键时向您的应用程序发送WM_HOTKEY消息。您可以忽略此消息以绕过默认的屏幕捕获行为。一个好的实现位置是在您的mainframe类中。
就此而言,这是可能的。以下是一些代码:
这将是一个由您创建的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));
}
}
}
}
[DllImport("msipc.dll", SetLastError = false, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int IpcProtectWindow([In] IntPtr hwnd);
从微软下载SDK
调用上述函数并提供您想要保护的表单的句柄。(Form.Handle属性)
在这里,你需要关注两种情况。一种是当你的窗口/应用程序有焦点时,另一种是没有焦点时。
当它没有焦点时,你不能做太多事情,即如果用户点击你的应用程序并进入桌面,键盘输入不会发送到你的应用程序,因此你永远看不到它们。在这种情况下,当你的应用程序失去焦点时,你可以将其最小化到托盘中(或者,也许,在表单上放置一个“空白”面板,以防止用户看到任何东西,这也将防止打印屏幕有用)。
在另一种情况下,当你有焦点时,捕获按键并检查它们。如果Alt键和PrintScreen键同时按下,则重置该值,以便不会发生打印屏幕。(想想看,那可能行不通。我需要测试一下才能确定。)
RegisterHotKey
允许调用者捕获键而不受焦点的影响——即“系统范围内”,这应该是OP的主要关注点。换句话说,无论窗口是否失去焦点,在这里都没有什么实际意义,当然也不是OP应该担心的事情。 - Armen Michaeli这并没有真正回答问题,但请记住存在捕获屏幕的工具,并且简单的相机会破坏一切。
我的意思是好吧你“必须”,但我会(但我还年轻,还是学生,所以我不太清楚可以说什么)回答这很愚蠢。
看看这个新技术 - sivizion.com,它们完全防止了屏幕截图 - 没有绕过它的方法。如果有人能想出如何破解它,请在此处发布,我无法破解。我认为他们还许可他们的技术,不确定,去看看吧。
有一些应用程序可以捕获OpenGL和DirectX应用程序的屏幕!(取决于它们是否用于录制游戏电影) 附注:Windows Aero是DirectX
http://www.fraps.com/ 我认为那就是这个应用程序
您可以使用视觉密码学和利用视网膜持续时间(详见此文章以获取详细信息,以及此bit.ly/vcrypto以获取网络演示)使任何随意的屏幕截图无效。
其思想是在两个或多个随机噪声图像之间高频交替,这些图像将通过视觉持续时间结合起来显示内容。屏幕截图只会抓取一个图像,其中包含无意义的随机噪声。
这样做的代价是闪烁和诱发用户头痛,可以被拍摄屏幕的相机或了解Photoshop的非随意用户所击败,但将击败任何一种随意屏幕截图或帧捕获。
在学术意义上,可能偶尔有用!