網站首頁 編程語言 正文
本文實例為大家分享了Winform使用FTP實現自動更新的具體代碼,供大家參考,具體內容如下
實現思路:在主程序打開前實現判斷是否需要更新(可以通過數據庫表記錄一下版本號或者別的方式記錄是否需要更新),若需要更新時從ftp站點下載更新包(關于配置ftp站點自己可以搜這里不再做詳述)。自己可以制定后綴格式的包或者別的!一般用壓縮包的形式來存放最新程序,將文件下載到本地路徑,在關閉當前程序打開更新程序做解壓替換文件操作,或者可以用批處理文、可執行文件來做操作都行!
1.判斷是否有新版本。
2.通過ftp將更新包下載至本地路徑。
3.打開更新程序(批處理文件或可執行文件)同時關閉所有主程序進程。
4.在更新程序中進行解壓、替換操作。
5.待替換完畢刪除本地更新包(可選)。
6.打開新程序同時關閉所有更新程序進程。
代碼:
1.在程序入口處Program.cs中做判斷:
//判斷版本號是否為數據庫表的版本號
? if (edition == "2021.5.12.0.1")//版本號自己可以判斷
? ? ? ? ? ? {
? ? ? ? ? ? ? ? var resulta = MessageBox.Show("有可用更新,是否更新?", "系統提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
? ? ? ? ? ? ? ? if (resulta == DialogResult.No)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? Application.Run(new Form1());
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? //從服務器獲取新壓縮文件后下載至某一路徑
? ? ? ? ? ? ? ? UpdatateHelp help = new UpdatateHelp();//更新類
? ? ? ? ? ? ? ? help.IP = "xxx.xx.xx.xxx";
? ? ? ? ? ? ? ? help.ServerFile = "OldDemoUpd.zip";
? ? ? ? ? ? ? ? help.User = "Administrator";
? ? ? ? ? ? ? ? help.Password = "*****";
? ? ? ? ? ? ? ? string message = string.Empty;
? ? ? ? ? ? ? ? if (!help.DownloadFile(out message))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? var result = MessageBox.Show(message, "系統提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
? ? ? ? ? ? ? ? ? ? if (result == DialogResult.Yes)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? Application.Run(new Form1());
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? //強制關閉進程 ? ?
? ? ? ? ? ? ? ? ? ? ? ? var proc = System.Diagnostics.Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
? ? ? ? ? ? ? ? ? ? ? ? foreach (Process item in proc)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? item.Kill();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //替換程序文件(用一個update程序負責解壓程序并替換文件,在刪除壓縮文件)
? ? ? ? ? ? ? ? System.Diagnostics.Process.Start(Application.StartupPath + "\\Update\\" + "AutoUpdate.exe");
? ? ? ? ? ? ? ? //關閉當前進程 ??
? ? ? ? ? ? ? ? foreach (Process item in System.Diagnostics.Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? item.Kill();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
2.更新幫助類UpdatateHelp
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace OldDemo
{
? ? class UpdatateHelp
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 服務器IP
? ? ? ? /// </summary>
? ? ? ? public string IP { get; set; }
? ? ? ? /// <summary>
? ? ? ? /// 服務器文件和下載到本地文件名一致
? ? ? ? /// </summary>
? ? ? ? public string ServerFile { get; set; }
? ? ? ? /// <summary>
? ? ? ? /// 服務器用戶名
? ? ? ? /// </summary>
? ? ? ? public string User { get; set; }
? ? ? ? /// <summary>
? ? ? ? /// 服務器密碼
? ? ? ? /// </summary>
? ? ? ? public string Password { get; set; }
? ? ? ? /// <summary>
? ? ? ? /// 下載服務器文件
? ? ? ? /// </summary>
? ? ? ? /// <param name="Message">返回信息</param>
? ? ? ? /// <returns></returns>
? ? ? ? public bool DownloadFile(out string Message)
? ? ? ? {
? ? ? ? ? ? FtpWebRequest reqFTP;
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? FileStream outputStream = new FileStream(Path.GetTempPath()+ ServerFile, FileMode.Create);//本地緩存目錄
? ? ? ? ? ? ? ? reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + IP + "http://"+ ServerFile));
? ? ? ? ? ? ? ? reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;//指定當前請求是什么命令(upload,download,filelist等)
? ? ? ? ? ? ? ? reqFTP.UseBinary = true;//指定文件傳輸的類型
? ? ? ? ? ? ? ? reqFTP.Credentials = new NetworkCredential(User, Password); //指定登錄ftp服務器的用戶名和密碼。
? ? ? ? ? ? ? ? reqFTP.KeepAlive = false;//指定在請求完成之后是否關閉到 FTP 服務器的控制連接
? ? ? ? ? ? ? ? //reqFTP.UsePassive = true;//指定使用主動模式還是被動模式
? ? ? ? ? ? ? ? //reqFTP.Proxy = null;//設置不使用代理
? ? ? ? ? ? ? ? //reqFTP.Timeout = 3000;
? ? ? ? ? ? ? ? FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
? ? ? ? ? ? ? ? Stream ftpStream = response.GetResponseStream();
? ? ? ? ? ? ? ? long cl = response.ContentLength;
? ? ? ? ? ? ? ? int bufferSize = 2048;
? ? ? ? ? ? ? ? int readCount;
? ? ? ? ? ? ? ? byte[] buffer = new byte[bufferSize];
? ? ? ? ? ? ? ? readCount = ftpStream.Read(buffer, 0, bufferSize);
? ? ? ? ? ? ? ? while (readCount > 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? outputStream.Write(buffer, 0, readCount);
? ? ? ? ? ? ? ? ? ? readCount = ftpStream.Read(buffer, 0, bufferSize);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ftpStream.Close();
? ? ? ? ? ? ? ? outputStream.Close();
? ? ? ? ? ? ? ? response.Close();
? ? ? ? ? ? ? ? Message = "下載更新文件成功!";
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception ex)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Message = "下載更新文件失敗!原因:"+ex.Message + " 按是進入原程序,按否關閉程序!";
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ?
? ? ? ? }
? ? }
}
3.關閉主程序進程打開更新程序AutoUpdate.exe,可以在Program中執行也可以在程序中新建一個窗體顯示進度條等!此處用Form1窗體來做解壓處理,需要注意的地方是我引用了using Ionic.Zip;可以在Nuget下搜一下DotNetZip,該dll是針對文件解壓縮幫助類,此只是例舉解壓,有興趣自己研究別的實現!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Ionic.Zip;
namespace AutoUpdate
{
? ? public partial class Form1 : Form
? ? {
? ? ? ? public Form1()
? ? ? ? {
? ? ? ? ? ? InitializeComponent(); ?
? ? ? ? }
? ? ? ? private void Form1_Load(object sender, EventArgs e)
? ? ? ? {
? ? ? ? ? ? StartUpdate();
? ? ? ? }
? ? ? ? void StartUpdate()
? ? ? ? {
? ? ? ? ? ? string FileLoad = System.IO.Path.GetTempPath() + "OldDemoUpd.zip";
? ? ? ? ? ? string IndexLoad = Application.StartupPath + "\\";
? ? ? ? ? ? var lis = IndexLoad.Split('\\').ToList();
? ? ? ? ? ? lis.Remove("");
? ? ? ? ? ? lis.Remove("Update");//由于更新程序沒和主程序目錄同步,所以需要返回到Update文件夾上一級主程序目錄中。
? ? ? ? ? ? IndexLoad = string.Join("\\",lis);
? ? ? ? ? ? //1.解壓臨時文件包到當前路徑并刪除壓縮包
? ? ? ? ? ? if (System.IO.File.Exists(FileLoad))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? label1.Text = "正在解壓軟件更新包...";
? ? ? ? ? ? ? ? //存在就解壓
? ? ? ? ? ? ? ? if (!Decompression(FileLoad, IndexLoad, true))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? MessageBox.Show("解壓更新包失敗,請重試!", "系統提示");
? ? ? ? ? ? ? ? ? ? //關閉當前進程 ??
? ? ? ? ? ? ? ? ? ? foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? item.Kill();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? label1.Text = "正在刪除軟件更新包...";
? ? ? ? ? ? ? ? //刪除壓縮包
? ? ? ? ? ? ? ? System.IO.File.Delete(FileLoad);
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? MessageBox.Show("軟件更新包不存在,請重新打開程序以獲取更新包!", "系統提示");
? ? ? ? ? ? ? ? //關閉當前進程 ??
? ? ? ? ? ? ? ? foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? item.Kill();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? label1.Text = "更新成功,請稍后...";
? ? ? ? ? ? //2.打開更新后程序
? ? ? ? ? ? System.Diagnostics.Process.Start(IndexLoad + "\\" + "OldDemo.exe");
? ? ? ? ? ? //關閉當前進程 ??
? ? ? ? ? ? foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? item.Kill();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 解壓ZIP文件
? ? ? ? /// </summary>
? ? ? ? /// <param name="strZipPath">待解壓的ZIP文件</param>
? ? ? ? /// <param name="strUnZipPath">解壓的目錄</param>
? ? ? ? /// <param name="overWrite">是否覆蓋</param>
? ? ? ? /// <returns>成功:true/失敗:false</returns>
? ? ? ? public static bool Decompression(string strZipPath, string strUnZipPath, bool overWrite)
? ? ? ? {
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ReadOptions options = new ReadOptions();
? ? ? ? ? ? ? ? options.Encoding = Encoding.Default;//設置編碼,解決解壓文件時中文亂碼
? ? ? ? ? ? ? ? using (ZipFile zip = ZipFile.Read(strZipPath, options))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? foreach (ZipEntry entry in zip)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? if (string.IsNullOrEmpty(strUnZipPath))
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? strUnZipPath = strZipPath.Split('.').First();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? if (overWrite)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? entry.Extract(strUnZipPath, ExtractExistingFileAction.OverwriteSilently);//解壓文件,如果已存在就覆蓋
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? entry.Extract(strUnZipPath, ExtractExistingFileAction.DoNotOverwrite);//解壓文件,如果已存在不覆蓋
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
4.需要注意的幾個地方有:
4.1在主程序的生成目錄下創建一個文件夾Update;
4.2把更新程序的生成文件放入Update文件夾下邊,主要是主程序Program中這一段(主程序目錄和更新目錄不是同級):
//替換程序文件(用一個update程序負責解壓程序并替換文件,在刪除壓縮文件)
?System.Diagnostics.Process.Start(Application.StartupPath + "\\Update\\" + "AutoUpdate.exe");
原文鏈接:https://blog.csdn.net/Mwlzx/article/details/116805223
相關推薦
- 2023-06-05 python文件編譯為pyc后運行的實現步驟_python
- 2023-02-03 python關于excel多個sheet的導入導出方式_python
- 2022-06-09 基于Python實現對比Exce的工具_python
- 2022-05-29 C/C++迭代器的失效問題詳解_C 語言
- 2022-10-17 Nginx中root與alias區別講解_nginx
- 2022-12-01 C語言數據在內存中的存儲流程深入分析_C 語言
- 2022-08-12 Android學習之BottomSheetDialog組件的使用_Android
- 2022-05-28 C語言?超詳細講解算法的時間復雜度和空間復雜度_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支