15

我希望在 C# 中创建一个非常基本的屏幕共享应用程序。无需遥控器。我只希望用户能够将他们的屏幕广播到网络服务器。

我应该如何实现这个?(任何指向正确方向的指针都将不胜感激)。

它不需要高 FPS。甚至更新 5 秒左右就足够了。你认为每 5 秒上传一次屏幕截图到我的网络服务器就足够了吗?

4

5 回答 5

18

我之前在博客上写过远程屏幕共享软件是如何工作的,它并不特定于 C#,但它提供了对该主题的良好基本理解。在那篇文章中还链接了远程帧缓冲区规范,您可能还想阅读它。

基本上你会想要截取屏幕截图,你可以传输这些屏幕截图并将它们显示在另一边。您可以保留最后一张截图,并以块为单位比较截图,看看您需要发送哪些截图块。您通常会在发送数据之前进行某种压缩。

要进行远程控制,您可以跟踪鼠标移动并将其传输并在另一端设置指针位置。关于击键也是如此。

就 C# 中的压缩而言,您可以简单地使用JpegBitmapEncoder来创建具有所需质量的 Jpeg 压缩屏幕截图。

JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.QualityLevel = 40; 

要比较文件块,您可能最好在旧块和新块上创建一个哈希,然后检查它们是否相同。您可以为此使用任何您想要的散列算法。

于 2010-07-20T23:58:37.240 回答
3

这是截取屏幕截图的代码,未压缩为位图:

    public static Bitmap TakeScreenshot() {
        Rectangle totalSize = Rectangle.Empty;

        foreach (Screen s in Screen.AllScreens)
            totalSize = Rectangle.Union(totalSize, s.Bounds);

        Bitmap screenShotBMP = new Bitmap(totalSize.Width, totalSize.Height, PixelFormat.
            Format32bppArgb);

        Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);

        screenShotGraphics.CopyFromScreen(totalSize.X, totalSize.Y, 0, 0, totalSize.Size,
            CopyPixelOperation.SourceCopy);

        screenShotGraphics.Dispose();

        return screenShotBMP;
    }

现在只需压缩它并通过网络发送它,你就完成了。

此代码将多屏幕设置中的所有屏幕组合成一个图像。根据需要进行调整。

于 2010-07-21T00:09:09.790 回答
2

我想做类似的事情,我刚刚在 CodeProject 上找到了这个。我想这会对你有所帮助。

http://www.codeproject.com/Articles/371955/Motion-JPEG-Streaming-Server

于 2013-01-21T15:55:04.360 回答
2

好吧,它可以像截屏、压缩它们然后通过网络发送一样简单。但是,现有的软件已经可以做到这一点。这是为了练习吗?

于 2010-07-20T23:59:17.573 回答
1

共享/复制屏幕的关键参与者是一个名为:RPDViewer 的 COM 组件 在此处输入图像描述

将该 com 组件添加到您的窗口表单和引用中。. 并将此代码添加到您的表单加载中,您将在表单中复制屏幕:

在此处输入图像描述

using RDPCOMAPILib;
using System;
using System.Windows.Forms;

namespace screenSharingAttempt
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        RDPSession x = new RDPSession(); 
        private void Incoming(object Guest)
        {
            IRDPSRAPIAttendee MyGuest = (IRDPSRAPIAttendee)Guest; 
            MyGuest.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_INTERACTIVE;
        }


        //access to COM/firewall will prompt 
        private void button1_Click(object sender, EventArgs e)
        {
            x.OnAttendeeConnected += Incoming;
            x.Open();
        }

        //connect
        private void button2_Click(object sender, EventArgs e)
        {
            IRDPSRAPIInvitation Invitation = x.Invitations.CreateInvitation("Trial", "MyGroup", "", 10);
            textBox1.Text = Invitation.ConnectionString;
        }

        //Share screen

        private void button4_Click(object sender, EventArgs e)
        {
            string Invitation = textBox1.Text;// "";// Interaction.InputBox("Insert Invitation ConnectionString", "Attention");
            axRDPViewer1.Connect(Invitation, "User1", "");
        }


        //stop sharing
        private void button5_Click(object sender, EventArgs e)
        {
            axRDPViewer1.Disconnect();
        }
    }
}
于 2017-04-14T20:51:46.663 回答