亚洲熟妇无码久久精品,最近中文字幕在线看免费完整版,亚洲AV中文无码字幕色三,一级a性色生活片久久毛片,一本大道香蕉综合视频在线观看

Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能

發(fā)布于: 2018-09-27    瀏覽: 2005    作者:Yang

一、問題背景

  本地程序在實(shí)際項(xiàng)目使用過程中,因?yàn)榭梢圆僮麟娔X本地的一些信息,并且對(duì)于串口、OPC、并口等數(shù)據(jù)可以方便的進(jìn)行收發(fā),雖然現(xiàn)在軟件行業(yè)看著動(dòng)不動(dòng)都是互聯(lián)網(wǎng)啊啥的,大有Web服務(wù)就是高大上的感覺,但是作為本地的應(yīng)用還是有著非常重要的位置,特別是在制造業(yè)工廠里,車間里相關(guān)的程序。

  拋開一切業(yè)務(wù)上的功能不談,本地程序一直比較詬病的地方就是在于軟件的更新上,由于程序都在客戶端電腦上運(yùn)行,當(dāng)需要更新的時(shí)候,就不得不由專門的實(shí)施人員過去,部署更新,無形中增加項(xiàng)目成本,SO,對(duì)于c/s程序的自動(dòng)更新也是比較苦惱的問題,下面我就來稍微解析下,一個(gè)自動(dòng)更新程序應(yīng)該要怎么實(shí)現(xiàn)(PS:思路可能比較傳統(tǒng),歡迎大家拍磚提供更好的思路

二、自動(dòng)更新的關(guān)注點(diǎn)

  Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技

  如圖所示,對(duì)于一個(gè)自動(dòng)更新程序,關(guān)注點(diǎn)應(yīng)該都是以上幾個(gè)點(diǎn)

· 管理員權(quán)限,在win7以后,如果應(yīng)用位置在C盤的話,每次操作目錄都會(huì)申請(qǐng)管理員權(quán)限,emmmm,所以這個(gè)必須要考慮

· 對(duì)于要實(shí)現(xiàn)一個(gè)較為通用的自動(dòng)更新,應(yīng)該要安裝了.NetFrameWork的都要可以使用,并且方便使用

· 更新程序同時(shí)要只能啟動(dòng)一個(gè),不然肯定出事兒,雖然很少有會(huì)有人去點(diǎn)2次,但是還是要考慮

· 界面要求上,更新說明以及進(jìn)度條要顯示

· 很多時(shí)候可能我們也是需要一個(gè)靜默更新的操作

· 運(yùn)行更新的時(shí)候,記得要關(guān)閉運(yùn)行的程序,不然肯定更新失敗

· 對(duì)于更新失敗,得有完善的回滾以及備份機(jī)制

· 更新成功后,得可以啟動(dòng)對(duì)應(yīng)的主程序

· 有些 時(shí)候程序部分信息是記錄在注冊(cè)表里,如果注冊(cè)表要修改咋辦呢,so,對(duì)于注冊(cè)表也得要支持

· 有些時(shí)候程序更新到后面,會(huì)出現(xiàn)一些多余的DLL,這些DLL那也是要干掉滴(雖然覺得有點(diǎn)雞肋)

  大概就是以上的一些點(diǎn),這些是我自己思考的時(shí)候羅列出來的,可能比較亂,大家明白就好

三、設(shè)計(jì)說明

  

Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技  更新程序主要流程如圖所示,大的流程方向上是比較簡(jiǎn)單的,但是如果深入后,還是有部分會(huì)比較復(fù)雜

Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技 

  程序類的一些簡(jiǎn)單說明

  config.update:注冊(cè)表的增刪規(guī)則以及文件的刪除規(guī)則,如下規(guī)則所示

[regedit_del] //刪除注冊(cè)表

SOFTWARE\\XXX\\XXX,name

[regedit_add]//新增注冊(cè)表

SOFTWARE\\XXX\\XXXX,name=John Doe

[file_del] //刪除文件

hello.dll

  Server.xml&RemoteInfo.cs:服務(wù)端的版本配置文件信息

  Local.xml&LocalInfo.cs:客戶端的版本配置文件信息

  UpdateWork.cs:核心的更新方法,為了方便后續(xù)有界面定制化的需求,將更新相關(guān)的全部放在UpdateWork中,使用UpdateWork.Do方法就可以進(jìn)行更新

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  一些細(xì)節(jié)說明

  1、如何讓程序盡量的方便集成?

  由于自動(dòng)更新程序必須是要與主程序分開的,所以我們要讓主程序啟動(dòng)更新程序的時(shí)候,將主程序自己的信息帶進(jìn)去,這樣才可以盡可能的做到通用

        /// <summary>

        /// 應(yīng)用程序的主入口點(diǎn)。
     /// <param name="args">[0]程序名稱,[1]靜默更新 0:否 1:是</param> 

        /// </summary>        [STAThread]

        static void Main(string[] args)

        {

            if (f)

            {

                try

                {

                    if (String.IsNullOrEmpty(args[0]) == false)

                    {

                        UpdateWork updateWork = new UpdateWork(args[0]);

                        if (updateWork.UpdateVerList.Count > 0)

                        {

                            /* 當(dāng)前用戶是管理員的時(shí)候,直接啟動(dòng)應(yīng)用程序

                             * 如果不是管理員,則使用啟動(dòng)對(duì)象啟動(dòng)程序,以確保使用管理員身份運(yùn)行

                             */

                            //獲得當(dāng)前登錄的Windows用戶標(biāo)示

                            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();

                            //創(chuàng)建Windows用戶主題                             Application.EnableVisualStyles();

                            System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);

                            //判斷當(dāng)前登錄用戶是否為管理員

                            if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))

                            {

                                if (args[1] == "1")

                                {

                                    updateWork.Do();

                                }

                                else

                                {

                                    Application.EnableVisualStyles();

                                    Application.SetCompatibleTextRenderingDefault(false);

                                    Application.Run(new MainForm(updateWork));

                                }

                            }

                            else

                            {

                                String result = Environment.GetEnvironmentVariable("systemdrive");

                                if (AppDomain.CurrentDomain.BaseDirectory.Contains(result))

                                {

                                    //創(chuàng)建啟動(dòng)對(duì)象

                                    ProcessStartInfo startInfo = new ProcessStartInfo

                                    {

                                        //設(shè)置運(yùn)行文件

                                        FileName = System.Windows.Forms.Application.ExecutablePath,

                                        //設(shè)置啟動(dòng)動(dòng)作,確保以管理員身份運(yùn)行

                                        Verb = "runas",


                                        Arguments = " " + args[0] + " " + args[1]

                                    };

                                    //如果不是管理員,則啟動(dòng)UAC                                     System.Diagnostics.Process.Start(startInfo);

                                }

                                else

                                {

                                    if (args[1] == "1")

                                    {

                                        updateWork.Do();

                                    }

                                    else

                                    {

                                        Application.EnableVisualStyles();

                                        Application.SetCompatibleTextRenderingDefault(false);

                                        Application.Run(new MainForm(updateWork));

                                    }

                                }

                            }

                        }

                    }

                }

                catch (Exception ex)

                {

                    MessageBox.Show(ex.Message);

                }

            }

        }

  winform在啟動(dòng)的main方法里,有一個(gè)參數(shù)是args,這就是我們可以接收來自外界的參數(shù),從代碼中可以看到,總共傳遞進(jìn)來的參數(shù)有2個(gè),args[0]程序名稱 args[1] 靜默安裝的配置信息,通過這2個(gè)參數(shù),我們就可以將自動(dòng)更新與主程序分開

  2、更新前備份

        /// <summary>

        /// 備份當(dāng)前的程序目錄信息

        /// </summary>

        private UpdateWork Bak()

        {

            try

            {


                LogTool.AddLog("更新程序:準(zhǔn)備執(zhí)行備份操作");


                DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

                foreach (var item in di.GetFiles())

                {

                    if (item.Name != mainName)//當(dāng)前文件不需要備份                    {

                        if (item.Name == "DotNetZip.dll")

                        {

                        }

                        else

                        {

                            File.Copy(item.FullName, bakPath + item.Name, true);

                        }

                    }

                }

                //文件夾復(fù)制

                foreach (var item in di.GetDirectories())

                {

                    if (item.Name != "bak" && item.Name != "temp")

                    {

                        CopyDirectory(item.FullName, bakPath);

                    }

                }

                LogTool.AddLog("更新程序:備份操作執(zhí)行完成,開始關(guān)閉應(yīng)用程序");

                OnUpdateProgess?.Invoke(20);

                return this;

            }

            catch (Exception EX)

            {

                throw EX;

            }

        }

  對(duì)于自動(dòng)更新來說,如果更新失敗的話,我們需要保證,程序是可回滾的,那就需要在更新前要對(duì)程序進(jìn)行一個(gè)備份,如代碼所示,由于我這邊用到了DotNetZip.dll,所以這個(gè)dll是不能備份的,不然恢復(fù)的時(shí)候由于自動(dòng)更新程序還在跑,覆蓋的時(shí)候會(huì)報(bào)錯(cuò),現(xiàn)在已經(jīng)將DotNetZip的代碼直接放到項(xiàng)目中,所以不需要去管DotNetZip.dll的問題,上述代碼邏輯還是很簡(jiǎn)單的,拷貝當(dāng)前運(yùn)行程序下的所有文件以及文件夾到備份目錄(ps:由于windows的安全限制,c盤目錄普通用戶只有對(duì)temp文件夾有操作權(quán)限,so需要將bakPath設(shè)置到temp目錄下,如下代碼所示

String bakPath = Path.Combine(Environment.GetEnvironmentVariable("TEMP"), @"MAutoUpdate\bak\");//獲取temp文件夾下的bak目錄,如果不存在記得通過程序去創(chuàng)建

  3、更新文件的下載

 /// <summary>

        /// 下載方法

        /// </summary>

        private UpdateWork DownLoad()

        {

            using (WebClient web = new WebClient())

            {

                foreach (var item in UpdateVerList)

                {

                    try

                    {

                        LogTool.AddLog("更新程序:下載更新包文件" + item.ReleaseVersion);

                        web.DownloadFile(item.ReleaseUrl, tempPath + item.ReleaseVersion + ".zip");

                        OnUpdateProgess?.Invoke(60 / UpdateVerList.Count);

                    }

                    catch (Exception ex)

                    {

                        LogTool.AddLog("更新程序:更新包文件" + item.ReleaseVersion + "下載失敗,本次停止更新,異常信息:" + ex.Message);

                        throw ex;

                    }

                }

                return this;

            }

        }

  要更新嘛,那當(dāng)然得有下載,索性.Net給我們提供了一個(gè)非常簡(jiǎn)單的下載玩意兒,WebClient,給url就下載,絕對(duì)不二話,WebClient本身也有不少的事件可以使用,這個(gè)大家自己摸索,由于更新可能會(huì)存在好幾個(gè)包一起更新的情況,所以這邊使用循環(huán)先將所有要更新的下載下來,這部分下載代碼還是比較簡(jiǎn)單的

  4、更新方法

  Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技

  流程如上圖所示,文字表達(dá)捉急,只能靠圖了,阿門

        private UpdateWork Update()

        {

            foreach (var item in UpdateVerList)

            {

                try

                {

                    //如果是覆蓋安裝的話,先刪除原先的所有程序

                    if (item.UpdateMode == "Cover")

                    {

                        DelLocal();

                    }

                    string path = tempPath + item.ReleaseVersion + ".zip";

                    using (ZipFile zip = new ZipFile(path))

                    {

                        LogTool.AddLog("更新程序:解壓" + item.ReleaseVersion + ".zip");

                        zip.ExtractAll(AppDomain.CurrentDomain.BaseDirectory, ExtractExistingFileAction.OverwriteSilently);

                        LogTool.AddLog("更新程序:" + item.ReleaseVersion + ".zip" + "解壓完成");

                        ExecuteINI();//執(zhí)行注冊(cè)表等更新以及刪除文件                    }

                    localInfo.LastUdpate = item.ReleaseDate;

                    localInfo.LocalVersion = item.ReleaseVersion;

                    localInfo.SaveXml();

                }

                catch (Exception ex)

                {

                    LogTool.AddLog("更新程序出現(xiàn)異常:異常信息:" + ex.Message);

                    LogTool.AddLog("更新程序:更新失敗,進(jìn)行回滾操作");

                    Restore();

                    break;

                }

                finally

                {

                    //刪除下載的臨時(shí)文件

                    LogTool.AddLog("更新程序:刪除臨時(shí)文件" + item.ReleaseVersion);

                    DelTempFile(item.ReleaseVersion + ".zip");//刪除更新包

                    LogTool.AddLog("更新程序:臨時(shí)文件刪除完成" + item.ReleaseVersion);

                }

            }

            OnUpdateProgess?.Invoke(98);

            return this;

        }

四、如何在程序中使用

  新建winform項(xiàng)目后,在Main里加入以下代碼

        /// <summary>

        /// 應(yīng)用程序的主入口點(diǎn)。

        /// </summary>        [STAThread]

        static void Main()

        {

            String path = AppDomain.CurrentDomain.BaseDirectory + "MAutoUpdate.exe";

            //同時(shí)啟動(dòng)自動(dòng)更新程序

            if (File.Exists(path))

            {

                ProcessStartInfo processStartInfo = new ProcessStartInfo()

                {

                    FileName = "MAutoUpdate.exe",

                    Arguments = " MAutoUpdate.Test 1"http://1表示靜默更新 0表示彈窗提示更新

                };

                Process proc = Process.Start(processStartInfo);

                if (proc != null)

                {

                    proc.WaitForExit();

                }

            }

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new Form1());

        }

  更新界面圖(可以自己改,這個(gè)反正很簡(jiǎn)單),細(xì)心的小伙伴們可能發(fā)現(xiàn)了,我這是有點(diǎn)魔方微信的圖(ps:也是看了微信的升級(jí)后,突然想到我們項(xiàng)目里目前為止比較糾結(jié)的自動(dòng)更新,所以趁著這幾個(gè)晚上搗鼓出來)

  Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技

  Winfrom中實(shí)現(xiàn)系統(tǒng)自動(dòng)升級(jí)功能-長(zhǎng)沙網(wǎng)站設(shè)計(jì)-長(zhǎng)沙簡(jiǎn)界科技

五、總結(jié)

  花了大概三個(gè)晚上的時(shí)間搗鼓這個(gè),里面其實(shí)考慮的因素還是很多,以前思考的時(shí)候不會(huì)深入思考,想著自動(dòng)更新么 就是判斷、更新啟動(dòng)結(jié)束,但是做下來,細(xì)節(jié)點(diǎn)真的是很多,后續(xù)可能會(huì)在公司內(nèi)部項(xiàng)目里進(jìn)行一個(gè)小的推廣,看看符不符合真實(shí)的需求,由于個(gè)人原因,在測(cè)試上可能會(huì)有所不夠,這個(gè)也是一個(gè)拋磚引玉,如果有小伙伴有更好更方便的升級(jí)方式,也請(qǐng)告知(ps:文字表達(dá)弱雞,大家多多包涵)

   項(xiàng)目地址:https://github.com/Hello-Mango/MAutoUpdate,代碼比較亂,見諒

作者: Mango

出處: http://www.cnblogs.com/OMango/

關(guān)于自己:專注.Net桌面開發(fā)以及Web后臺(tái)開發(fā),開始接觸微服務(wù)、docker等互聯(lián)網(wǎng)相關(guān)(最近被互聯(lián)網(wǎng)架構(gòu)搞的死去活來- -)

本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接,如有問題, 可站內(nèi)信告知.

在線客服

售前咨詢

售后服務(wù)

投訴/建議

服務(wù)熱線
0731-83091505
18874148081
亚洲熟妇无码久久精品,最近中文字幕在线看免费完整版,亚洲AV中文无码字幕色三,一级a性色生活片久久毛片,一本大道香蕉综合视频在线观看