IoTClientTool自動升級更新

IoTClientTool是什麼

IoTClientTool是什麼,IoTClientToolIoTClient開源組件的可視化操的做實現。方便對plc設備和ModBusRtu、BACnet、串口等協議進行測試和調試。git

打包成單文件exe

一般咱們開發出來的WinForm程序,除了一個exe文件還會有不少dll文件。
那麼有沒有辦法只生成一個exe文件,讓程序更加方便傳播和使用,答案是確定的。
NuGet搜索Costura.Fody並下載,而後從新生成解決方案便可,你在去bin目錄查看,原來的一堆dll不見了。
github

.net core官方支持打包成單文件

若是你使用的.net core 3.0,那麼你能夠直接使用官方支持的發佈單文件功能。
直接使用命令dotnet publish -r win10-x64 /p:PublishSingleFile=true
或者修改一下項目文件json

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <RuntimeIdentifier>win10-x64</RuntimeIdentifier>//發佈平臺
    <PublishSingleFile>true</PublishSingleFile>//是否單個exe
  </PropertyGroup>
  <PropertyGroup>
    <PublishTrimmed>true</PublishTrimmed>//啓用壓縮
  </PropertyGroup>
</Project>

自動升級更新

一個有生命的桌面程序理應作到能夠自動升級。不少人在作自動升級更新時會執行一個單獨的升級exe,也就是說一個完整的程序起碼包括兩個exe。我的以爲不夠優雅,若是能用一個exe本身更新本身豈不是完美。思考以下:
api

本身更新本身 ,而後殺了本身,啓動新的本身。
代碼可參考https://github.com/zhaopeiym/IoTClient/blob/master/IoTClient.Tool/IndexForm.cs中的CheckUpgradeAsync方法。app

/// <summary>
/// 檢查當前是否須要升級
/// </summary>
private async Task CheckUpgradeAsync()
{
    UpgradeFileManage();
    HttpClient http = new HttpClient();
    var content = new StringContent(JsonConvert.SerializeObject(new VersionCheckInput()));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    var response = await http.PostAsync("https://download.haojima.net/api/IoTClient/VersionCheck", content);
    var result = await response.Content.ReadAsStringAsync();
    var VersionObj = JsonConvert.DeserializeObject<ResultBase<VersionCheckOutput>>(result);
    if (VersionObj.Code == 200 && VersionObj.Data.Code == 1)
    {
        if (MessageBox.Show("IoTClient有新版本,是否升級到最新版本?", "版本升級", MessageBoxButtons.OKCancel) == DialogResult.OK)
        {
            if (new UpgradeForm().ShowDialog() != DialogResult.OK) return;
            var newApp = Application.StartupPath + @"\temp." + Path.GetFileName(Application.ExecutablePath);
            //打開臨時文件 關閉並舊版本
            Process.Start(newApp);
            Close();
            Environment.Exit(0);
        }
    }
}

/// <summary>
/// 升級文件處理
/// </summary>
private void UpgradeFileManage()
{
    //若是啓動的升級臨時文件,
    //則一、刪除舊版本 二、複製當前臨時文件爲新版本 三、啓動新版本 四、關閉當前打開的臨時版本
    if (Path.GetFileName(Application.ExecutablePath).Contains("temp."))
    {
        var filePath = Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath).Replace("temp.", ""));
        var newFilePath = filePath;
        try
        {
            try
            {
                //2.1刪除舊版本
                if (File.Exists(filePath)) File.Delete(filePath);
            }
            catch (Exception)
            {
                //若是由於進程正在使用中則休眠後再重試
                //出現此問題的緣由是,上一個程序還沒關閉,這個程序就啓動了,啓動後會執行刪除上一個程序,因此報錯。
                Thread.Sleep(500);
                if (File.Exists(filePath)) File.Delete(filePath);
            }
            //三、複製臨時文件爲新的文件 打開新的文件       
            File.Copy(Application.ExecutablePath, newFilePath);
            //三、打開新的文件
            Process.Start(filePath);
            //四、關閉臨時文件   
            //Close();
            Environment.Exit(0);
        }
        catch (Exception ex)
        {
            MessageBox.Show("升級失敗 " + ex.Message);
        }
    }
    //4.2若是當前啓動的不是臨時文件,則刪除臨時文件。
    else
    {
        var filePath = Path.Combine(Application.StartupPath, "temp." + Path.GetFileName(Application.ExecutablePath));
        try
        {
            if (File.Exists(filePath)) File.Delete(filePath);
        }
        catch (Exception)
        {
            Thread.Sleep(500);
            if (File.Exists(filePath)) File.Delete(filePath);
        }
    }
}

效果圖

相關文章
相關標籤/搜索