- 浏览: 18984 次
最新评论
用C#做远程监控程序
2009年12月05日
最近在做的C/S程序要加入远程监控的功能,于是去搜索怎么用C#来做这个功能,然后看了一些资料。最后有了一点点思路,远程监控其实就是总结出来一个大概的流程:
首先,实时的将被监控端的屏幕截图并发送到监控端。
然后,把本地的鼠标和键盘事件的值传到远程,然后再远程模拟出来。
有了想法那就开始做吧,先做第一步
一、屏幕截图并发送到服务器端
先要让客户端连接到服务器端,用的是TCP连接
程序代码
socket = new TcpClient(serveraddress, serverport);
ns = clientsocket.GetStream();
然后启动一个线程来截图,截图的代码可以看 C#截图代码。 可以在连接服务器之后就启动这个线程,我现在的是让服务器发一个命令到客户端,然后客户端再用一个线程来不断侦听服务器发来的消息,如果收到截图的命令,那么再启动截图。
截下的图片保存在内存流中,要注意的一点是,在调用了SAVE方法之后要重新设置流的位置为0
程序代码
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
//将图片写入流,但是流的当前位置会改变(在流的末端)
ms.Position = 0;
//在调用ms.Read方法之前重设流的当前位置
截图已经完成,接下来就是要传送图片了。一次发送完整个图片是不好的,所以我们要把它分块传输。我设置了1024字节的缓冲区,循环发送数据。
程序代码
while (sendCount
程序代码
Byte[] buffer = new Byte[1024];
int count = socket.Receive(buffer);
while (count != 0)
{
if (count == 4)
break;
try
{
ms.Write(buffer, 0, count); //写入内存流
buffer = new Byte[1024];
Byte[] tempbuff = new Byte[1024];
count = socket.Receive(tempbuff);
buffer = tempbuff;
}
catch (Exception ex)
{ }
}
将内存流再转换为图片,然后显示出来,我用的是PictureBox,下面是显示图片的代码
程序代码
Image image = Image.FromStream(ms);
picScreen.Image = image;
ms.Flush();
ms = new MemoryStream();
到这里基本上就实现了第一步的功能,可以看到客户端的桌面了,小小的高兴一下~~~~不过还有一些问题,显示的速度慢,正在想办法解决这个问题。图片应该要压缩下,也许不传整张图片也是一个比较好的办法。
远程监控的第一步完成了,已经可以看见对方的桌面了。现在开始实现第二步,即远程控制部分。把本地的鼠标事件传到远程,在远程模拟鼠标事件,这部分参考了一些网上的源码。
要把鼠标类型(单击、双击、移动)和坐标转换成二进制然后发送到远程,这里定义一个鼠标事件的类,里面还需要有一个将接收到的字节转换成类型和坐标的函数,部分代码如下
程序代码
public class MouseHook
{
private Byte[] mouseType;
private Byte[] x;
private Byte[] y;
public MouseHook(MouseEventType mouseType, int x, int y)
{
this.mouseType = BitConverter.GetBytes((int)mouseType);
this.x = BitConverter.GetBytes(x);
this.y = BitConverter.GetBytes(y);
}
}
然后再定义鼠标类型的枚举,好区别不同的鼠标类型。
程序代码
public enum MouseEventType
{
MouseMove,
....
MouseClick,
}
在被控端要引入WIN32的API以模拟鼠标事件,用到的是user32.dll
程序代码
// 模拟鼠标事件的函数模型
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern void mouse_event(int flags, int dx, int dy, int dwData, int dwExtraInfo);
/// 设置光标到指定位置的函数模型
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetCursorPos(int X, int Y);
在服务器端显示图片用的是Picturebox控件,为了要实现控制,得在Picturebox添加几个事件MouseMove,MouseUp,MouseClick等事件,在这些事件触发的时候发送鼠标的类型和坐标。
这是其中的一个事件,鼠标单击事件
程序代码
private void picScreen_MouseClick(object sender, MouseEventArgs e)
{
MouseHook MouseEvent = new MouseHook(MouseEventType.MouseClick, e.X, e.Y);
ns.Write(MouseEvent.ToBytes(),0,12);
}
成功发送出去之后就可以在另一端接收了,接收到之后再转换为坐标,判断接收到的类型,模拟出相应的事件。需要定义委托来模拟鼠标事件。
程序代码
public delegate void DoMouseButtons(MouseEventFlag flags, int dx, int dy, int dwData, int dwExtraInfo);
private event DoMouseButtons MouseButton;
直接像下面这样使用就可以了
程序代码
MouseButton(MouseEventFlag.LeftDown, MEvent.X, MEvent.Y, 0, 0);
接收的代码我就懒得写出来了,其实就是和接收图片一样的。
到这里基本上控件的代码也完成了,测试了一下,可以控制了,但是会一卡一卡的,反应有点慢。写得有点乱,远程监控大概的流程就是这样。完成的代码还是很粗糙,也还有一些问题,需要做一些改进。
前面也说过,要实现键盘控制就是要在服务器端响应键盘事件,传送到客户端,客户端再模拟出来。
为了避免鼠标和键盘的事件传送的时候发生冲突,需要在客户端再连接一个不同的端口,服务端启动的时候监听这两个端口。具
体的代码可以参考第一篇里所写的。
定义一个键盘事件类型的枚举,主要就是按键按下和释放。
程序代码
public enum KeyBoardType
{
Key_Down,
Key_Up,
Key_Press,
}
public enum KeyBoard
{
KEYEVENTF_KEYDOWN = 0x0001,
KEYEVENTF_KEYUP = 0x0002
}
为了发送键代码,需要一个转换键盘事件的类,将键盘事件类型和键代码转为二进制以方便网络传输,形式和鼠标事件是类似的
,部分代码如下:
程序代码
public class KeyBoardHook
{
private Byte[] keyType;
private Byte[] code;
public KeyBoardHook(KeyBoardType type, Keys keyCode)
{
keyType = BitConverter.GetBytes((int)type);
code = BitConverter.GetBytes((int)keyCode);
}
public KeyBoardHook(Byte[] Content)
{
keyType = new byte[4];
code = new byte[4];
for (int i = 0; i = 0 && i = 4 && i =
break;
}
}
}
写好了键盘事件的类,然后就要将键盘代码发送出去,要在KeyDown事件中处理。因为我用的是Picturebox显示客户端屏幕,就得触发Picturebox的KeyDown事件。在Picturebox的属性里是没有这个事件的,需要自己添加。在KeyDown事件里发送键盘代码。
程序代码
this.picScreen.KeyDown += new System.Windows.Forms.KeyEventHandler(picScreen_KeyDown);
private void picScreen_KeyDown(object sender, KeyEventArgs e)
{
KeyBoardHook keyboard = new KeyBoardHook(KeyBoardType.Key_Down, e.KeyCode);
e.SuppressKeyPress = true;
nskb.Write(keyboard.ToBytes(), 0,;
}
然后再用同样的方法添加Picturebox的KeyUp事件,里面写上类似的代码,不同的是KeyBoardType为Key_Up。
接下来就在客户端写接收的方法了,新开一个进程处理
程序代码
receive2 = new Thread(new ThreadStart(ReceiveKey));
receive2.Start();
要模拟键盘事件,先引入DLL
程序代码
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "keybd_event")]
public static extern void keybd_event(
byte bVk,
byte bScan,
int dwFlags,
int dwExtraInfo
);
模拟键盘按下按键
程序代码
public static void KeyDown(System.Windows.Forms.Keys keyCode)
{
keybd_event((byte)keyCode, 0, (int)KeyBoard.KEYEVENTF_KEYDOWN, 0);
}
然后在函数里处理模拟键盘的事件
程序代码
public void ReceiveKey()
{
bool keepalive = true;
while (keepalive)
{
byte[] recKeyboard = new byte[1024];
nskb.Read(recKeyboard, 0, recKeyboard.Length);
KeyBoardHook key = new KeyBoardHook(recKeyboard);
switch (key.KeyType)
{
case KeyBoardType.Key_Down:
KeyDown(key.Code);
break;
case KeyBoardType.Key_Up:
KeyUp(key.Code);
break;
}
}
}
到这里这个程序就已经基本上做完了,测试了一下,键盘模拟成功。整体的来看就是截图的发送的太慢,监控屏幕的时候有点卡
。写这些东西只是记录一下我学习C#网络编程的一些心得,写得有点乱。我的.NET交流群号:30954402。有兴趣的来交流一下学习C#.NET的一些心得。
发表评论
-
Java.lang.ThreadLocal类
2012-01-20 09:02 416Java.lang.ThreadLocal类 2010 ... -
.net 线程概述
2012-01-20 09:02 500.net 线程概述 2011年06月23日 概论 多线 ... -
Borland 基础与应用开发课程认证试题整理集
2012-01-20 09:02 603Borland 基础与应用开发课程认证试题整理集 2010年 ... -
windows x64 vista以上系统代码完整性校验分析
2012-01-20 09:02 1644windows x64 vista以上系统代码完整性校验分析 ... -
C1X系列: 多线程(N1494)
2012-01-20 09:02 715C1X系列: 多线程(N1494) 2010年08月03日 ... -
VBS整人代码 很多 测试把我给整安逸了
2012-01-19 14:06 2254VBS整人代码 很多 测试把我给整安逸了 2010年08月2 ... -
利用VBS让QQ永远在线
2012-01-19 14:06 557利用VBS让QQ永远在线 201 ... -
VBS Runas 自动明文的输入密码
2012-01-19 14:06 698VBS Runas 自动明文的输入密码 2010年06月23 ... -
VBS运用之妙用SendKeys
2012-01-19 14:06 905VBS运用之妙用SendKeys 2010年11月12日 ... -
了解VBE!VBS教程!
2012-01-19 14:06 684了解VBE!VBS教程! 2011年09 ... -
使用Windbg排除蓝屏故障(已发表)
2012-01-17 03:56 634使用Windbg排除蓝屏故障(已发表) 2011年09月28 ... -
系统的一些解决方法
2012-01-17 03:56 604系统的一些解决方法 20 ... -
2011-11-1
2012-01-17 03:56 4662011-11-1 2011年11月01日 第一篇:一 ... -
Linux下FrameBuffer直接写屏
2012-01-17 03:56 982Linux下FrameBuffer直接写屏 2011年09月 ... -
exe文件不能运行的解决方法
2012-01-17 03:56 1034exe文件不能运行的解决 ... -
Socket基础
2012-01-16 02:45 542Socket基础 2010年04月02日 Socket基 ... -
一个类似ifconfig功能的程序代码--C语言(ZZ)
2012-01-16 02:44 952一个类似ifconfig功能的程序代码--C语言(ZZ) 2 ... -
tcp简单实现C/S模式程序,测试成功
2012-01-16 02:44 1094tcp简单实现C/S模式程序,测试成功 2010年03月25 ... -
简单的C#Socket编程
2012-01-16 02:44 552简单的C#Socket编程 2009年06月23日 us ...
相关推荐
以前的网上看到的一个用C#开发的可以进行远程桌面监控的程序,也可以实现远程屏幕控制,含受控端、监控端、远程监控端和代理类。
C#远程监控源代码C#远程监控源代码C#远程监控源代码
C#利用.net remoting技术开发的远程监控程序,可以实现类似远程桌面的功能。
C#远程屏幕监控 此代码适合写远程控制的朋友, 已完成的功能远程屏幕观看,鼠标强制控制 ((鼠标点击事件和键盘事件)本人有原码,要的下面有我的QQ可以联系我,我发给你),由于最近接了项目所以没做了. 话为...
C#编写的远程监控程序,可以秘密潜入对方电脑,进行文件,注册表等查看,以及修改,我还没有研究清楚所有功能,但是这是一套完整的源码,可以很方便的提供学习
C#实现的远程监控小程序,包含代理类、视频端、监控端、受控端四部分。
C#利用.net remoting技术开发的远程监控程序,可以实现类似远程桌面的功能
屏幕监控程序源代码,开发环境:visual studio 2008,语言:C#,网络:基于udp协议传输数据,有优化算法,程序代码会自动检测被监控端屏幕无变化部分不进行重复数据传输。 关键算法:整屏幕截图,这个很简单,当然也是从...
C#客户端和服务器端源代码及程序,客户端和服务器端源代码及程序(C#)
C# 远程控制
vb的远程监控程序(全源码提供)vb的远程监控程序(全源码提供)vb的远程监控程序(全源码提供)vb的远程监控程序(全源码提供)
C# 一对多远程屏幕监控 可用于多终端切屏投影,一个管理端,一个客户端,需要在客户端设置好管理端IP地址,客户端上线下线管理端自动感知,管理端可随意切换要查看的屏幕,项目采用VS2012编写。 可用作学习屏幕录像...
近期公司要让写个远程监控进程的内存和cpu百分比,自己写了个程序,主要功能就是监控多台机器指定进程的cpu占比和内存消耗
使用C#开发的远程桌面连接程序 支持多个桌面的同时连接 很有用啊
c#远程监控源代码。编译通过。完整工程。
用C#写的远程控制代码,包括客户端及服务器端全部代码。 功能描述: 文件:更新ip,端口映射,配置服务器,卸载服务器,退出 设置:系统设置,更新皮肤,添加到桌面,添加快捷方式,添加到开始程序 查看:工具栏,ip...
c# 远程监视,操作 读取 PLC源码
基于C#的固定设备物联网小程序,采用OneNet平台进行通信,实测通过,分享出来,大家一起交流
C#远程控制服务器端和客户端源代码 需要改了IP地址就能测试
C#远程控制桌面源码 源码描述 用C#写的远程控制代码,包括客户端及服务器端全部代码。 功能描述: 文件:更新ip,端口映射,配置服务器,卸载服务器,退出 设置:系统设置,更新皮肤,添加到桌面,添加快捷方式,添加...