这篇文章主要介绍了用c# 自动更新程序的代码示例,帮助大家更好的理解和使用c#编程语言,感兴趣的朋友可以了解下
作者:冰封一夏
出处:http://www.cnblogs.com/bfyx/
HZHControls官网:http://www.hzhcontrols.com
首先看获取和更新的接口
更新程序Program.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Update
{
static class Program
{
/// <summary>
/// 更新程序启动后复制自身,使用副本进行更新
/// -h 不显示界面
/// -c 不使用copy更新程序
/// -d 更新完成删除自身,通常用在copy的更新程序
/// -b 更新下载到备份文件,不替换原文件
/// -r 更新完成运行的文件,下一个参数为文件路径
/// -k 如果系统正在运行则干掉
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += Application_ThreadException;
List<string> lst = args.ToList();
if (!lst.Contains("-b") && !lst.Contains("-k"))
{
//这里判断成程序是否退出
if (Process.GetProcessesByName("serviceclient").Length > 0)
{
MessageBox.Show("服务正在运行,请退出后重试。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}
if (lst.Contains("-k"))
{
var ps = Process.GetProcessesByName("serviceclient");
if (ps.Length > 0)
{
ps[0].Kill();
}
}
//副本更新程序运行
if (!lst.Contains("-c"))//不存在-c 则进行复制运行
{
string strFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Guid.NewGuid().ToString() + ".exe");
File.Copy(Application.ExecutablePath, strFile);
lst.Add("-c");
lst.Add("-d");
Process.Start(strFile, string.Join(" ", lst));
}
else
{
Action actionAfter = null;
//将更新文件替换到当前目录
if (!lst.Contains("-b"))
{
actionAfter = () =>
{
string strUpdatePath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "UpdateCache\\");
if (Directory.Exists(strUpdatePath) && Directory.GetFiles(strUpdatePath).Length > 0)
{
CopyFile(strUpdatePath, System.AppDomain.CurrentDomain.BaseDirectory, strUpdatePath);
if (File.Exists(Path.Combine(strUpdatePath, "ver.xml")))
File.Copy(Path.Combine(strUpdatePath, "ver.xml"), Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "ver.xml"), true);
Directory.Delete(strUpdatePath, true);
}
};
}
try
{
//隐藏运行
if (!lst.Contains("-h"))
{
Application.Run(new FrmUpdate(actionAfter, true));
}
else
{
FrmUpdate frm = new FrmUpdate(actionAfter);
frm.Down();
}
}
catch (Exception ex)
{ }
//运行更新后的文件
if (lst.Contains("-r"))
{
int index = lst.IndexOf("-r");
if (index + 1 < lst.Count)
{
string strFile = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, lst[index + 1]);
if (File.Exists(strFile))
{
Process.Start(strFile, "-u");
}
}
}
//删除自身
if (lst.Contains("-d"))
{
DeleteItself();
}
}
Application.Exit();
Process.GetCurrentProcess().Kill();
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
throw new NotImplementedException();
}
private static void CopyFile(string strSource, string strTo, string strBasePath)
{
string[] files = Directory.GetFiles(strSource);
foreach (var item in files)
{
string strFileName = Path.GetFileName(item).ToLower();
if (strFileName == "ver.xml ")
{
continue;
}
//如果是版本文件和文件配置xml则跳过,复制完成后再替换这2个文件
string strToPath = Path.Combine(strTo, item.Replace(strBasePath, ""));
var strdir = Path.GetDirectoryName(strToPath);
if (!Directory.Exists(strdir))
{
Directory.CreateDirectory(strdir);
}
File.Copy(item, strToPath, true);
}
string[] dires = Directory.GetDirectories(strSource);
foreach (var item in dires)
{
CopyFile(item, strTo, strBasePath);
}
}
private static void DeleteItself()
{
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 1000 > Nul & Del " + Application.ExecutablePath);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.CreateNoWindow = true;
Process.Start(psi);
}
}
}
更新程序界面
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace HW.Print.ServiceClient.Update
{
public partial class FrmUpdate : Form
{
private static string m_strkey = "sdfadsfdsfasdf";//定义一个密钥用以验证权限,不适用ticket
Random r = new Random();
Action m_actionAfter = null;
bool m_blnShow = false;
public FrmUpdate(Action actionAfter, bool blnShow = false)
{
m_blnShow = blnShow;
m_actionAfter = actionAfter;
InitializeComponent();
}
private void Form1_VisibleChanged(object sender, EventArgs e)
{
if (Visible)
{
var rect = Screen.PrimaryScreen.WorkingArea;
this.Location = new Point(rect.Right - this.Width, rect.Bottom - this.Height);
}
}
private void FrmUpdate_Load(object sender, EventArgs e)
{
Thread th = new Thread(() =>
{
Down();
this.BeginInvoke(new MethodInvoker(delegate ()
{
this.Close();
}));
});
th.IsBackground = true;
th.Start();
}
private string CheckIsXP(string strUrl)
{
bool blnXp = false;
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1)
{
blnXp = true;
}
if (blnXp && strUrl.StartsWith("https"))
{
strUrl = "http" + strUrl.Substring(5);
}
return strUrl;
}
private void SetProcess(string strTitle, int? value, int? maxValue = null)
{
this.lblMsg.BeginInvoke(new MethodInvoker(delegate ()
{
if (maxValue.HasValue)
{
this.progressBar1.Maximum = maxValue.Value;
}
if (value.HasValue)
{
this.progressBar1.Value = value.Value;
}
if (!string.IsNullOrEmpty(strTitle))
{
this.lblMsg.Text = strTitle;
}
lblValue.Text = this.progressBar1.Value + "/" + this.progressBar1.Maximum;
}));
}
public void Down()
{
if (m_blnShow)
SetProcess("正在检查版本", null);
try
{
//先清理掉旧文件
try
{
if (Directory.Exists(System.AppDomain.CurrentDomain.BaseDirectory + "UpdateCache"))
{
Directory.Delete(System.AppDomain.CurrentDomain.BaseDirectory + "UpdateCache", true);
}
}
catch { }
if (!File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + "setting.dat"))
{
Log.WriteLog("配置文件setting.dat不存在!");
return;
}
string strFileUrl = File.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + "setting.dat");
strFileUrl = CheckIsXP(strFileUrl);
//获取列表文件
string json = HttpGet(strFileUrl.Trim('/') + "/getUpdaterList?key=" + Encrypt(m_strkey), Encoding.UTF8);
ResponseMessage rm = fastJSON.JSON.ToObject<ResponseMessage>(json);
if (rm == null)
{
Log.WriteLog("获取更新文件错误");
return;
}
if (!rm.Result)
{
Log.WriteLog("获取更新文件错误:" + rm.ErrorMessage);
return;
}
//云列表
Dictionary<string, DateTime> lstNewFiles = new Dictionary<string, DateTime>();
XmlDocument doc = new XmlDocument();
doc.LoadXml(rm.KeyValue);
var documentElement = doc.DocumentElement;
var nodes = documentElement.SelectNodes("//files/file");
foreach (XmlNode item in nodes)
{
lstNewFiles[item.InnerText] = DateTime.Parse(item.Attributes["time"].Value);
}
List<string> lstUpdateFile = new List<string>();
string locationXml = System.AppDomain.CurrentDomain.BaseDirectory + "ver.xml";
if (!File.Exists(locationXml))
{
lstUpdateFile = lstNewFiles.Keys.ToList();
}
else
{
XmlDocument docLocation = new XmlDocument();
docLocation.Load(locationXml);
var documentElementLocation = docLocation.DocumentElement;
var nodesLocation = documentElementLocation.SelectNodes("//files/file");
foreach (XmlNode item in nodesLocation)
{
if (!lstNewFiles.ContainsKey(item.InnerText))
{
lstUpdateFile.Add(item.InnerText);
}
else if (lstNewFiles[item.InnerText] < DateTime.Parse(item.Attributes["time"].Value))
{
lstUpdateFile.Add(item.InnerText);
}
}
}
if (lstUpdateFile.Count > 0)
{
string strRootPath = System.AppDomain.CurrentDomain.BaseDirectory + "UpdateCache";
if (!System.IO.Directory.Exists(strRootPath))
{
System.IO.Directory.CreateDirectory(strRootPath);
}
SetProcess("", null, lstUpdateFile.Count);
for (int i = 0; i < lstUpdateFile.Count; i++)
{
if (m_blnShow)
SetProcess("正在下载:" + lstUpdateFile[i], i + 1);
string filejson = HttpGet(strFileUrl.Trim('/') + "/downloadUpdaterFile?key=" + Encrypt(m_strkey) + "&file=" + System.Web.HttpUtility.UrlEncode(lstUpdateFile[i]), Encoding.UTF8);
ResponseMessage filerm = fastJSON.JSON.ToObject<ResponseMessage>(filejson);
if (rm == null)
{
Log.WriteLog("下载更新文件错误");
return;
}
if (!rm.Result)
{
Log.WriteLog("下载更新文件错误:" + rm.ErrorMessage);
return;
}
string saveFile = Path.Combine(strRootPath, lstUpdateFile[i]);
if (!Directory.Exists(Path.GetDirectoryName(saveFile)))
{
System.IO.Directory.CreateDirectory(Path.GetDirectoryName(saveFile));
}
string strbase64 = filerm.KeyValue;
MemoryStream stream = new MemoryStream(Convert.FromBase64String(strbase64));
FileStream fs = new FileStream(strRootPath + "\\" + lstUpdateFile[i], FileMode.OpenOrCreate, FileAccess.Write);
byte[] b = stream.ToArray();
fs.Write(b, 0, b.Length);
fs.Close();
}
doc.Save(System.AppDomain.CurrentDomain.BaseDirectory + "UpdateCache//ver.xml");
if (m_actionAfter != null)
{
if (m_blnShow)
SetProcess("替换文件", null);
m_actionAfter();
}
if (m_blnShow)
SetProcess("更新完成。", null);
}
else
{
if (m_blnShow)
SetProcess("没有需要更新的文件。", null);
}
}
catch (Exception ex)
{
if (m_blnShow)
SetProcess("获取更新列表失败:" + ex.Message, null);
Log.WriteLog(ex.ToString());
}
finally
{
if (m_blnShow)
Thread.Sleep(3000);
}
}
private static string encryptKey = "111222333444555666";
//默认密钥向量
private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F };
/// <summary>
/// 加密
/// </summary>
/// <param name="encryptString"></param>
/// <returns></returns>
public static string Encrypt(string encryptString)
{
if (string.IsNullOrEmpty(encryptString))
return string.Empty;
RijndaelManaged rijndaelProvider = new RijndaelManaged();
rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32));
rijndaelProvider.IV = Keys;
ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor();
byte[] inputData = Encoding.UTF8.GetBytes(encryptString);
byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length);
return System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(encryptedData));
}
public static string HttpGet(string url, Encoding encodeing, Hashtable headht = null)
{
HttpWebRequest request;
//如果是发送HTTPS请求
//if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
//{
//ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ServicePoint.Expect100Continue = false;
request.ProtocolVersion = HttpVersion.Version11;
request.KeepAlive = true;
/