首頁 > 軟體

C# WinForm實現自動更新程式之使用者端的範例程式碼

2022-10-16 14:04:03

前言

第二步理論上我們該寫使用者端了,但是,在此之前,需要先介紹下一些必要的方法以及操作。

寫程式碼還是要儘量的保證通用性,以便以後需要的時候可以拿來稍微改改甚至直接使用。所以在這裡我們將自動更新的程式抽象出來,即對於使用者端來說,它只包含三個檔案(AutoUpdate.dll、AutoUpdate.exe、UpdateList.xml,如果是.NET Framework的話,其實是沒有AutoUpdate.dll檔案的,就一個exe就足夠了。這也是我為什麼一直不用NET Core來寫Winform程式的原因之一);然後將這三個檔案放到主程式的目錄中即可。

然後就是傳參呼叫,在Program檔案中做了以下程式碼操作。所以呼叫的時候需要將主程式的執行目錄以及程序名傳過來,作用分別是再更新完後自動啟動以及更新之前把相關的程序殺掉以便完成更新。

同時可以看到在更新的時候,有一個圖片旋轉的動作,也一併放到此篇文章中。

開發環境

.NET Core 3.1

開發工具

Visual Studio 2019

實現程式碼

//更新程式
namespace AutoUpdate {
    static class Program {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args) {
            if(args.Length != 1) {
                return;
            }
            var arg = args[0].Split("|*|");
            if(arg.Length == 0) {
                return;
            }
            string runPath = arg[0];
            string procesName = arg[1];
            Process[] processes = Process.GetProcesses();
            foreach(Process process in processes) {
                if(process.ProcessName == procesName) {
                    process.Kill(true);
                }
            }
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form_update(runPath));
        }
    }
}
//主程式
namespace AutoUpdate.Test {
    static class Program {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {

            Update();

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


        readonly static string updateXml = Application.StartupPath + "UpdateList.xml";
        /// <summary>
        /// 獲取本地更新地址
        /// </summary>
        /// <returns></returns>
        static string GetUpdateUrl() {
            XElement xele = XElement.Load(updateXml);
            string url = xele.Element("url").Value;
            return url;
        }

        /// <summary>
        /// 獲取本地更新檔案
        /// </summary>
        /// <returns></returns>
        static string GetUpdateFiles() {
            XDocument xdoc = XDocument.Load(updateXml);
            var files = from f in xdoc.Root.Element("files").Elements() select new { name = f.Attribute("name").Value, version = f.Attribute("version").Value };
            return JsonConvert.SerializeObject(files);
        }

        /// <summary>
        /// 檢查是否需要更新
        /// </summary>
        /// <returns></returns>
        static bool CheckUpdate() {
            string url = GetUpdateUrl();
            HttpResult httpResult = HttpUtil.HttpRequest(new HttpItem(url + "GetUpdateFiles", requestData: GetUpdateFiles()));
            if(httpResult.Status) {
                UpdateModel_Out output = JsonConvert.DeserializeObject<UpdateModel_Out>(httpResult.HttpStringData);

                if(output.updateList.Count > 0)
                    return true;
            }
            return false;
        }

        static void Update() {
            if(CheckUpdate()) {
                string processName = Assembly.GetExecutingAssembly().GetName().Name;

                ProcessStartInfo info = new ProcessStartInfo(Application.StartupPath + "AutoUpdate.exe", Process.GetCurrentProcess().MainModule.FileName + "|*|" + processName);
                Process.Start(info);
                Environment.Exit(0);
            }
        }
    }
}
public static class ImageEx {
        /// <summary>
        /// 旋轉圖片
        /// </summary>
        /// <param name="image"></param>
        /// <param name="angle"></param>
        /// <returns></returns>
        public static Image RotateImage(this Image image, float angle) {
            if(image == null)
                throw new ArgumentNullException("image");
            float dx = image.Width / 2.0f;
            float dy = image.Height / 2.0f;

            Bitmap rotatedBmp = new Bitmap(image.Width, image.Height);
            rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            Graphics g = Graphics.FromImage(rotatedBmp);
            g.TranslateTransform(dx, dy);
            g.RotateTransform(angle);
            g.TranslateTransform(-dx, -dy);
            g.DrawImage(image, new PointF(0, 0));

            g.Dispose();
            return rotatedBmp;
        }
    }

實現效果

程式碼解析

這裡可以關注下在主程式中的獲取更新地址以及檔案等方法,其實我這裡是有重複判斷的,即在主程式中判斷了一遍,還會在更新程式中判斷一遍,如果覺得不需要,可以執行選擇去掉,全部交給更新程式去做。但是也就需要統一放在更新程式的入口中做處理了,相對而言,我覺得寫兩遍還是很方便。

到此這篇關於C# WinForm實現自動更新程式之使用者端的範例程式碼的文章就介紹到這了,更多相關C# WinForm更新程式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com