关于c#:. NET Windows 7使用“本地系统帐户”在“Windows服务”下运行时截屏不起作用

.NET Windows 7 take screenshot not working when running under 'Windows Service' with 'Local System Account'

在Windows 7 x64上运行时,我有以下代码,当我作为独立应用程序(如ConsoleApplication1)运行时,这些代码工作正常:

1
2
3
4
5
6
7
8
9
var screen = Screen.PrimaryScreen;

using (var bitmap = new Bitmap(screen.Bounds.Width, screen.Bounds.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
    graphics.CopyFromScreen(new Point(screen.Bounds.Left, screen.Bounds.Top), new Point(0, 0),
    screen.Bounds.Size);
    bitmap.Save(@"c:\\Test.png", ImageFormat.Png);
}

我需要将这段代码放在"Windows服务"中,"本地系统帐户"和"允许服务与桌面交互",但是当我在那里运行它时,它会捕获一个黑屏。

我知道在Win7中,服务是孤立的,没有与桌面的交互,但是我需要以某种方式截图,或者传递一些管理凭证。

Windows服务必须以"本地系统帐户"运行,我无法将其更改为以管理员身份运行

我怎么还能截图呢?


截屏与GUI相关,但Windows服务不能有GUI。这个msdn文章提供了一个解决方法,但是它说:在提升的安全上下文中运行的服务,例如localsystem帐户,不应该在交互式桌面上创建一个窗口,因为在交互式桌面上运行的任何其他应用程序都可以与这个窗口交互。这将向登录用户执行的任何应用程序公开该服务。此外,作为LocalSystem运行的服务不应通过调用OpenWindowsStation或GetThreadEsktop函数来访问交互式桌面。

此外,这些文章还进一步讨论了这个问题:1。Windows服务屏幕捕获返回黑屏2。如何在上运行Windows GUI应用程序作为服务?


您正在拍摄的屏幕截图是会话0桌面。这就是服务运行的地方。"允许服务与桌面交互"选项的描述本身可能有点误导人。下面是它允许的一个很好的描述:http://msdn.microsoft.com/en-us/library/windows/desktop/ms683502(v=vs.85).aspx

一次可以有许多"桌面",因为您可以有多个用户登录(快速用户切换和RDP)。您可能需要改进您的方法,以获取"控制台"用户的会话或当前登录的用户的会话。

您需要一个在窗口会话中运行的代理进程来完成这项工作。

我建议您进一步调查并为您找到正确的选择:

  • 使用CreateProcessAsUser在用户会话中生成进程以截屏
  • 在每个用户的会话中运行一个系统托盘应用程序,您可以与之交互(即命名管道),并告诉它截屏。