【C#】【源码】直接可用的远程桌面应用

news2024/12/23 18:43:54

【背景】

封闭环境无法拷贝外来的远程桌面软件,所以就直接自己用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)
        {

        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018575.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 周赛上分之旅 #45 精妙的 O(lgn) 扫描算法与树上 DP 问题

⭐️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度…

python 二手车数据分析以及价格预测

二手车交易信息爬取、数据分析以及交易价格预测 引言一、数据爬取1.1 解析数据1.2 编写代码爬1.2.1 获取详细信息1.2.2 数据处理 二、数据分析2.1 统计分析2.2 可视化分析 三、价格预测3.1 价格趋势分析(特征分析)3.2 价格预测 引言 本文着眼于车辆信息,结合当下较…

6. 装饰器

UML 聚合(Aggregation)关系&#xff1a;大雁和雁群&#xff0c;上图中空心菱形箭头表示聚合关系组合(Composition)关系&#xff1a;大雁和翅膀 &#xff0c;实心菱形箭头表示组合(Composition)关系 测试代码 #include <iostream> #include <stdio.h> #include &l…

IDEA2023.2.1中创建第一个Tomcat的web项目

首先&#xff0c;创建一个普通的java项目。点击【file】-【new】-【project】 创建一个TomcatDemo项目 创建如下图 添加web部门。点击【file】-【project structure】 选择【modules】-选中项目“TomcatDemo” 点击项目名上的加号【】&#xff0c;添加【web】模块 我们就会发现…

【微信小程序】文章设置

设置基本字体样式&#xff1a;行高、首行缩进 font-size: 32rpx;line-height: 1.6em;text-indent: 2em;padding: 20rpx 0;border-bottom: 1px dashed var(--themColor); 两端对齐 text-align: justify; css文字两行或者几行显示省略号 css文字两行或者几行显示省略号_css…

FPGA project : dht11 温湿度传感器

没有硬件&#xff0c;过几天上板测试。 module dht11(input wire sys_clk ,input wire sys_rst_n ,input wire key ,inout wire dht11 ,output wire ds ,output wire …

72、Spring Data JPA 的 Specification 动态查询

Specification&#xff1a;规范、规格 ★ Specification查询 它也是Spring Data提供的查询——是对JPA本身 Criteria 动态查询 的包装。▲ 为何要有动态查询 页面上常常会让用户添加不同的查询条件&#xff0c;程序就需要根据用户输入的条件&#xff0c;动态地组合不同的查询…

外星人入侵游戏-(创新版)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

不同类型程序的句柄研究

先做一个winform程序&#xff1b;随便放几个控件&#xff1b; 用窗口句柄查看工具看一下&#xff1b;form和上面的每个控件都有一个句柄&#xff1b; 然后看一下记事本&#xff1b;记事本一共包含三个控件&#xff0c;各自有句柄&#xff1b; 这工具的使用是把右下角图标拖到要…

服务器迁移:无缝过渡指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

基于SSM+Vue的高校实验室管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

线程的方法(未完成)

线程的方法 1、sleep(long millis) 线程休眠&#xff1a;让执行的线程暂停一段时间&#xff0c;进入计时等待状态。 static void sleep(long millis):调用此方法后&#xff0c;当前线程放弃 CPU 资源&#xff0c;在指定的时间内&#xff0c;sleep 所在的线程不会获得可运行的机…

如何使用Java语言判断出geek是字符串参数类型,888是整数参数类型,[hello,world]是数组参数类型,2.5是双精度浮点数类型?

如何使用Java语言判断出geek是字符串参数类型&#xff0c;888是整数参数类型&#xff0c;[hello,world]是数组参数类型&#xff0c;2.5是双精度浮点数类型&#xff1f; Java是一种静态类型的编程语言&#xff0c;这意味着我们需要在编译时为变量指定具体的类型。但是&#xff…

web应用及微信小程序版本更新检测方案实践

背景&#xff1a; 随着项目体量越来越大&#xff0c;用户群体越来越多&#xff0c;用户的声音也越来越明显&#xff1b;关于应用发版之后用户无感知&#xff0c;导致用户用的是仍然还是老版本功能&#xff0c;除非用户手动刷新&#xff0c;否则体验不到最新的功能&#xff1b;这…

ICCV 2023 | MPI-Flow:从单视角构建的多平面图像中学习光流

ICCV 2023 | MPI-Flow&#xff1a;从单视角构建的多平面图像中学习光流 引言&#xff1a;主要贡献&#xff1a;Motivation&#xff1a;算法细节&#xff1a;Optical Flow Data GenerationIndependent Object MotionsDepth-Aware Inpainting 实验结果&#xff1a; 来源&#xff…

QT:使用分组框、单选按钮、普通按钮、标签、行编辑器、垂直分布、水平分布做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QRadioButton> //单选按钮 #include <QGroupBox> //分组框 #include <QHBoxLayout> //水平布局 #include <QVBoxLayout> //垂直布局 #include <QPushButton>…

MFC主框架和视类PreCreateWindow()函数学习

在VC生成的单文档应用程序中&#xff0c;主框架类和视类均具有PreCreateWindow函数&#xff1b; 从名字可知&#xff0c;可在此函数中添加一些代码&#xff0c;来控制窗口显示后的效果&#xff1b; 并且它有注释说明&#xff0c; Modify the Window class or styles here by…

RHCSA 重定向、vim练习题

1.重定向练习题 (1)新建一个文件redirect.txt&#xff0c;并在其中写入20210804RHCSA,保存并退出 先输入命令 [rootlocalhost ~]# vim redirect.txt进入vim编辑器后&#xff0c;按快捷键“i”进入编辑模式&#xff0c;再写入数据&#xff0c;写完之后按“esc"键退出编辑…

python 采用selenium+cookies 获取登录后的网页

百度网页由于需要登陆手机短信验证。比较麻烦 这里我采用先人工登录百度账号&#xff0c;然后将百度账号的相关cookies保存下来 然后采用selenium动态登录网页 整体代码如下 from selenium import webdriverimport timeoptions webdriver.ChromeOptions()options.add_argu…

LLM 08-分布式训练

LLM 08-分布式训练 8.1 为什么分布式训练越来越流行 近年来&#xff0c;深度学习被广泛应用到各个领域&#xff0c;包括计算机视觉、语言理解、语音识别、广告推荐等。在这些不同的领域中&#xff0c;一个共同的特点就是模型规模越来越大&#xff0c;比如 GPT-3 模型的参数量达…