VC++实现对远程计算机屏幕的监视
CND8学院 VC教程 发布日期:2009年06月18日
将本文收藏到: | 收藏到本地 | 复制本文地址
--------------------------------------------------------------------------------
对远程计算机屏幕的捕捉和显示
前面部分的工作只是为整个监控系统提供一个低层的网络数据通讯的能力,也可以说是为现场主机和监控中心提供一个通信用信道。至于本文的中心议题--远程监视工作则需要分别在现场主机和监控中心中完成对屏幕的捕捉和信息的再现。屏幕的捕捉可以采取先获取桌面窗口指针并建立一个与之兼容的设备环境,然后创建一个与桌面窗口指针相兼容的内存位图并以位图的形式将屏幕图像拷贝到新创建的位图之中:
char dot[1572864]; //1024*768*2
CBitmap bmp; //内存位图
CDC wdc; //设备环境
CDC* pDC; //指向桌面窗口的设备环境指针
……
static CWindowDC ddc(GetDesktopWindow()); //引用桌面窗口指针定义对象ddc
pDC=&ddc; //将指针pdc指向ddc
wdc.CreateCompatibleDC(pDC); //建立与ddc兼容的设备环境
bmp.CreateCompatibleBitmap(pDC,1024,768); //建立与ddc兼容的位图
wdc.SelectObject(&bmp); //选择bmp
……
wdc.BitBlt(0,0,1024,768,pDC,0,0,SRCCOPY); //把桌面图像复制到wdc的bmp中
这时虽以获取到了屏幕的信息,并将其复制到内存位图之中,但此时还不能直接将其发送出去,需要调用CBitmap 类的成员函数GetBitmapBits()来将图像信息从内存位图拷贝到缓存,并通过套接字的send()函数将缓存中存放的屏幕信息通过网络从现场主机发送到控制中心。
现场主机的屏幕信息在控制中心的再现,基本上是屏幕截取的逆过程:先建立一个同客户区相关的设备环境并建立一个与之兼容的设备环境,然后按位图格式在内存中创建一个与之兼容的内存位图。在从网络接收完一屏信息后,通过CBitmap的成员函数SetBitmapBits()把缓存中的屏幕信息按位图格式拷贝到内存位图,最后完成对内存位图的显示。其主要过程如下:
CDC* pDC=GetDC(); //引用用户窗口指针定义对象pDC
wdc.CreateCompatibleDC(pDC); //建立与pDC兼容的device context
bmp.CreateCompatibleBitmap(pDC,1024,768); //建立与pDC兼容的位图
wdc.SelectObject(&bmp);
……
iReadLen = recv(sock,buffer,60000,0); //从网络接收数据
for(i=0;i{
dot[pointer]=buffer[i];
pointer++;
if(pointer==1572864) //判断接收到的信息是否已满一屏
{
GetClientRect(&rect);
bmp.SetBitmapBits(1572864,(LPVOID)dot); //把内存数据复制到bmp中
//把bmp中图像复制到用户窗口中
pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&wdc,0,0,1024,768,SRCCOPY);
pointer=0; //接收完一屏后指针复位,准备接收下一屏
}
}
服务程序的自动加载及扩展
从功能上看,服务端程序只负责为远程客户提供服务,在全部运行期间根本不需要人为的外来干预,因此可以隐藏其界面并将其作成后台服务程序:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
……
cs.cx=200;
cs.cy=10;
cs.style=WS_POPUP;
cs.dwExStyle|=WS_EX_TOOLWINDOW;
return TRUE;
}
另外,由于现在计算机多具有通过Modem实现远程唤醒的功能,因此如能使服务程序具备自启动功能将实现远程现场主机的无人值守。自启动有多种方式:在Autoexec.bat、win.ini等文件中加入启动命令、在"启动"菜单里加入指向程序的快捷方式、修改注册表等。其中由于注册表通常被人为改动的机会要小的多,因此通过修改注册表实现自启动是一种比较安全的方法。本文采取的方法是:先通过API函数CopyFile()将服务程序复制到系统目录,然后对HKEY_LOCAL_MACHINE 的SoftwareMicrosoftWindowsCurrentVersionRun写入一个字符串键值,该键值的内容是服务程序在系统目录下的全路径:
DWORD type=REG_SZ;
DWORD size=MAX_PATH;
LPCTSTR Rgspath="Software\Microsoft\Windows\CurrentVersion\Run" ;
……
GetSystemDirectory(SysPath,size); //获取系统目录
GetModuleFileName(NULL,CurrentPath,size); //获取程序路径
FileCurrentName = CurrentPath;
FileNewName = lstrcat(SysPath,"\Surveillant.exe");
ret = CopyFile(FileCurrentName,FileNewName,TRUE); //拷贝程序到系统目录
……
//打开注册表
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,Rgspath,0,KEY_WRITE, &hKEY);
……
//写入注册表
ret=RegSetValueEx(hKEY,"Surveillant",NULL,type, FileNewName,size);
……
//关闭注册表
RegCloseKey(hKEY);
至于监控中心对现场主机的远程控制,则主要是通过向对方程序发送用以标识消息的数据并在远程主机接收完毕后用SendMessage()向指定窗口发送消息来完成的,可用CreateProcess();来启动现场主机的程序以响应消息。由于该部分技术亦可用来编写黑客软件,故本文在此不便作进一步的描述。
小结:
本文主要针对基于流式套接字的低层网络通讯模块和建立在该模块基础之上的屏幕截取和复原技术的设计、实现作了较为详细的介绍。本文所述监控系统在实际应用中取得了较好的效果。使工程技术人员能在控制中心及时了解到位于工程现场的计算机屏幕上的指示图表的动态显示,并根据监视结果作出及时的决策。本文所述程序在Windows 2000 Professional下,由Microsoft Visual C++编译通过。
CND8学院 VC教程 发布日期:2009年06月18日
将本文收藏到: | 收藏到本地 | 复制本文地址
--------------------------------------------------------------------------------
对远程计算机屏幕的捕捉和显示
前面部分的工作只是为整个监控系统提供一个低层的网络数据通讯的能力,也可以说是为现场主机和监控中心提供一个通信用信道。至于本文的中心议题--远程监视工作则需要分别在现场主机和监控中心中完成对屏幕的捕捉和信息的再现。屏幕的捕捉可以采取先获取桌面窗口指针并建立一个与之兼容的设备环境,然后创建一个与桌面窗口指针相兼容的内存位图并以位图的形式将屏幕图像拷贝到新创建的位图之中:
char dot[1572864]; //1024*768*2
CBitmap bmp; //内存位图
CDC wdc; //设备环境
CDC* pDC; //指向桌面窗口的设备环境指针
……
static CWindowDC ddc(GetDesktopWindow()); //引用桌面窗口指针定义对象ddc
pDC=&ddc; //将指针pdc指向ddc
wdc.CreateCompatibleDC(pDC); //建立与ddc兼容的设备环境
bmp.CreateCompatibleBitmap(pDC,1024,768); //建立与ddc兼容的位图
wdc.SelectObject(&bmp); //选择bmp
……
wdc.BitBlt(0,0,1024,768,pDC,0,0,SRCCOPY); //把桌面图像复制到wdc的bmp中
这时虽以获取到了屏幕的信息,并将其复制到内存位图之中,但此时还不能直接将其发送出去,需要调用CBitmap 类的成员函数GetBitmapBits()来将图像信息从内存位图拷贝到缓存,并通过套接字的send()函数将缓存中存放的屏幕信息通过网络从现场主机发送到控制中心。
现场主机的屏幕信息在控制中心的再现,基本上是屏幕截取的逆过程:先建立一个同客户区相关的设备环境并建立一个与之兼容的设备环境,然后按位图格式在内存中创建一个与之兼容的内存位图。在从网络接收完一屏信息后,通过CBitmap的成员函数SetBitmapBits()把缓存中的屏幕信息按位图格式拷贝到内存位图,最后完成对内存位图的显示。其主要过程如下:
CDC* pDC=GetDC(); //引用用户窗口指针定义对象pDC
wdc.CreateCompatibleDC(pDC); //建立与pDC兼容的device context
bmp.CreateCompatibleBitmap(pDC,1024,768); //建立与pDC兼容的位图
wdc.SelectObject(&bmp);
……
iReadLen = recv(sock,buffer,60000,0); //从网络接收数据
for(i=0;i{
dot[pointer]=buffer[i];
pointer++;
if(pointer==1572864) //判断接收到的信息是否已满一屏
{
GetClientRect(&rect);
bmp.SetBitmapBits(1572864,(LPVOID)dot); //把内存数据复制到bmp中
//把bmp中图像复制到用户窗口中
pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&wdc,0,0,1024,768,SRCCOPY);
pointer=0; //接收完一屏后指针复位,准备接收下一屏
}
}
服务程序的自动加载及扩展
从功能上看,服务端程序只负责为远程客户提供服务,在全部运行期间根本不需要人为的外来干预,因此可以隐藏其界面并将其作成后台服务程序:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
……
cs.cx=200;
cs.cy=10;
cs.style=WS_POPUP;
cs.dwExStyle|=WS_EX_TOOLWINDOW;
return TRUE;
}
另外,由于现在计算机多具有通过Modem实现远程唤醒的功能,因此如能使服务程序具备自启动功能将实现远程现场主机的无人值守。自启动有多种方式:在Autoexec.bat、win.ini等文件中加入启动命令、在"启动"菜单里加入指向程序的快捷方式、修改注册表等。其中由于注册表通常被人为改动的机会要小的多,因此通过修改注册表实现自启动是一种比较安全的方法。本文采取的方法是:先通过API函数CopyFile()将服务程序复制到系统目录,然后对HKEY_LOCAL_MACHINE 的SoftwareMicrosoftWindowsCurrentVersionRun写入一个字符串键值,该键值的内容是服务程序在系统目录下的全路径:
DWORD type=REG_SZ;
DWORD size=MAX_PATH;
LPCTSTR Rgspath="Software\Microsoft\Windows\CurrentVersion\Run" ;
……
GetSystemDirectory(SysPath,size); //获取系统目录
GetModuleFileName(NULL,CurrentPath,size); //获取程序路径
FileCurrentName = CurrentPath;
FileNewName = lstrcat(SysPath,"\Surveillant.exe");
ret = CopyFile(FileCurrentName,FileNewName,TRUE); //拷贝程序到系统目录
……
//打开注册表
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,Rgspath,0,KEY_WRITE, &hKEY);
……
//写入注册表
ret=RegSetValueEx(hKEY,"Surveillant",NULL,type, FileNewName,size);
……
//关闭注册表
RegCloseKey(hKEY);
至于监控中心对现场主机的远程控制,则主要是通过向对方程序发送用以标识消息的数据并在远程主机接收完毕后用SendMessage()向指定窗口发送消息来完成的,可用CreateProcess();来启动现场主机的程序以响应消息。由于该部分技术亦可用来编写黑客软件,故本文在此不便作进一步的描述。
小结:
本文主要针对基于流式套接字的低层网络通讯模块和建立在该模块基础之上的屏幕截取和复原技术的设计、实现作了较为详细的介绍。本文所述监控系统在实际应用中取得了较好的效果。使工程技术人员能在控制中心及时了解到位于工程现场的计算机屏幕上的指示图表的动态显示,并根据监视结果作出及时的决策。本文所述程序在Windows 2000 Professional下,由Microsoft Visual C++编译通过。