使用C#和WPF在Windows上防止屏幕截图

4

我试图像Microsoft Office一样防止我的WPF窗口被截屏。

我尝试使用SetWindowDisplayAffinity,但它总是返回false,而且我不知道在哪里调用这个方法。

App.xaml:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetWindowDisplayAffinity(IntPtr hwnd, DisplayAffinity affinity);

protected override void OnStartup(StartupEventArgs e)
{
    var mainView = new MainWindow();
    var ok = SetWindowDisplayAffinity(Process.GetCurrentProcess().MainWindowHandle, DisplayAffinity.Monitor);
    mainView.Show();
}

但是SetWindowDisplayAffinity方法总是返回false。我找到了另一个问题,但它没有说明这个方法应该在哪里使用。


1
“像微软办公套件一样”是什么意思?自从何时起,微软办公套件阻止你截屏了吗? - user2819245
2
@elgonzo,对于受IRM/DRM保护的文件,它会防止屏幕截图并使窗口变黑。 - JoeYop
@elgonzo 这就是我想要的:https://imgur.com/a/UVyXbP2 它是微软Word,但我希望我的应用程序也能实现同样的功能,而且还可以与视频录制一起使用。 - JoeYop
很遗憾,我不知道该怎么做(Office365似乎依赖于浏览器内部的一些与DRM相关的实现)。但是看看这个涉及某种微软代表的对话:https://answers.microsoft.com/en-us/msoffice/forum/all/why-am-i-able-to-capture-the-screenshot-of-a-irm/df2a40ff-6f86-4fff-b0aa-d3dd67dd2598 ,即使是权威人士也认为,在文档被打开并在Office中显示后,可靠地阻止某人进行截屏(以任何方式)是一个愚蠢的行为。 - user2819245
关于您的“SetWindowDisplayAffinity”问题。第一个建议是调用本地的“GetLastError”函数,以查看当“SetWindowDisplayAffinity”返回false时实际的错误是什么。第二个建议(我猜测),是在窗口显示后尝试调用“SetWindowDisplayAffinity”。也许是因为本机主窗口句柄在主窗口显示之前没有被创建... - user2819245
显示剩余2条评论
1个回答

3
在主窗口中添加一个事件处理程序到“Loaded”事件:Loaded="Window_Loaded":
然后像下面这样定义该方法:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    IntPtr handle = (new WindowInteropHelper(this)).Handle;
    bool s = SetWindowDisplayAffinity(handle, DisplayAffinity.Monitor);
    MessageBox.Show(s.ToString());
}

如果在截屏时,代码返回True,那么该窗口会被黑掉。

如果将相同的代码放在构造函数中的InitializeComponent();之后,则返回False,窗口不会被黑掉。

请注意,如果窗口未加载,(new WindowInteropHelper(this)).Handle将等于0,并且在窗口加载后它会有一个值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接