使用C#进行屏幕截图及远程桌面问题

16

我有一个C#控制台应用程序,可以多次截取MS Word文档的屏幕截图。它工作得很好,但是当我将此应用程序放在远程Windows XP机器上时,在我使用远程桌面时(即我的远程桌面可见),它运行良好,但是如果我运行我的应用程序并离开远程桌面(最小化它,甚至不需要注销),它所拍摄的截图都是空白的!

屏幕截图应用程序由一个以SYSTEM用户身份运行的服务运行。

如何使GUI在没有用户连接时仍然保持活动状态?

这是我使用的代码:

public Image CaptureWindow(IntPtr handle)
{
    // get te hDC of the target window
    IntPtr hdcSrc = User32.GetWindowDC(handle);
    // get the size
    User32.RECT windowRect = new User32.RECT();
    User32.GetWindowRect(handle, ref windowRect);
    int width = windowRect.right - windowRect.left;
    int height = windowRect.bottom - windowRect.top;
    // create a device context we can copy to
    IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
    // create a bitmap we can copy it to,
    // using GetDeviceCaps to get the width/height
    IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
    // select the bitmap object
    IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
    // bitblt over
    GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
    // restore selection
    GDI32.SelectObject(hdcDest, hOld);
    // clean up 
    GDI32.DeleteDC(hdcDest);
    User32.ReleaseDC(handle, hdcSrc);

    // get a .NET image object for it
    Image img = Image.FromHbitmap(hBitmap);
    // free up the Bitmap object
    GDI32.DeleteObject(hBitmap);

    return img;
}

更新

我目前正在使用PrintWindow,它是唯一能够最接近地捕获窗口框架(即最小化、最大化和关闭按钮)的方法,但内部是黑色的。

尽管它还没有完全成功,但已经向我证明了在应用程序不可见的情况下,可以从窗口句柄创建图像。

1个回答

7

不久之前,我们在做类似的事情时发现,当RDC被最小化时,远程桌面会话不会重绘或接受键盘或鼠标事件。一切正常工作直到我们最小化了RDC屏幕。后来一个同事发现这是出于性能原因。

几天前我偶然发现了这个问题,但还没有机会尝试。如果你尝试并且它可以解决问题,请告诉我 :)

最小化RDC时与远程桌面交互

关于您的评论:我认为这是另一种问题...我知道您需要确保应用程序即使没有用户登录也能正常工作。我已经实现了允许与桌面交互的服务,例如,启动和自动化应用程序。即使没有用户登录,您仍然可以使用UI自动化库(或您的代码)操作UI。

在启动计算机后,当我的服务和自动化应用程序正在运行时,一切都很正常。稍后,正在自动化的UI将出现在第一个登录人员的桌面上(我是机器管理员,我不知道当某些权限较低的用户登录时会发生什么)。

如果第一次登录是通过RDC完成的,我不知道会发生什么。也许您可以尝试更改这些RDC设置,看看是否会影响应用程序的行为。另一个选项是:

  1. 禁用RDC并配置Windows自动登录指定帐户
  2. 使用另一个远程桌面应用程序(例如TightVNC)连接到此计算机

这有帮助吗?


@Kay,你的问题是你的应用程序无法截取屏幕截图,例如登录屏幕吗?我们开发的监控软件可以访问任何屏幕,无论是用户屏幕还是登录屏幕都没有问题。你是说现在没有人登录时,你需要编程创建一个会话,在其中运行一个应用程序,进行屏幕截图,但系统应该认为没有人登录吗?请澄清最终所需的情况,以便我提供帮助。 - Maxim V. Pavlov
@Maxim - 感谢您的评论。我想做的是通过窗口句柄从某些应用程序中抓取图像。当用户登录时应该可以捕获图像,并且在用户未登录或远程桌面最小化时也应该能够捕获图像,即不依赖于Windows GUI模式。我已经开始使用PrintWindow,但是它失败了(尽管它能够捕获窗口框架而不是内容,但它显示为黑色),当远程桌面被最小化时也会失败。我希望我的应用程序能在没有用户登录时运行。它可以作为任何用户运行,无论是系统用户还是普通/管理员用户。 - Kay
@Maxim - 我也更新了我的问题。“你是说当没有人登录时,你需要通过编程方式创建一个会话,在其中运行应用程序,进行屏幕截图”,直到那个点你是正确的。 - Kay
@Kay - 只是想知道..你是否尝试更改我在答案链接中指示的RDC设置?它是否会改变屏幕截图的行为(至少在RDC最小化的情况下)? - Haplo
@Haplo - 我还没有尝试过这个,问题是我不会总是使用RDC。这只是一个例子,用来说明Windows进入无GUI模式时,我无法依赖Windows GUI来捕获图像。即使它能够工作,也不能解决我所有的问题。 - Kay
显示剩余13条评论

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