如何从Windows服务捕获屏幕?

时间:2016-01-25 13:29:06

标签: c++ windows qt service windows-services

我正在编写远程桌面应用程序,我想截取登录屏幕,当前登录用户桌面,屏幕保护程序和UAC屏幕的屏幕截图。

作为桌面应用程序,截取用户桌面的截图工作正常。

现在我正在实现一个Windows服务,这样我就可以截取UAC屏幕,登录屏幕和屏幕保护程序的屏幕截图。然而,无论我到目前为止尝试了什么,都会产生黑色图像。

我正在使用QService编写跨平台的Windows服务,它启动正常。这是我到目前为止从Windows服务截取屏幕截图的地方:

在主要功能上,我打开WinSta0窗口站并创建一个新桌面

#include <QCoreApplication>
#include "andamaservice.h"

int main(int argc, char *argv[])
{

    auto winsta = OpenWindowStation(L"WinSta0", true, GENERIC_ALL);
        qDebug("OpenWindowStation lasterror =%u", GetLastError());


        //SECURITY_ATTRIBUTES attributes = {sizeof(SECURITY_ATTRIBUTES), 0, true};
        //attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
        //attributes.bInheritHandle = true;
        //hNewDesktop = CreateDesktop("NewDesktopName", NULL, NULL, 0 , GENERIC_ALL,  &stSecurityAttr);

    auto hwinsta2 = SetProcessWindowStation(winsta);
        qDebug("SetProcessWindowStation lasterror =%u", GetLastError());


    //auto desktop = OpenDesktop(L"default", 0, false, GENERIC_ALL);
    //qDebug("OpenDesktop lasterror = %u", GetLastError());


    // Create the desktop.
    auto desktop = CreateDesktop(L"newdesktop",
                               NULL,
                               NULL,
                               0,
                               GENERIC_ALL,
                               &attributes);
    qDebug("CreateDesktop lasterror =%u", GetLastError());


    SetThreadDesktop(desktop);
    //SwitchDesktop(desktop);
    qDebug("SetThreadDesktop lasterror =%u", GetLastError());


    AndamaService service(argc, argv);
    return service.exec();
}

然后,在我的代码中的其他一点,我正在截取屏幕截图,但结果是黑色图像。这是我正在使用的代码:

// get the device context of the screen
HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);

// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);

// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

BitBlt(hMemoryDC, 0, 0, x, y, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);

qimg = QtWin::fromHBITMAP(hBitmap, QtWin::HBitmapNoAlpha).toImage();

// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

完整的应用程序源代码和可执行文件位于:http://andama.org/source-code

如何从Windows服务中正确获取桌面(或登录屏幕或UAC屏幕)的屏幕截图?

1 个答案:

答案 0 :(得分:0)

我认为您不需要:CreateDesktop,但是需要:

_hDesktop = NativeMethods.OpenDesktop("Default", 0, true, Constants.MAXIMUM_ALLOWED);

[DllImport("User32.dll", SetLastError = true)]
public static extern IntPtr OpenDesktop(String lpszDesktop, int dwFlags, bool fInherit, int dwDesiredAccess);