0

I am writing a remote desktop application and I want to take a screenshot of the log in screen, the current logged user desktop, the screensaver and the UAC screen.

As a desktop application, taking a screenshot of the user desktop works fine.

Now I am implementing a windows service so that I can be able to take a screenshot of the UAC screen, the log in screen and the screensaver. However whatever I tried so far results in a black image.

I am using QService for writting a cross platform windows service and it starts fine. This is where I have reached until now to take a screenshot from the windows service:

On the main function I open the WinSta0 window station and create a new desktop

#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();
}

then, at some other point in my code, I am taking the screenshot, but the result is a black image. This is the code I am using:

// 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);

The complete application source code and executables are here: http://andama.org/source-code

How can I correctly get a screenshot of the desktop (or log in screen, or UAC screen) from a windows service?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Yiannis Mpourkelis
  • 1,366
  • 1
  • 15
  • 34

1 Answers1

0

I don't think you want this: CreateDesktop, but instead want this:

_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);
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135