C# 实现远程控制软件的关键技术

一、服务器端多线程Socket技术

用TcpListener进行侦听,接受客户端连接,有客户端连进来后开启处理线程处理数据,代码如下: < xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />

using System;

using System.Threading;

using System.Net.Sockets;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void < xmlnamespace prefix ="st1" ns ="urn:schemas-microsoft-com:office:smarttags" />Main(string[] args)

        {

            // 在8888端口侦听

            TcpListener serverSocket = new TcpListener(8888);

            TcpClient clientSocket = default(TcpClient);

            int counter = 0;

 

            serverSocket.Start();

            Console.WriteLine(" >> " + "Server Started");

 

            counter = 0;

            while (true)

            {

                counter += 1;

                // 接受客户端连接

                clientSocket = serverSocket.AcceptTcpClient();

                Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");

                // 启动客户端处理代码

                handleClinet client = new handleClinet();

                client.startClient(clientSocket, Convert.ToString(counter));

            }

 

            clientSocket.Close();

            serverSocket.Stop();

            Console.WriteLine(" >> " + "exit");

            Console.ReadLine();

        }

    }

 

    // 客户端连接处理类

    public class handleClinet

    {

        TcpClient clientSocket;

        string clNo;

 

        public void startClient(TcpClient inClientSocket, string clineNo)

        {

            this.clientSocket = inClientSocket;

            this.clNo = clineNo;

            // 开启处理线程

            Thread ctThread = new Thread(doChat);

            ctThread.Start();

        }

 

        private void doChat()

        {

            int requestCount = 0;

            byte[] bytesFrom = new byte[10025];

            string dataFromClient = null;

            Byte[] sendBytes = null;

            string serverResponse = null;

            string rCount = null;

            requestCount = 0;

 

            while ((true))

            {

                try

                {

                    requestCount = requestCount + 1;

 

                    // 读取内容

                    NetworkStream networkStream = clientSocket.GetStream();

                    networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);

                    dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);

                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                    Console.WriteLine(" >> " + "From client-" + clNo + dataFromClient);

 

                    rCount = Convert.ToString(requestCount);

                    serverResponse = "Server to clinet(" + clNo + ") " + rCount;

                    sendBytes = Encoding.ASCII.GetBytes(serverResponse);

                    networkStream.Write(sendBytes, 0, sendBytes.Length);

                    networkStream.Flush();

                    Console.WriteLine(" >> " + serverResponse);

                }

                catch (Exception ex)

                {

                    Console.WriteLine(" >> " + ex.ToString());

                }

            }

        }

    }

}

二、鼠标控制技术 

鼠标的控制用到了 mouse_event 这个API函数,参考代码如下:

using System;

using System.Threading;

using System.Runtime.InteropServices;

using System.Windows.Forms;

 

namespace MouseControl

{

    class MouseControl

    {

        ///

        /// 鼠标控制参数

        ///

        const int MOUSEEVENTF_LEFTDOWN = 0x2;

        const int MOUSEEVENTF_LEFTUP = 0x4;

        const int MOUSEEVENTF_MIDDLEDOWN = 0x20;

        const int MOUSEEVENTF_MIDDLEUP = 0x40;

        const int MOUSEEVENTF_MOVE = 0x1;

        const int MOUSEEVENTF_ABSOLUTE = 0x8000;

        const int MOUSEEVENTF_RIGHTDOWN = 0x8;

        const int MOUSEEVENTF_RIGHTUP = 0x10;

       

        ///

        /// 鼠标的位置

        ///

        public struct PONITAPI

        {

            public int x, y;

        }

 

        [DllImport("user32.dll")]

        public static extern int GetCursorPos(ref PONITAPI p);

 

        [DllImport("user32.dll")]

        public static extern int SetCursorPos(int x, int y);

 

        [DllImport("user32.dll")]

        public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

 

        [STAThread]

        static void Main()

        {

            PONITAPI p = new PONITAPI();

            GetCursorPos(ref p);

            Console.WriteLine("鼠标现在的位置X:{0}, Y:{1}", p.x, p.y);

            Console.WriteLine("Sleep 1 sec...");

            Thread.Sleep(1000);

 

            p.x = (new Random()).Next(Screen.PrimaryScreen.Bounds.Width);

            p.y = (new Random()).Next(Screen.PrimaryScreen.Bounds.Height);

            Console.WriteLine("把鼠标移动到X:{0}, Y:{1}", p.x, p.y);

            SetCursorPos(p.x, p.y);

            GetCursorPos(ref p);

            Console.WriteLine("鼠标现在的位置X:{0}, Y:{1}", p.x, p.y);

            Console.WriteLine("Sleep 1 sec...");

            Thread.Sleep(1000);

 

            Console.WriteLine("在X:{0}, Y:{1} 按下鼠标左键", p.x, p.y);

            mouse_event(MOUSEEVENTF_LEFTDOWN, p.x, p.y, 0, 0);

            Console.WriteLine("Sleep 1 sec...");

            Thread.Sleep(1000);

 

            Console.WriteLine("在X:{0}, Y:{1} 释放鼠标左键", p.x, p.y);

            mouse_event(MOUSEEVENTF_LEFTUP, p.x, p.y, 0, 0);

            Console.WriteLine("程序结束,按任意键退出....");

            Console.ReadKey();

        }

    }

}

三、键盘控制技术

键盘的控制用到了 keybd_event 这个API函数,参考代码段如下:

[DllImport("user32.dll", EntryPoint = "keybd_event")]

public static extern void keybd_event(

     byte bVk,

     byte bScan,

     int dwFlags,

     int dwExtraInfo

);

 

keybd_event((byte)Keys.F11, 0, 0, 0);//按下F11

keybd_event((byte)Keys.F11, 0, 0x2, 0);   //弹起F11

四、运行程序
4.1

public static void RunProcess(string name, string command)

{

     Process myProcess = new Process();

 

     myProcess.StartInfo.FileName = name;

     myProcess.StartInfo.Arguments = command;

     myProcess.Start();

     return;

}

4.2 运行CMD并取得命令执行结果

public static string RunCmd(string command)//运行一个cmd命令

{

     Process p = new Process();

 

     //p.StartInfo.WorkingDirectory = "c:\\";    // 工作目录

     p.StartInfo.FileName = "cmd.exe";           // 程序名

     p.StartInfo.Arguments = "/c " + command;    // 执行参数

     p.StartInfo.UseShellExecute = false;        // 关闭Shell的使用

     p.StartInfo.RedirectStandardInput = true;   // 重定向标准输入

     p.StartInfo.RedirectStandardOutput = true;  // 重定向标准输出

     p.StartInfo.RedirectStandardError = true;   // 重定向错误输出

     p.StartInfo.CreateNoWindow = true;          // 设置不显示窗口

 

     p.Start();   //启动

 

     //p.StandardInput.WriteLine(command);       // 也可以用这种方式输入要执行的命令

     //p.StandardInput.WriteLine("exit");        // 不过要记得加上Exit,要不然下一行执行的时候会出错

             

     return p.StandardOutput.ReadToEnd();        // 从输出流取得命令执行结果

}

五、取得屏幕拷贝

public Image GetScreen( )

{

     //this.Hide();

     IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);

     //创建显示器的DC

     Graphics g1 = Graphics.FromHdc(dc1);

     //由一个指定设备的句柄创建一个新的Graphics对象

     Bitmap MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);

     //根据屏幕大小创建一个与之相同大小的Bitmap对象

     Graphics g2 = Graphics.FromImage(MyImage);

     //获得屏幕的句柄

     IntPtr dc3 = g1.GetHdc();

     //获得位图的句柄

     IntPtr dc2 = g2.GetHdc();

     //把当前屏幕捕获到位图对象中

     BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);

     //把当前屏幕拷贝到位图中

     g1.ReleaseHdc(dc3);

     //释放屏幕句柄

     g2.ReleaseHdc(dc2);

     //释放位图句柄

     return MyImage;

     //this.Show();

}

取得屏幕拷贝的代码直接用了bitmap格式,性能不高,在实际使用中应该考虑进行压缩。

 

posted @ 2021-03-30 06:18  學海無邊  阅读(1035)  评论(0编辑  收藏  举报