【背景】
封闭环境无法拷贝外来的远程桌面软件,所以就直接自己用C#写一个。
【效果】
【说明】
本篇会给出完整的编程步骤,照着写就能拥有你自己的远程桌面应用,直接可以运行在局域网。
如果不想自己敲代码,也可以选择直接下载项目资源,解包后直接用VS2019打开即可运行或自行打包成exe:
https://download.csdn.net/download/weixin_41697242/88350078
【设计】
远程桌面需要一个服务端,一个客户端,各自是一个项目文件。
本项目中客户端分享画面(发送截屏数据流),服务端则是监听并接收画面,因此服务端需要两个Form(窗体)。
【项目源码】
客户端UI
只需要一个Form1,布局如下:
具体组件和属性设置如下:
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();
}
}
}
服务端UI
Form1
textBox1,name设置为txtPort
button1,name设置为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
源项目中追加一个窗体。
一个窗体里放一个imageBox,mode设置为zoom,dock设置为停靠。
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)
{
}
}
}