DHT抓取程序開源地址:https://github.com/h31h31/H31DHTDEMO
數據處理程序開源地址:https://github.com/h31h31/H31DHTMgr
國外測試服務器: http://www.sosobta.com 大家可以給提點意見...
--------------------------------------------------------------------------------------------------------------------
關於自動更新,在.NET下面已經是很普通的事情,無非就是在服務器端保存配置好要更新的程序,然后客戶端再寫一個小程序來檢測,有更新的則復制過來。
但現在問題是就一個程序,如何讓程序自己進行更新而不用調用另外的程序,對於用戶來說體驗更好.
如何讓程序自己更新自己的方法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。代碼全部粘貼如下:
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,就調用這個方法。
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 網址是不是自己服務器上的...
當然希望大家多多推薦哦...大家的推薦才是下一篇介紹的動力...