Skip to content

VelinoStudio/Updater

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Updater

更新器

下载:https://github.com/VelinoStudio/Updater/releases/download/1.0.7150.34766/UpdateUI.zip

使用UpdaterUI制作更新配置文件,主要以文件版本为主,MD5为辅。将制作的配置文件与更新的程序下的所有文件原样放入HTTP服务器。 客户端引用UpdaterUI里的Updater.dll,并调用下面两句即可。

//更新配置文件中记录的是相对路径,HTTP链接应该是程序的根目录,更新配置文件也需要在这个目录中
Updater updater = new Updater("HTTP链接", "更新配置文件");
//检查并更新
//这个方法唯一的参数是父窗体,使用时可以阻止父窗体被点击到。可以使用单独的线程运行,不会影响到父窗口内代码的运行,而同时又确保不会点击到父窗口
updater.CheckUpdate(Form);

CheckUpdate方法有两个重载:

public DialogResult CheckUpdate(Form parentForm, out Dictionary<string, string> configurations)
public DialogResult CheckUpdate<T>(Form parentForm, out Dictionary<string, string> configurations) where T : Form, IUpdateForm, new()

第一个重载增加了一个out参数,用户获取更新配置中保存的.exe.config结尾的配置文件中节点下的所有配置项。

第二个重载有一个泛型T参数,使用该参数,可以使用自定义的更新窗口,更新窗口是通过接口“IUpdateForm”调用的,而不是使用窗体“Form”调用,这样提高了自定义窗体的自由度。

自定义窗口必须是实现了“IUpdateForm”接口的“Form”或“Form”的派生类,你可以使用任何继承于“Form”的第三方窗体控件,比如DevExpress的XtraForm。

接口中定义了两个事件、一个属性和一个方法,这四个都是“Form”类中自带的,自定义窗口中无需自己实现。

除了这四个,还定义了9个属性和1个方法。9个属性中,有三个是给自定义窗体可能用到的基础信息,另外6个是委托方法。9个属性在实例化时,就已经由调用方法全部 赋值了,只需要实现最简单的{get;set;}即可。剩下的那一个方法是更新进度的CallBack,只有一个参数,通过这个参数可以获取更新进度的每一步骤。

自定义窗口的代码看起来应该是这样的:

public partial class Form_FindedUpdate : XtraForm, IUpdateForm
    {
        bool finish = false;
        bool error = false;
        public UpdateInfo UpdateInfo { get; set; }
        public string VersionHistory { get; set; }
        public UpdateFileInfo[] NeedUpdateFile { get; set; }
        public Func<Dictionary<string, string>> BackupFile { get; set; }
        public Action OnErrorUpdate { get; set; }
        public Action OnFinishUpdate { get; set; }
        public Action OnCancelUpdate { get; set; }
        public Action OnRollbackUpdate { get; set; }
        public Action OnBeginUpdate { get; set; }
        public Form_FindedUpdate(){InitializeComponent();}
        private void Form_FindedUpdate_Load(object sender, EventArgs f)
        {
            richTextBox1.Text = VersionHistory;
            progressBar1.Maximum = NeedUpdateFile.Length;
            progressBar1.Step = 1;
            progressBar1.Minimum = 0;
            progressBar1.Value = 0;
            progressBar1.Visible = true;
            progressBar2.Maximum = 100;
            progressBar2.Minimum = 0;
            progressBar2.Value = 0;
            progressBar2.Visible = true;
        }
        public void UpdateProgressingCallBack(UpdateArgs e)
        {
            switch (e.UpdateState)
            {
                case UpdateState.Find:
                    this.Text = $"找到更新,更新文件数量 {e.FilesCount}";
                    break;
                case UpdateState.Updating:
                    this.Text = $"更新中,当前文件:{e.UpdateFileInfo.FilePath} ({e.CurrentIndex}/{e.FilesCount})"; 
                    break;
                case UpdateState.Downloading:
                    int progress = (int)(((e.DownloadInfo.DownloadingFile.DownloadedSize * 1.00) / (e.DownloadInfo.DownloadingFile.ContentLength * 1.00)) * 100);
                    progressBar2.Value = progress;
                    break;
                case UpdateState.Downloaded:
                    progressBar1.PerformStep();
                    break;
                case UpdateState.Rollback:
                    this.Text = $"更新失败,正在回滚:{e.UpdateFileInfo.FilePath.Replace(Environment.CurrentDirectory, "")}";
                    error = true;
                    break;
                case UpdateState.Finish:
                    this.Text = "完成更新!";
                    button3.Text = "完成更新";
                    button1.Enabled = button1.Visible = false;
                    button2.Enabled = button2.Visible = false;
                    button3.Enabled = button3.Visible = true;
                    break;
                case UpdateState.Rollbacked:
                    this.Text = "回滚完成,关闭更新界面查看错误信息!";
                    button3.Text = "关闭";
                    button1.Enabled = button1.Visible = false;
                    button2.Enabled = button2.Visible = false;
                    button3.Enabled = button3.Visible = false;
                    break;
            }
        }
        private void Button1_Click(object sender, EventArgs e)
        {
            if (finish)
                OnFinishUpdate();
            else
            {
                button1.Enabled = false;
                button2.Enabled =  false;
                OnBeginUpdate();
            }
        }
        private void Button3_Click(object sender, EventArgs e)
        {
            if (error)
                OnErrorUpdate();
            else
                OnFinishUpdate();
        }
        private void Button2_Click(object sender, EventArgs e)
        {
            if (finish)
                OnFinishUpdate();
            else
                OnCancelUpdate();
        }
    }

================================================================

UpdaterUI用于制作更新的配置文件,通过该程序的配置文件,可以指定哪些文件或哪些目录下的文件(不包含子目录)使用MD5校验的方式更新,方便更新一些不包含文件版本的文件,比如文本类型的配置文件或图片。

比较特殊的是以“.exe.config”结尾的EXE配置文件,UI会自动记录主EXE程序的配置文件中节点下的所有配置项,而其他的以“.exe.config”结尾的EXE配置文件会被自动忽略。

通过该程序的配置文件,可以指定哪些文件或哪些目录下的文件(不包含子目录)使用MD5校验的方式更新,方便更新一些不包含文件版本的文件,比如文本类型的配置文件或图片。 配置文件中设置如下,需要的请自行添加,理论上可以有无限多个。但是使用MD5校验方式更新会影响更新的效率,建议不要太多。

<appSettings>
    <add key="MD5Hash_File_1" value="文件1"/>
    <add key="MD5Hash_File_2" value="文件2"/>
    <add key="MD5Hash_File_3" value="bin\文件3"/>
    <add key="MD5Hash_File_x" value="bin\data\文件x"/>
    <add key="MD5Hash_Directory_1" value="bin\data\"/>
    <add key="MD5Hash_Directory_2" value="bin\image\"/>
    <add key="MD5Hash_Directory_3" value="bin\gif\"/>
    <add key="MD5Hash_Directory_x" value="bin\xxxxx\"/>
</appSettings>

About

更新器

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages