我需要在WinXP /Win7 7/10中捕获一个winlogon屏幕。对于WinXP,我使用的是镜像驱动程序和如下所示的标准方法:
...
extern "C" __declspec(dllexport) void SetActiveDesktop() {
if ( currentDesk != NULL )
CloseDesktop( currentDesk );
currentDesk = OpenInputDesktop( 0, FALSE, GENERIC_ALL );
BOOL ret = SetThreadDesktop( currentDesk );
int LASTeRR = GetLastError();
}
extern "C" __declspec(dllexport) HBITMAP CaptureAnImage(
int width,
int height,
int bitsPerPixel )
{
HBITMAP hbmScreen;
LPTSTR bih = NULL;
HDC hdcMemDC = NULL;
int colorDepth = GetCurrentColorDepth();
if ( bitsPerPixel > colorDepth && colorDepth > 0 )
bitsPerPixel = colorDepth;
// Checks a current HDC
if ( currHdc == NULL ) {
SetActiveDesktop();
currHdc = GetDcMirror();
}
if ( prevHdc != currHdc ) {
prevHdc = currHdc;
}
// Check an application instance handler
if ( appInstance == NULL )
appInstance = GetModuleHandle(NULL);
// Creates a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC( currHdc );
if( hdcMemDC == NULL )
{
return NULL;
}
// Defines bitmap parameters
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = bitsPerPixel;
// Creates a bitmap with defined parameters
hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );
if ( hbmScreen == NULL ) {
return NULL;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);
// Bit block transfer into our compatible memory DC.
if(!BitBlt(hdcMemDC,
0,0,
width, height,
currHdc,
0,0,
SRCCOPY))
{
SetActiveDesktop();
currHdc = GetDC(NULL);//GetDcMirror();
hdcMemDC = CreateCompatibleDC( currHdc );
// Creates a bitmap with defined parameters
hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );
if(!BitBlt(hdcMemDC,
0,0,
width, height,
currHdc,
0,0,
SRCCOPY ))
{
DeleteDC( hdcMemDC );
return hbmScreen;
}
}
if (DeleteDC( hdcMemDC ) == FALSE ) {
return NULL;
}
return hbmScreen;
}幸运的是,它可以在WinXP上工作。但是,如果是win7 7/win7 10,情况就完全不同了:
切换到winlogon后,SetThreadDesktop函数总是返回FALSE,错误为5(访问被拒绝),我试图更改策略:
- as an Administrator
- as a service with enabled desktop interaction.
- at winlogon desktop using CreateProcess flags ( in this case program simply crashes )
结果也一样。我做错什么了?我应该试试桌面复制API吗?
提前感谢您的回复!
发布于 2018-05-04 09:59:25
由于Winlogon是一个安全桌面,您必须在LOCAL_SYSTEM帐户下运行应用程序才能访问它。
示例:在LOCAL_SYSTEM下运行的windows服务,它在控制台会话中启动用户应用程序(捕捉屏幕)。
在您的代码中,不检查OpenInputDesktop的返回值,它可能为NULL,错误代码5(访问被拒绝)。
还可以查看this answer以获得更多信息
https://stackoverflow.com/questions/43520385
复制相似问题