[搜片神器]winform程序本身如何更新本身的方法代碼

DHT抓取程序開源地址:https://github.com/h31h31/H31DHTDEMOgit

數據處理程序開源地址:https://github.com/h31h31/H31DHTMgrgithub

國外測試服務器: http://www.sosobta.com  你們能夠給提點意見...web

--------------------------------------------------------------------------------------------------------------------小程序

關於自動更新,在.NET下面已是很普通的事情,無非就是在服務器端保存配置好要更新的程序,而後客戶端再寫一個小程序來檢測,有更新的則複製過來。服務器

但如今問題是就一個程序,如何讓程序本身進行更新而不用調用另外的程序,對於用戶來講體驗更好.ide

如何讓程序本身更新本身的方法1:                                                                          

1.首先程序exe本身下載覆蓋本身確定是不行的,會報「當前程序正在被另外一個進程所使用」的系統錯誤;

2.在進程中的程序不能覆蓋本身,可是能夠重命名,你從遠程下載一個新的exe文件,重命名爲xxx.exe.tmp;

3.待下載完畢後,把舊的exe重命名一下,好比xxx.exe.old,而後把新的xxx.exe.tmp重命名爲xxx.exe;

4.重命名的方法:System.IO.File.Move(filepath + ".tmp", filepath);

5.而後重啓程序Application.Restart();在form_Load事件裏面判斷一下
if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + @"xxx.exe.old"))
                System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + @"xxx.exe.old");
這樣就能夠了,若是作的再好點的話,能夠把xxx.exe.old的文件屬性設置爲隱藏就行了.

如何讓程序本身更新本身的方法2:                                                                          

網上搜索的方法: 學習

若是建一個bat文件,執行的是複製功能,而後再用一個bat來調用他,而且用一個bat文件去殺掉某一個文件,而後再複製新的,再啓動是沒有什麼問題的吧。測試

添加了一個方法KillSelfThenRun()用於刪除正在運行的主Exe,而後再重啓新的主Exe。代碼所有粘貼以下:this

 

KillSelfThenRun
private void KillSelfThenRun()
{
string strXCopyFiles = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "XCopyFiles.bat");
using (StreamWriter swXcopy = File.CreateText(strXCopyFiles))
{
string strOriginalPath = tempUpdatePath.Substring(0, tempUpdatePath.Length - 1);
swXcopy.WriteLine(string.Format(@"
@echo off
xcopy /y/s/e/v " + strOriginalPath + " " + Directory.GetCurrentDirectory() +"", AppDomain.CurrentDomain.FriendlyName));
}
string filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "killmyself.bat");
using (StreamWriter bat = File.CreateText(filename))
{
// 自刪除,自啟動
bat.WriteLine(string.Format(@"
@echo off
:selfkill
attrib -a -r -s -h ""{0}""
del ""{0}""
if exist ""{0}"" goto selfkill
call XCopyFiles.bat
del XCopyFiles.bat
del /f/q " + tempUpdatePath+Environment.NewLine + " rd " + tempUpdatePath +Environment.NewLine + " start " + mainAppExe +Environment.NewLine + " del %0 ", AppDomain.CurrentDomain.FriendlyName));
}

// 啓動自刪除批處理文件
ProcessStartInfo info = new ProcessStartInfo(filename);
info.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(info);

// 強制關閉當前進程
Environment.Exit(0);
}

 

第三步調用時,原程序自己就有一個Try的作法,就在Catch裏面判斷一下,若是出現IOException,就調用這個方法。url

 

點擊完成複製更新文件到應用程序目錄
private void btnFinish_Click(object sender, System.EventArgs e)
{
this.Dispose();
//KillSelfThenRun();
try
{
CopyFile(tempUpdatePath, Directory.GetCurrentDirectory());
System.IO.Directory.Delete(tempUpdatePath, true);
}
catch (Exception ex)
{
if (ex.GetType() == typeof(IOException))
{
KillSelfThenRun();
}
else
{
MessageBox.Show(ex.Message.ToString());
}
}
if (true == this.isRun) Process.Start(mainAppExe);
}

 通過分析後仍是以爲第一種方法來得快些,簡單易用:

先看使用方法:

在主程序界面裏面增長一個定時器,而後用來延時來判斷服務器上的程序是否有更新,若是在程序一開始就判斷,程序會加載很慢,從而給用戶體驗很差.

            string m_localPath = AppDomain.CurrentDomain.BaseDirectory;
            string thisexename = Application.ExecutablePath.Replace(m_localPath, "");
            H31Updater update1 = new H31Updater();
            bool isupdate = update1.CheckServerUpdate(m_localPath, thisexename);
            if (isupdate)
            {
                DialogResult dlg = MessageBox.Show(this, "檢測到服務器上有新版本,須要更新麼?", "信息提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dlg == DialogResult.OK)
                {
                    update1.Show();
                    update1.UpdaterStart();
                }
            }

而後程序就會顯示更新進度條:

程序更新後將本身命令爲*.old,而後使用MOVE命令將新的更新爲本身.

服務器上的返回XML文件列表方式:

<?xml version="1.0" encoding="utf-8" ?>  
<AutoUpdater> 
 
  <UpdateInfo id="1">  
    <Version value = "1.0.0.3"/>  
  </UpdateInfo>  
  <!--升級文件列表-->  
  <UpdateFileList>  
    <UpdateFile>software\H31Thunder.exe</UpdateFile>
   <!--能夠複製多行,更新本身目錄下面的程序--> 
  <UpdateFile>software\H31Thunder.exe</UpdateFile>  
</UpdateFileList> </AutoUpdater>

上面配置的XML文件列表能夠複製多行來執行多個更新.

現將本身通過測試的代碼提供給你們討論學習下,但願你們可以用到: 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


using System.Globalization; 
using System.IO; 
using System.Net; 
using System.Xml;
using System.Threading;

namespace H31Thunder
{
    public partial class H31Updater : Form
    {
        private WebClient downWebClient = new WebClient();
        private static string m_exePath = "";
        private static string m_exeName = "";
        private static string m_url = "http://h31bt.com/";
        private static string[] fileNames; 
        private static int m_downNowPos;//已更新文件數 
        private static string fileName;//當前文件名 
        public H31Updater()
        {
            InitializeComponent();
        }

       public bool CheckServerUpdate(string exePath,string exeName) 
       {
           m_exePath = exePath;
           m_exeName = exeName;
           if (File.Exists(m_exePath + m_exeName + ".old"))
               File.Delete(m_exePath + m_exeName + ".old");
           string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
           string theNewVersion = GetTheNewVersion(m_url + "version.asp?id=1");
           if (!String.IsNullOrEmpty(theNewVersion) && !String.IsNullOrEmpty(currentVersion)) 
           { 
               if (string.Compare(theNewVersion,currentVersion)> 0) 
               {
                   return true; 
               } 
           } 
           return false;
       } 

       /// <summary> 
       /// 開始更新 
       /// </summary> 
       public void UpdaterStart() 
       { 
           try 
           { 
               float tempf; 
               //委託下載數據時事件 
               this.downWebClient.DownloadProgressChanged += delegate(object wcsender, DownloadProgressChangedEventArgs ex) 
               { 
                   this.label2.Text = String.Format(CultureInfo.InvariantCulture,"正在下載:{0}  [ {1}/{2} ]",fileName,ConvertSize(ex.BytesReceived),ConvertSize(ex.TotalBytesToReceive));

                   tempf = ((float)(m_downNowPos) / fileNames.Length);
                   this.progressBar2.Value = ex.ProgressPercentage;
                   this.progressBar1.Value = Convert.ToInt32(tempf * 90);
               };
               //委託下載完成時事件 
               this.downWebClient.DownloadFileCompleted += delegate(object wcsender, AsyncCompletedEventArgs ex)
               {
                   if (ex.Error != null)
                   {
                       MeBox(ex.Error.Message);
                   }
                   else
                   {
                       if (fileNames.Length > m_downNowPos)
                       {
                           DownloadFile(m_downNowPos);
                       }
                       else
                       {
                           this.progressBar1.Value = this.progressBar1.Maximum;
                           this.progressBar2.Value = this.progressBar2.Maximum;
                           Thread.Sleep(100);
                           UpdaterClose();
                       }
                   }
               };

               m_downNowPos = 0; 
               if (fileNames != null) 
                   DownloadFile(0);
           }
           catch (WebException ex)
           {
               MeBox(ex.Message);
           } 
       } 

       /// <summary> 
       /// 下載文件 
       /// </summary> 
       /// <param name="arry">下載序號</param> 
       private void DownloadFile(int arry) 
       { 
           try 
           { 
               m_downNowPos++;
               int findpos = fileNames[arry].LastIndexOf("/");
               if (findpos != -1)
                   fileName = fileNames[arry].Substring(findpos+1, fileNames[arry].Length - findpos-1);
               else
                   fileName = fileNames[arry];
               this.label1.Text = String.Format(CultureInfo.InvariantCulture, "更新進度 {0}/{1}", m_downNowPos, fileNames.Length); 

               this.progressBar2.Value = 0;
               string weburl = m_url + fileNames[arry];
               string savename=m_exePath + fileName + ".new";
               this.downWebClient.DownloadFileAsync(new Uri(weburl), savename); 
           } 
           catch (Exception ex) 
           { 
               MeBox(ex.Message); 
           }
       } 


       /// <summary> 
       /// 關閉程序 
       /// </summary> 
       private static void UpdaterClose() 
       {
           try 
           {
               if (File.Exists(m_exePath + m_exeName + ".old"))
                   File.Delete(m_exePath + m_exeName + ".old");
               for(int i=0;i<fileNames.Length;i++)
               {
                   int findpos = fileNames[i].LastIndexOf("/");
                   string savename = fileNames[i];
                   if(findpos!=-1)
                        savename = fileNames[i].Substring(findpos+1, fileNames[i].Length - findpos-1);
                   if (File.Exists(m_exePath + savename + ".old"))
                       File.Delete(m_exePath + savename + ".old");
                   File.Move(m_exePath + savename, m_exePath + savename + ".old");
                   File.Move(m_exePath + savename + ".new", m_exePath + savename);
                   File.SetAttributes(m_exePath + savename + ".old", FileAttributes.Archive | FileAttributes.Hidden); 
               }
           }
           catch (Exception ex) 
           {
               //if (ex.GetType() == typeof(IOException))
               //{

               //}
               //else
                    MeBox(ex.Message); 
           } 

           Application.Exit(); 
       }

       /// <summary> 
       /// 判斷軟件的更新日期 
       /// </summary> 
       /// <param name="Dir">服務器地址</param> 
       /// <returns>返回日期</returns> 
       private static string GetTheNewVersion(string webUrl) 
       { 
           string NewVersion = ""; 
           try 
           { 
               WebClient wc = new WebClient();
               Stream getStream = wc.OpenRead(webUrl);
               StreamReader streamReader = new StreamReader(getStream, Encoding.UTF8);
               string xmltext = streamReader.ReadToEnd();
               streamReader.Close(); 

               XmlDocument xmlDoc = new XmlDocument();
               xmlDoc.InnerXml = xmltext;
               XmlNode root = xmlDoc.SelectSingleNode("//Version");
               if (root.Name == "Version") 
               {
                   NewVersion = root.Attributes["value"].Value.ToString(); 
               }
               XmlNodeList root1 = xmlDoc.SelectNodes("//UpdateFileList");
               if (root1 != null)
               {
                   fileNames = new string[root1.Count];
                   int i=0;
                   foreach (XmlNode temp in root1)
                   {
                       fileNames[i] = temp.InnerText.Replace("\\","/");
                       i++;
                   }
               }

           } 
           catch (WebException ex) 
           { 
               //MeBox(ex.Message); 
           } 
           return NewVersion; 
       }

       /// <summary> 
       /// 彈出提示框 
       /// </summary> 
       /// <param name="txt">輸入提示信息</param> 
       private static void MeBox(string txt)
       {
           MessageBox.Show(txt, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
       }
       /// <summary> 
       /// 轉換字節大小 
       /// </summary> 
       /// <param name="byteSize">輸入字節數</param> 
       /// <returns>返回值</returns> 
       private static string ConvertSize(long byteSize)
       {
           string str = "";
           float tempf = (float)byteSize;
           if (tempf / 1024 > 1)
           {
               if ((tempf / 1024) / 1024 > 1)
               {
                   str = ((tempf / 1024) / 1024).ToString("##0.00", CultureInfo.InvariantCulture) + "MB";
               }
               else
               {
                   str = (tempf / 1024).ToString("##0.00", CultureInfo.InvariantCulture) + "KB";
               }
           }
           else
           {
               str = tempf.ToString(CultureInfo.InvariantCulture) + "B";
           }
           return str;
       } 

    }
}
程序自動更新類代碼

 若是你們有什麼更好的方法,請指教.謝謝.

下載程序:H31Thunder.rar

下一篇給你們介紹上面圖中顯示如何從迅雷服務器上偷用視頻圖片地址的方法.不信的話你們能夠去查看下圖片的 http://www.sosobta.com 網址是否是本身服務器上的... 

固然但願你們多多推薦哦...你們的推薦纔是下一篇介紹的動力...

相關文章
相關標籤/搜索