基于C#編寫(xiě)一個(gè)遠(yuǎn)程桌面應(yīng)用
背景
封閉環(huán)境無(wú)法拷貝外來(lái)的遠(yuǎn)程桌面軟件,所以就直接自己用C#寫(xiě)一個(gè)。
效果
說(shuō)明
本篇會(huì)給出完整的編程步驟,照著寫(xiě)就能擁有你自己的遠(yuǎn)程桌面應(yīng)用,直接可以運(yùn)行在局域網(wǎng)。
如果不想自己敲代碼,也可以選擇直接下載項(xiàng)目資源,解包后直接用VS2019打開(kāi)即可運(yùn)行或自行打包成exe
設(shè)計(jì)
遠(yuǎn)程桌面需要一個(gè)服務(wù)端,一個(gè)客戶端,各自是一個(gè)項(xiàng)目文件。
本項(xiàng)目中客戶端分享畫(huà)面(發(fā)送截屏數(shù)據(jù)流),服務(wù)端則是監(jiān)聽(tīng)并接收畫(huà)面,因此服務(wù)端需要兩個(gè)Form(窗體)。
項(xiàng)目源碼
客戶端UI
只需要一個(gè)Form1,布局如下:
具體組件和屬性設(shè)置如下:
- Label1,text改為IP即可;
- Label2,text改為Port即可;
- textbox1,名稱改為txtIP;
- textbox2,名稱改為txtPort,text改為80
- button1,text改為Connect,名稱改為btnConnect
- button2,text改為ShareScreen,名稱改為btnShare
客戶端源碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.Drawing.Imaging; using System.Runtime.Serialization.Formatters.Binary; namespace OriginalClient { public partial class Form1 : Form { private readonly TcpClient client = new TcpClient(); private NetworkStream mainStream; private int portNumber; private static Image GrabDesktop() { Rectangle bound = Screen.PrimaryScreen.Bounds; Bitmap screenshot = new Bitmap(bound.Width, bound.Height, PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(screenshot); graphics.CopyFromScreen(bound.X, bound.Y, 0, 0, bound.Size, CopyPixelOperation.SourceCopy); return screenshot; } private void SendDesktopImage() { BinaryFormatter binFormatter = new BinaryFormatter(); mainStream = client.GetStream(); binFormatter.Serialize(mainStream, GrabDesktop()); } public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { btnShare.Enabled = false; } private void btnConnect_Click(object sender, EventArgs e) { portNumber = int.Parse(txtPort.Text); try { client.Connect(txtIP.Text, portNumber); btnConnect.Text = "Connected"; MessageBox.Show("Connected"); btnConnect.Enabled = false; btnShare.Enabled = true; } catch (Exception) { MessageBox.Show("Failed to connect"); btnConnect.Text = "Not Connected"; } } private void btnShare_Click(object sender, EventArgs e) { if (btnShare.Text.StartsWith("Share")) { timer1.Start(); btnShare.Text = "Stop Sharing"; } else { timer1.Stop(); btnShare.Text = "Share My Screen"; } } private void timer1_Tick(object sender, EventArgs e) { SendDesktopImage(); } } }
服務(wù)端UI Form1
- textBox1,name設(shè)置為txtPort
- button1,name設(shè)置為btnListen
Form1代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace OriginalServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void btnListen_Click(object sender, EventArgs e) { new Form2(int.Parse(txtPort.Text)).Show(); btnListen.Enabled = false; } } }
Form2
源項(xiàng)目中追加一個(gè)窗體。
一個(gè)窗體里放一個(gè)imageBox,mode設(shè)置為zoom,dock設(shè)置為??俊?/p>
Form2源碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.Net; using System.Threading; using System.Runtime.Serialization.Formatters.Binary; namespace OriginalServer { public partial class Form2 : Form { private readonly int port; private TcpClient client; private TcpListener server; private NetworkStream mainStream; private readonly Thread Listening; private readonly Thread GetImage; public Form2(int Port) { port = Port; client = new TcpClient(); Listening = new Thread(StartListening); GetImage = new Thread(Receiveimage); InitializeComponent(); } private void StartListening() { while (!client.Connected) { server.Start(); client = server.AcceptTcpClient(); } GetImage.Start(); } private void StopListening() { server.Stop(); client = null; if (Listening.IsAlive) Listening.Abort(); if (GetImage.IsAlive) Listening.Abort(); } private void Receiveimage() { BinaryFormatter binFormatter = new BinaryFormatter(); while (client.Connected) { mainStream = client.GetStream(); pictureBox1.Image = (Image)binFormatter.Deserialize(mainStream); } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); server = new TcpListener(IPAddress.Any, port); Listening.Start(); } protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); StopListening(); } private void pictureBox1_Click(object sender, EventArgs e) { } private void Form2_Load(object sender, EventArgs e) { } } }
到此這篇關(guān)于基于C#編寫(xiě)一個(gè)遠(yuǎn)程桌面應(yīng)用的文章就介紹到這了,更多相關(guān)C#遠(yuǎn)程桌面內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中一個(gè)方法返回多個(gè)值的實(shí)現(xiàn)方法小結(jié)
通常一個(gè)方法只能返回一個(gè)值,但是如果在某些時(shí)候,我們想要返回多個(gè)值,例如某個(gè)方法將一個(gè)浮點(diǎn)數(shù)分割成一個(gè)整數(shù)和一個(gè)小數(shù)返回,因此本文給大家介紹了C#中一個(gè)方法返回多個(gè)值的實(shí)現(xiàn)方法及示例代碼,需要的朋友可以參考下2024-05-05C#使用Winform編寫(xiě)一個(gè)圖片預(yù)覽器管理
這篇文章主要為大家詳細(xì)介紹了C#如何使用Winform編寫(xiě)一個(gè)通用圖片預(yù)覽器管理,包含滾輪放大縮小,剪切,下一頁(yè),方向變化等,需要的可以參考下2024-02-02C#實(shí)現(xiàn)Windows服務(wù)測(cè)試與調(diào)試
這篇文章介紹了C#實(shí)現(xiàn)Windows服務(wù)測(cè)試與調(diào)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02C#由當(dāng)前日期計(jì)算相應(yīng)的周一和周日的實(shí)例代碼
這篇文章介紹了C#由當(dāng)前日期計(jì)算相應(yīng)的周一和周日的實(shí)例代碼,有需要的朋友可以參考一下2013-09-09Unity實(shí)現(xiàn)移動(dòng)端手勢(shì)解鎖功能
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)移動(dòng)端手勢(shì)解鎖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07