C# 實現遠程控制軟件的關鍵技術


C# 實現遠程控制軟件的關鍵技術

編者:wyl

一、服務器端多線程Socket技術

TcpListener進行偵聽,接受客戶端連接,有客戶端連進來后開啟處理線程處理數據,代碼如下:

using System;
using System.Threading;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void 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
    {
        /// <summary>
        /// 鼠標控制參數
        /// </summary>
        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;
        
        /// <summary>
        /// 鼠標的位置
        /// </summary>
        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();        // 從輸出流取得命令執行結果
}

五、取得屏幕拷貝

取得屏幕拷貝的代碼直接用了bitmap格式,性能不高,在實際使用中應該考慮進行壓縮。

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM