C# Winfrom 常用功能整合-2

目录

Winfrom 启动一个外部exe文件,并传入参数

Winform ListBox用法

HTTP下载文件(推荐)

Winform HTTP下载并显示进度

Winform HTTP下载文件

Winform 跨线程访问UI组件

Winform 改变文字的颜色和大小


Winfrom 启动一个外部exe文件,并传入参数

在我们常用的一些软件中,经常有些软件,双击之后根本打不开,这是因为启动时做了限制,我们需要传入一些参数才能打开,在工作中,这个需求也可以用在软件的自动更新上,在Unity里,有XLua,ILruntime 等框架进行热更新,在Winform中,由于Windows的机制,打开软件后,不能做文件替换工作,我们可以利用一个软件启动器,更新本地软件的文件,然后再启动软件,就达到了自动更新的目的,当然,软件本地也不能直接双击打开。

新建一个winform 项目,界面如下,用来做一个软件启动器

只需要添加一个按钮,给按钮添加点击事件,代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 启动器
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string path = "E:\\CSharp Project\\Test\\Test\\bin\\Debug\\Test.exe";
            string[] parameter = {"启动器参数1", "启动器参数2", "启动器参数3", "启动器参数4" };
            bool startResult = StartProcess(path, parameter);
            if (startResult)
                System.Environment.Exit(0);
        }

        /// <summary>
        /// 启动一个软件,并传入参数
        /// </summary>
        /// <param name="runFilePath"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool StartProcess(string runFilePath, params string[] args)
        {
            string s = "";
            foreach (string arg in args)
            {
                s = s + arg + " ";
            }
            s = s.Trim();
            Process process = new Process();//创建进程对象    
            ProcessStartInfo startInfo = new ProcessStartInfo(runFilePath, s); // 括号里是(程序名,参数)
            process.StartInfo = startInfo;
            process.Start();
            return true;
        }

    }
}

下面新建第二个项目,用来做软件的本体

新建一个winform项目,里面什么都不用加,先设置软件的输出类型为控制台

然后打开启动脚本 Program.cs ,添加参数的打印,由于软件刚启动时,控制台也刚打开,立马打印会看不见日志,于是我这里加了异步延时操作。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Test
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Task.Run(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                if (args.Length > 0)
                {
                    for (int i = 0; i < args.Length; i++)
                    {
                        Console.WriteLine("参数是:" + args[i]);
                    }
                }
                else
                    Console.WriteLine("args参数是0");
            });

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

 现在开始测试,打开软件启动器,点击按钮,5秒后,然后就可以看到控制台的输出

这里就可以对参数做一个限制了,如果参数不正确,直接return,用户就不能直接打开软件了 

Winform ListBox用法

在Winform中,ListBox用来显示日志还不错,如图:

用法:

/// <summary>
/// 添加普通日志
/// </summary>
/// <param name="content">内容</param>
public void AddOrdinaryLog(string content)
{
    if (this.InvokeRequired)
    {
        //切换到UI线程
        this.Invoke(new MethodInvoker(delegate
        {
            AddOrdinaryLog_UI(content);
        }));
    }
    else
    {
        AddOrdinaryLog_UI(content);
    }
}


private void AddOrdinaryLog_UI(string content)
{
    //读取当前ListBox列表长度
    int len = ListBox_OrdinaryLogList.Items.Count;
    //插入新的一行
    ListBox_OrdinaryLogList.Items.Insert(len, content);
    //列表长度大于30,那么就删除第1行的数据
    if (len > 30)
        ListBox_OrdinaryLogList.Items.RemoveAt(0);
    //插入新的数据后,将滚动条移动到最下面
    int visibleItems = ListBox_OrdinaryLogList.ClientSize.Height / ListBox_OrdinaryLogList.ItemHeight;
    ListBox_OrdinaryLogList.TopIndex = Math.Max(ListBox_OrdinaryLogList.Items.Count - visibleItems + 1, 0);
}

这里我加了一个线程的判断,不需要直接复制 AddOrdinaryLog_UI 这个方法即可。

HTTP下载文件(推荐)

代码:

/// <summary>
/// Http下载文件
/// </summary>
public static string HttpDownloadFile(string url, string path)
{
    // 设置参数
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    //发送请求并获取相应回应数据
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
    //直到request.GetResponse()程序才开始向目标网页发送Post请求
    Stream responseStream = response.GetResponseStream();
    //创建本地文件写入流
    Stream stream = new FileStream(path, FileMode.Create);

    long totalBytes = response.ContentLength;
    Console.WriteLine("请求内容的长度:" + totalBytes);

    byte[] bArr = new byte[1024];
    int size = responseStream.Read(bArr, 0, (int)bArr.Length);
    long totalDownloadBytes = 0;
    while (size > 0)
    {
        totalDownloadBytes += size;
        stream.Write(bArr, 0, size);
        Console.WriteLine("下载进度:" + (int)totalDownloadBytes);
        size = responseStream.Read(bArr, 0, (int)bArr.Length);
    }
    stream.Close();
    responseStream.Close();
    return path;
}

调用:

//下载360压缩的安装包
string url1 = "https://dl.360safe.com/360zip_setup.exe";
//下载到Debug目录下
string url2 = Application.StartupPath + "\\360zip.exe";

string res = HttpDownloadFile(url1, url2);
Console.WriteLine("下载完成:" + res);

Winform HTTP下载并显示进度

效果:

HTTPDownManager.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Utils
{
    public class HTTPDownManager
    {
        /// <summary>
        /// 下载实时返回下载进度
        /// </summary>
        /// <param name="URL">下载地址</param>
        /// <param name="savePath">本地存储地址</param>
        /// <param name="downAction">委托回调函数</param>
        public static void DownloadFileData(string URL, string savePath, Action<string, string, int> downAction, Action downEndAction)
        {
            try
            {
                float percent = 0;
                string fileName = Path.GetFileName(savePath);
                System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
                System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                long totalBytes = myrp.ContentLength, totalDownloadedByte = 0;
                System.IO.Stream st = myrp.GetResponseStream(), so = new System.IO.FileStream(savePath, System.IO.FileMode.Create);
                byte[] by = new byte[1024];
                int osize = st.Read(by, 0, (int)by.Length);
                while (osize > 0)
                {
                    totalDownloadedByte = osize + totalDownloadedByte;
                    so.Write(by, 0, osize);
                    osize = st.Read(by, 0, (int)by.Length);
                    percent = (float)totalDownloadedByte / (float)totalBytes * 100;//当前位置
                    //totalBytes 是总字节数
                    downAction(fileName, GetSize(totalBytes), (int)percent);
                }
                if (downEndAction != null) downEndAction();
                so.Close();
                st.Close();
            }
            catch (System.Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        private static string GetSize(double size)
        {
            String[] units = new String[] { "B", "KB", "MB", "GB", "TB", "PB" };
            double mod = 1024.0;
            int i = 0;
            while (size >= mod)
            {
                size /= mod;
                i++;
            }
            return Math.Round(size) + units[i];
        }
    }
}

Winform 界面

Form1.cs

using FileBootUp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utils;

namespace 下载文件1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string url = "http://localhost/vodo.mp4"; //下载地址
        private string loadFilefolder = Application.StartupPath + "//vodo.mp4";//保存位置

        private void Form1_Load(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                HTTPDownManager.DownloadFileData(url, loadFilefolder, DownProgress, DownEnd);
            });
        }


        private void DownProgress(string fileName, string size, int percent)
        {
            FormControlExtensions.InvokeIfRequired(this, () =>
            {
                this.Label_FileName.Text = string.Format("正在下载:{0}", fileName);
                this.Label_Size.Text = size;
                this.Label_DownProgress.Text = string.Format("{0}%", percent);
                this.ProgressBar_DownProgress.Value = percent;
            });
        }

        private void DownEnd()
        {
            Console.WriteLine("下载完成");
        }
 
    }
}

FormControlExtensions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileBootUp
{
    public static class FormControlExtensions
    {
        /// <summary>
        /// Invokes actions in UI thread.
        /// </summary>
        public static void InvokeIfRequired(this Control control, Action action)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(action));
            }
            else
            {
                action();
            }
        }
    }
}

Winform HTTP下载文件

效果:

HttpHeper.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;

namespace HTTPTool
{
    public class HttpHelper
    {
        const int bytebuff = 1024;
        const int ReadWriteTimeOut = 2 * 1000;//超时等待时间
        const int TimeOutWait = 5 * 1000;//超时等待时间
        const int MaxTryTime = 12;

        private double totalSize, curReadSize, speed;
        private int proc, remainTime;
        private int totalTime = 0;

        private bool downLoadWorking = false;

        private string StrFileName = "";
        private string StrUrl = "";

        private string outMsg = "";

        private string fileName = string.Empty;

        public HttpHelper(string url, string savePath)
        {
            this.StrUrl = url;
            this.StrFileName = savePath;

            this.fileName = Path.GetFileName(savePath);
        }

        /// <summary>
        /// 下载数据更新
        /// </summary>
        /// <param name="totalNum">下载文件总大小</param>
        /// <param name="num">已下载文件大小</param>
        /// <param name="proc">下载进度百分比</param>
        /// <param name="speed">下载速度</param>
        /// <param name="remainTime">剩余下载时间</param>
        public delegate void delDownFileHandler(string totalNum, string num, int proc, string speed, string remainTime, string outMsg,string fileName);
        public delDownFileHandler processShow;

        public delegate void delDownCompleted();
        public delDownCompleted processCompleted;

        public System.Windows.Forms.Timer timer;

        public void init()
        {
            timer.Interval = 50;
            timer.Tick -= TickEventHandler;
            timer.Tick += TickEventHandler;
            timer.Enabled = true;
            downLoadWorking = true;
        }

        /// <summary>
        /// 获取文件大小
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        private string GetSize(double size)
        {
            String[] units = new String[] { "B", "KB", "MB", "GB", "TB", "PB" };
            double mod = 1024.0;
            int i = 0;
            while (size >= mod)
            {
                size /= mod;
                i++;
            }
            return Math.Round(size) + units[i];
        }

        /// <summary>
        /// 获取时间
        /// </summary>
        /// <param name="second"></param>
        /// <returns></returns>
        private string GetTime(int second)
        {
            return new DateTime(1970, 01, 01, 00, 00, 00).AddSeconds(second).ToString("HH:mm:ss");
        }

        /// <summary>
        /// 下载文件(同步)  支持断点续传
        /// </summary>
        public void DowLoadFile()
        {
            totalSize = GetFileContentLength(StrUrl);

            //打开上次下载的文件或新建文件
            long lStartPos = 0;
            System.IO.FileStream fs;
            if (System.IO.File.Exists(StrFileName))
            {
                fs = System.IO.File.OpenWrite(StrFileName);
                lStartPos = fs.Length;
                fs.Seek(lStartPos, System.IO.SeekOrigin.Current);   //移动文件流中的当前指针
            }
            else
            {
                fs = new System.IO.FileStream(StrFileName, System.IO.FileMode.Create);
                lStartPos = 0;
            }

            curReadSize = lStartPos;

            if (curReadSize == totalSize)
            {
                outMsg = "文件已下载!";
                processCompleted?.Invoke();
                timer.Enabled = false;
                return;
            }

            //打开网络连接
            try
            {
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(StrUrl);
                if (lStartPos > 0)
                    request.AddRange((int)lStartPos);    //设置Range值

                //向服务器请求,获得服务器回应数据流
                System.IO.Stream ns = request.GetResponse().GetResponseStream();
                byte[] nbytes = new byte[bytebuff];
                int nReadSize = 0;
                proc = 0;

                do
                {

                    nReadSize = ns.Read(nbytes, 0, bytebuff);
                    fs.Write(nbytes, 0, nReadSize);

                    //已下载大小
                    curReadSize += nReadSize;
                    //进度百分比
                    proc = (int)((curReadSize / totalSize) * 100);
                    //下载速度
                    speed = (curReadSize / totalTime) * 10;
                    //剩余时间
                    remainTime = (int)((totalSize / speed) - (totalTime / 10));

                    if (downLoadWorking == false)
                        break;

                } while (nReadSize > 0);

                fs.Close();
                ns.Close();

                if (curReadSize == totalSize)
                {
                    outMsg = "下载完成!";
                    processCompleted?.Invoke();
                    downLoadWorking = false;
                }
            }
            catch (Exception ex)
            {
                fs.Close();
                outMsg = string.Format("下载失败:{0}", ex.ToString());
            }
        }

        public void DownLoadPause()
        {
            outMsg = "下载已暂停";
            downLoadWorking = false;
        }

        public void DownLoadContinue()
        {
            outMsg = "正在下载";
            downLoadWorking = true;
            DownLoadStart();
        }

        public void DownLoadStart()
        {
            Task.Run(() =>
            {
                DowLoadFile();
            });
        }


        /// <summary>
        /// 定时器方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TickEventHandler(object sender, EventArgs e)
        {
            processShow?.Invoke(GetSize(totalSize),
                                GetSize(curReadSize),
                                proc,
                                string.Format("{0}/s", GetSize(speed)),
                                GetTime(remainTime),
                                outMsg,
                                fileName
                                );
            if (downLoadWorking == true)
            {
                totalTime++;
            }
        }

        /// <summary>
        /// 获取下载文件长度
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public long GetFileContentLength(string url)
        {
            HttpWebRequest request = null;
            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(url);
                //request.Timeout = TimeOutWait;
                //request.ReadWriteTimeout = ReadWriteTimeOut;
                //向服务器请求,获得服务器回应数据流
                WebResponse respone = request.GetResponse();
                request.Abort();
                return respone.ContentLength;
            }
            catch (WebException e)
            {
                if (request != null)
                    request.Abort();
                return 0;
            }
        }
    }
}

winform 界面:

代码:

using HTTPTool;
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 下载文件
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        static string url = "http://localhost/vodo.mp4"; //下载地址
        static string loadFilefolder = Application.StartupPath + "//vodo.mp4";//保存位置
        HttpHelper httpManager = new HttpHelper(url, loadFilefolder);




        private void Form1_Load(object sender, EventArgs e)
        {
            httpManager.timer = new System.Windows.Forms.Timer();
            httpManager.processShow += processSho;
            httpManager.processCompleted += processComplete;
            httpManager.init();
        }

        public void processSho(string totalNum, string num, int proc, string speed, string remainTime, string msg, string fileName)
        {
            this.label1.Text = string.Format("文件大小:{0}", totalNum);
            this.label2.Text = string.Format("已下载:{0}", num);
            this.label3.Text = string.Format("进度:{0}%", proc);
            this.label4.Text = msg;
            this.label5.Text = string.Format("速度:{0}", speed);
            this.label6.Text = string.Format("剩余时间:{0}", remainTime);
            this.label7.Text = fileName;

            progressBar1.Value = proc;
        }

        private void processComplete()
        {
            MessageBox.Show("文件下载完成!", "提示");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            httpManager.DownLoadStart();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            httpManager.DownLoadPause();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            httpManager.DownLoadContinue();
        }

    }
}

源码文件:点击下载

Winform 跨线程访问UI组件

this.Invoke 必须运行在winform的代码中,所有下面的代码也只能写在Form 界面代码中。

代码:

var task = Task.Run(async delegate
{
	await Task.Delay(200);
	this.Invoke(new MethodInvoker(delegate {
		Label_Log.Text = string.Empty;
	}));
});

如果在其他的线程中,调用UI 相关的控件需要切换线程,否则会报错。

下面方法可以切换到UI 线程并执行 Action

public static class FormControlExtensions
{
    /// <summary>
    /// Invokes actions in UI thread.
    /// </summary>
    public static void InvokeIfRequired(this Control control, Action action)
    {
        if (control.InvokeRequired)
        {
            control.Invoke(new MethodInvoker(action));
        }
        else
        {
            action();
        }
    }
}

其实也可以这样写,申请一个线程,执行完成后,再切换到 UI 线程,这样就不会卡界面了

new Thread((ThreadStart)(delegate()
{
    //线程内的计算
	//......
	//切换回UI线程
    this.Dispatcher.BeginInvoke((Action)delegate
    {
        //Label1.Text = "执行完成";
    });
})).Start();

Winform 改变文字的颜色和大小

代码

label1.Font = new Font("隶书", 20, FontStyle.Bold); //第一个是字体,第二个大小,第三个是样式,
label1.ForeColor = Color.Red; //颜色 

label2.Font = new Font("华文行楷", 20, FontStyle.Bold); //第一个是字体,第二个大小,第三个是样式,
label2.ForeColor = Color.Green; //颜色

label3.Font = new Font("宋体", 20, FontStyle.Bold); //第一个是字体,第二个大小,第三个是样式,
label3.ForeColor = Color.Blue; //颜色 
label3.Text = DateTime.Now.ToString("yyyy-MM-dd");

end

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊思宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值