WindowForm实现下载功能,用于软件自动更新
2023-12-28 22:04:55
简介
先上图:
下载完成后删除之前应用
再将下载的包解压保持里面的名字都不变(有快捷方式的情况,不然名子变了就找不到了)
这样就完成了更新的目的,**注意:**这里不是热更新方案,热更新指的是在程序内部将资源、逻辑替换
分析需求
做过Unity的人应该对Window的包不陌生通常是三个文件如下图(部分可能会多,不过无所谓)
把WindowForm的工具放在我们打包出来的exe目录中即可
双击打开Debug
下图是我们自定义的配置文件(根据需求)
Version用来比对是否有新版本进行下载
Version是服务器下载资源名(这里只有一个rar的压缩方式)
DeleteOriginal是原始包文件(下载完删除所有,也就是开篇我说的Window的包)
程序中会找到Debug的上一级目录去删除该资源
上图中蓝色的rar文件就是服务器下载完成的新包(只不过手动将这三个文件压缩成了RAR格式的而已)
双击Update.exe之后就会出现我最开始的简介部分
下图是我上传到服务器的配置文件和新包文件,第三个文件不用管我是我之前测试的用的
具体实现
AppConst.CS
using System.Windows.Forms;
namespace Update
{
public static class AppConst
{
/// <summary>
/// 压缩后缀名
/// </summary>
public static string CondenseEndName = ".rar";
/// <summary>
/// 本地配置文件存放地址
/// </summary>
public static string LocalConfigFilePath = Application.StartupPath + "\\config.ini";
/// <summary>
/// 服务器配置文件路径
/// </summary>
public static string HttpConfigPath = "http://47.101.204.7/Component/FindWord/";
}
}
CondenseHelper.cs
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
namespace Update
{
public class CondenseHelper
{
/// <summary>
/// 解压RAR和ZIP文件(需存在Winrar.exe(只要自己电脑上可以解压或压缩文件就存在Winrar.exe))
/// </summary>
/// <param name="UnPath">解压后文件保存目录</param>
/// <param name="rarPathName">待解压文件存放绝对路径(包括文件名称)</param>
/// <param name="IsCover">所解压的文件是否会覆盖已存在的文件(如果不覆盖,所解压出的文件和已存在的相同名称文件不会共同存在,只保留原已存在文件)</param>
/// <param name="PassWord">解压密码(如果不需要密码则为空)</param>
/// <returns>true(解压成功);false(解压失败)</returns>
public static bool UnRarOrZip(string UnPath, string rarPathName, bool IsCover, string PassWord)
{
if (!Directory.Exists(UnPath))
Directory.CreateDirectory(UnPath);
Process Process1 = new Process();
Process1.StartInfo.FileName = "WinRAR.exe";
Process1.StartInfo.CreateNoWindow = true;
string cmd = "";
if (!string.IsNullOrEmpty(PassWord) && IsCover)
//解压加密文件且覆盖已存在文件( -p密码 )
cmd = string.Format(" x -p{0} -o+ {1} {2} -y", PassWord, rarPathName, UnPath);
else if (!string.IsNullOrEmpty(PassWord) && !IsCover)
//解压加密文件且不覆盖已存在文件( -p密码 )
cmd = string.Format(" x -p{0} -o- {1} {2} -y", PassWord, rarPathName, UnPath);
else if (IsCover)
//覆盖命令( x -o+ 代表覆盖已存在的文件)
cmd = string.Format(" x -o+ {0} {1} -y", rarPathName, UnPath);
else
//不覆盖命令( x -o- 代表不覆盖已存在的文件)
cmd = string.Format(" x -o- {0} {1} -y", rarPathName, UnPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();//无限期等待进程 winrar.exe 退出
//Process1.ExitCode==0指正常执行,Process1.ExitCode==1则指不正常执行
if (Process1.ExitCode == 0)
{
Process1.Close();
return true;
}
else
{
Process1.Close();
return false;
}
}
/// <summary>
/// 压缩文件成RAR或ZIP文件(需存在Winrar.exe(只要自己电脑上可以解压或压缩文件就存在Winrar.exe))
/// </summary>
/// <param name="filesPath">将要压缩的文件夹或文件的绝对路径</param>
/// <param name="rarPathName">压缩后的压缩文件保存绝对路径(包括文件名称)</param>
/// <param name="IsCover">所压缩文件是否会覆盖已有的压缩文件(如果不覆盖,所压缩文件和已存在的相同名称的压缩文件不会共同存在,只保留原已存在压缩文件)</param>
/// <param name="PassWord">压缩密码(如果不需要密码则为空)</param>
/// <returns>true(压缩成功);false(压缩失败)</returns>
public static bool CondenseRarOrZip(string filesPath, string rarPathName, bool IsCover, string PassWord)
{
string rarPath = Path.GetDirectoryName(rarPathName);
if (!Directory.Exists(rarPath))
Directory.CreateDirectory(rarPath);
Process Process1 = new Process();
Process1.StartInfo.FileName = "WinRAR.exe";
Process1.StartInfo.CreateNoWindow = true;
string cmd = "";
if (!string.IsNullOrEmpty(PassWord) && IsCover)
//压缩加密文件且覆盖已存在压缩文件( -p密码 -o+覆盖 )
cmd = string.Format(" a -ep1 -p{0} -o+ {1} {2} -r", PassWord, rarPathName, filesPath);
else if (!string.IsNullOrEmpty(PassWord) && !IsCover)
//压缩加密文件且不覆盖已存在压缩文件( -p密码 -o-不覆盖 )
cmd = string.Format(" a -ep1 -p{0} -o- {1} {2} -r", PassWord, rarPathName, filesPath);
else if (string.IsNullOrEmpty(PassWord) && IsCover)
//压缩且覆盖已存在压缩文件( -o+覆盖 )
cmd = string.Format(" a -ep1 -o+ {0} {1} -r", rarPathName, filesPath);
else
//压缩且不覆盖已存在压缩文件( -o-不覆盖 )
cmd = string.Format(" a -ep1 -o- {0} {1} -r", rarPathName, filesPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();//无限期等待进程 winrar.exe 退出
//Process1.ExitCode==0指正常执行,Process1.ExitCode==1则指不正常执行
if (Process1.ExitCode == 0)
{
Process1.Close();
return true;
}
else
{
Process1.Close();
return false;
}
}
}
}
ConnectHelper.cs
using System;
namespace Update
{
public static class ConnectHelper
{
private const int INTERNET_CONNECTION_MODEM = 1;
private const int INTERNET_CONNECTION_LAN = 2;
[System.Runtime.InteropServices.DllImport("winInet.dll")]
private static extern bool InternetGetConnectedState(ref int dwFlag, int dwReserved);
/// <summary>
/// 判断本地的连接状态
/// </summary>
/// <returns></returns>
public static bool LocalConnectionStatus()
{
System.Int32 dwFlag = new Int32();
if (!InternetGetConnectedState(ref dwFlag, 0))
{
//MessageBox.Show("LocalConnectionStatus--未连网!");
return false;
}
else
{
if ((dwFlag & INTERNET_CONNECTION_MODEM) != 0)
{
//MessageBox.Show("LocalConnectionStatus--采用调制解调器上网。");
return true;
}
else if ((dwFlag & INTERNET_CONNECTION_LAN) != 0)
{
//MessageBox.Show("LocalConnectionStatus--采用网卡上网。");
return true;
}
}
return false;
}
}
}
DelegateConst.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Update
{
#region 委托
/// <summary>
/// 用于指示文件信息(文件大小,当前下载的数量,当前下载的百分比)
/// </summary>
/// <param name="totalNum"></param>
/// <param name="num"></param>
/// <param name="proc"></param>
public delegate void delDownFileHandler(int totalNum, int num, int proc);
/// <summary>
/// 文件下载完成之后
/// </summary>
/// <param name="isCompleted"></param>
public delegate void DelComDownFileHandler(bool isCompleted);
#endregion
}
FileHelper.cs
using System;
using System.IO;
using System.Linq;
namespace Update
{
public static class FileHelper
{
/// <summary>
/// 读取文件
/// </summary>
/// <param name="oldPath"></param>
/// <returns></returns>
public static string GetCurrentConfigFile(string oldPath)
{
if (!File.Exists(oldPath))
{
return null;
}
return File.ReadAllText(oldPath);
}
/// <summary>
/// 删除文件夹
/// </summary>
/// <param name="path"></param>
public static void DeleteDir(string file)
{
try
{
//去除文件夹和子文件的只读属性
//去除文件夹的只读属性
System.IO.DirectoryInfo fileInfo = new DirectoryInfo(file);
fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;
//去除文件的只读属性
System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal);
//判断文件夹是否还存在
if (Directory.Exists(file))
{
foreach (string f in Directory.GetFileSystemEntries(file))
{
if (File.Exists(f))
{
//如果有子文件删除文件
File.Delete(f);
Console.WriteLine(f);
}
else
{
//循环递归删除子文件夹
DeleteDir(f);
}
}
//删除空文件夹
Directory.Delete(file);
}
}
catch (Exception ex) // 异常处理
{
Console.WriteLine(ex.Message.ToString());// 异常信息
}
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="file"></param>
public static void DeleteFile(string file)
{
if (file != null)
{
File.Delete(file);
}
}
/// <summary>
/// 删除文件夹或者文件
/// </summary>
/// <param name="directory"></param>
/// <param name="DeleteOriginal"></param>
public static void DeleteFiles(string directory, string[] DeleteOriginal)
{
for (int i = 0; i < DeleteOriginal.Length; i++)
{
if (DeleteOriginal[i].Contains('.'))
{
DeleteFile(directory + DeleteOriginal[i]);
}
else
{
DeleteDir(directory + DeleteOriginal[i]);
}
}
}
}
}
INIParser.cs
/*******************************
Version: 1.0
Project Boon
*******************************/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
public class INIParser
{
#region "Declarations"
// *** Error: In case there're errors, this will changed to some value other than 1 ***
// Error codes:
// 1: Null TextAsset
public int error = 0;
// *** Lock for thread-safe access to file and local cache ***
private object m_Lock = new object();
// *** File name ***
private string m_FileName = null;
public string FileName
{
get
{
return m_FileName;
}
}
// ** String represent Ini
private string m_iniString = null;
public string iniString
{
get
{
return m_iniString;
}
set
{
m_iniString = value;
}
}
// *** Automatic flushing flag ***
private bool m_AutoFlush = false;
// *** Local cache ***
private Dictionary<string, Dictionary<string, string>> m_Sections = new Dictionary<string, Dictionary<string, string>>();
private Dictionary<string, Dictionary<string, string>> m_Modified = new Dictionary<string, Dictionary<string, string>>();
// *** Local cache modified flag ***
private bool m_CacheModified = false;
#endregion
#region "Methods"
// *** Open ini file by path ***
public void Open(string path)
{
m_FileName = path;
if (File.Exists(m_FileName))
{
m_iniString = File.ReadAllText(m_FileName);
}
else
{
//If file does not exist, create one
var temp = File.Create(m_FileName);
temp.Close();
m_iniString = "";
}
Initialize(m_iniString, false);
}
public void OpenAdd(string content)
{
m_iniString = content;
Initialize(m_iniString, false);
}
// *** Open ini file from string ***
public void OpenFromString(string str)
{
m_FileName = null;
Initialize(str, false);
}
// *** Get the string content of ini file ***
public override string ToString()
{
return m_iniString;
}
private void Initialize(string iniString, bool AutoFlush)
{
m_iniString = iniString;
m_AutoFlush = AutoFlush;
Refresh();
}
// *** Close, save all changes to ini file ***
public void Close()
{
lock (m_Lock)
{
PerformFlush();
//Clean up memory
m_FileName = null;
m_iniString = null;
}
}
// *** Parse section name ***
private string ParseSectionName(string Line)
{
if (!Line.StartsWith("[")) return null;
if (!Line.EndsWith("]")) return null;
if (Line.Length < 3) return null;
return Line.Substring(1, Line.Length - 2);
}
// *** Parse key+value pair ***
private bool ParseKeyValuePair(string Line, ref string Key, ref string Value)
{
// *** Check for key+value pair ***
int i;
if ((i = Line.IndexOf('=')) <= 0) return false;
int j = Line.Length - i - 1;
Key = Line.Substring(0, i).Trim();
if (Key.Length <= 0) return false;
Value = (j > 0) ? (Line.Substring(i + 1, j).Trim()) : ("");
return true;
}
// *** If a line is neither SectionName nor key+value pair, it's a comment ***
private bool isComment(string Line)
{
string tmpKey = null, tmpValue = null;
if (ParseSectionName(Line) != null) return false;
if (ParseKeyValuePair(Line, ref tmpKey, ref tmpValue)) return false;
return true;
}
// *** Read file contents into local cache ***
private void Refresh()
{
lock (m_Lock)
{
StringReader sr = null;
try
{
// *** Clear local cache ***
m_Sections.Clear();
m_Modified.Clear();
// *** String Reader ***
sr = new StringReader(m_iniString);
// *** Read up the file content ***
Dictionary<string, string> CurrentSection = null;
string s;
string SectionName;
string Key = null;
string Value = null;
while ((s = sr.ReadLine()) != null)
{
s = s.Trim();
// *** Check for section names ***
SectionName = ParseSectionName(s);
if (SectionName != null)
{
// *** Only first occurrence of a section is loaded ***
if (m_Sections.ContainsKey(SectionName))
{
CurrentSection = null;
}
else
{
CurrentSection = new Dictionary<string, string>();
m_Sections.Add(SectionName, CurrentSection);
}
}
else if (CurrentSection != null)
{
// *** Check for key+value pair ***
if (ParseKeyValuePair(s, ref Key, ref Value))
{
// *** Only first occurrence of a key is loaded ***
if (!CurrentSection.ContainsKey(Key))
{
CurrentSection.Add(Key, Value);
}
}
}
}
}
finally
{
// *** Cleanup: close file ***
if (sr != null) sr.Close();
sr = null;
}
}
}
private void PerformFlush()
{
// *** If local cache was not modified, exit ***
if (!m_CacheModified) return;
m_CacheModified = false;
// *** Copy content of original iniString to temporary string, replace modified values ***
StringWriter sw = new StringWriter();
try
{
Dictionary<string, string> CurrentSection = null;
Dictionary<string, string> CurrentSection2 = null;
StringReader sr = null;
try
{
// *** Open the original file ***
sr = new StringReader(m_iniString);
// *** Read the file original content, replace changes with local cache values ***
string s;
string SectionName;
string Key = null;
string Value = null;
bool Unmodified;
bool Reading = true;
bool Deleted = false;
string Key2 = null;
string Value2 = null;
StringBuilder sb_temp;
while (Reading)
{
s = sr.ReadLine();
Reading = (s != null);
// *** Check for end of iniString ***
if (Reading)
{
Unmodified = true;
s = s.Trim();
SectionName = ParseSectionName(s);
}
else
{
Unmodified = false;
SectionName = null;
}
// *** Check for section names ***
if ((SectionName != null) || (!Reading))
{
if (CurrentSection != null)
{
// *** Write all remaining modified values before leaving a section ****
if (CurrentSection.Count > 0)
{
// *** Optional: All blank lines before new values and sections are removed ****
sb_temp = sw.GetStringBuilder();
while ((sb_temp[sb_temp.Length - 1] == '\n') || (sb_temp[sb_temp.Length - 1] == '\r'))
{
sb_temp.Length = sb_temp.Length - 1;
}
sw.WriteLine();
foreach (string fkey in CurrentSection.Keys)
{
if (CurrentSection.TryGetValue(fkey, out Value))
{
sw.Write(fkey);
sw.Write('=');
sw.WriteLine(Value);
}
}
sw.WriteLine();
CurrentSection.Clear();
}
}
if (Reading)
{
// *** Check if current section is in local modified cache ***
if (!m_Modified.TryGetValue(SectionName, out CurrentSection))
{
CurrentSection = null;
}
}
}
else if (CurrentSection != null)
{
// *** Check for key+value pair ***
if (ParseKeyValuePair(s, ref Key, ref Value))
{
if (CurrentSection.TryGetValue(Key, out Value))
{
// *** Write modified value to temporary file ***
Unmodified = false;
CurrentSection.Remove(Key);
sw.Write(Key);
sw.Write('=');
sw.WriteLine(Value);
}
}
}
// ** Check if the section/key in current line has been deleted ***
if (Unmodified)
{
if (SectionName != null)
{
if (!m_Sections.ContainsKey(SectionName))
{
Deleted = true;
CurrentSection2 = null;
}
else
{
Deleted = false;
m_Sections.TryGetValue(SectionName, out CurrentSection2);
}
}
else if (CurrentSection2 != null)
{
if (ParseKeyValuePair(s, ref Key2, ref Value2))
{
if (!CurrentSection2.ContainsKey(Key2)) Deleted = true;
else Deleted = false;
}
}
}
// *** Write unmodified lines from the original iniString ***
if (Unmodified)
{
if (isComment(s)) sw.WriteLine(s);
else if (!Deleted) sw.WriteLine(s);
}
}
// *** Close string reader ***
sr.Close();
sr = null;
}
finally
{
// *** Cleanup: close string reader ***
if (sr != null) sr.Close();
sr = null;
}
// *** Cycle on all remaining modified values ***
foreach (KeyValuePair<string, Dictionary<string, string>> SectionPair in m_Modified)
{
CurrentSection = SectionPair.Value;
if (CurrentSection.Count > 0)
{
sw.WriteLine();
// *** Write the section name ***
sw.Write('[');
sw.Write(SectionPair.Key);
sw.WriteLine(']');
// *** Cycle on all key+value pairs in the section ***
foreach (KeyValuePair<string, string> ValuePair in CurrentSection)
{
// *** Write the key+value pair ***
sw.Write(ValuePair.Key);
sw.Write('=');
sw.WriteLine(ValuePair.Value);
}
CurrentSection.Clear();
}
}
m_Modified.Clear();
// *** Get result to iniString ***
m_iniString = sw.ToString();
sw.Close();
sw = null;
// ** Write iniString to file ***
if (m_FileName != null)
{
File.WriteAllText(m_FileName, m_iniString);
}
}
finally
{
// *** Cleanup: close string writer ***
if (sw != null) sw.Close();
sw = null;
}
}
// *** Check if the section exists ***
public bool IsSectionExists(string SectionName)
{
return m_Sections.ContainsKey(SectionName);
}
// *** Check if the key exists ***
public bool IsKeyExists(string SectionName, string Key)
{
Dictionary<string, string> Section;
// *** Check if the section exists ***
if (m_Sections.ContainsKey(SectionName))
{
m_Sections.TryGetValue(SectionName, out Section);
// If the key exists
return Section.ContainsKey(Key);
}
else return false;
}
// *** Delete a section in local cache ***
public void SectionDelete(string SectionName)
{
// *** Delete section if exists ***
if (IsSectionExists(SectionName))
{
lock (m_Lock)
{
m_CacheModified = true;
m_Sections.Remove(SectionName);
//Also delete in modified cache if exist
m_Modified.Remove(SectionName);
// *** Automatic flushing : immediately write any modification to the file ***
if (m_AutoFlush) PerformFlush();
}
}
}
// *** Delete a key in local cache ***
public void KeyDelete(string SectionName, string Key)
{
Dictionary<string, string> Section;
//Delete key if exists
if (IsKeyExists(SectionName, Key))
{
lock (m_Lock)
{
m_CacheModified = true;
m_Sections.TryGetValue(SectionName, out Section);
Section.Remove(Key);
//Also delete in modified cache if exist
if (m_Modified.TryGetValue(SectionName, out Section)) Section.Remove(SectionName);
// *** Automatic flushing : immediately write any modification to the file ***
if (m_AutoFlush) PerformFlush();
}
}
}
// *** Read a value from local cache ***
public string ReadValue(string SectionName, string Key, string DefaultValue)
{
lock (m_Lock)
{
// *** Check if the section exists ***
Dictionary<string, string> Section;
if (!m_Sections.TryGetValue(SectionName, out Section)) return DefaultValue;
// *** Check if the key exists ***
string Value;
if (!Section.TryGetValue(Key, out Value)) return DefaultValue;
// *** Return the found value ***
return Value;
}
}
// *** Insert or modify a value in local cache ***
public void WriteValue(string SectionName, string Key, string Value)
{
lock (m_Lock)
{
// *** Flag local cache modification ***
m_CacheModified = true;
// *** Check if the section exists ***
Dictionary<string, string> Section;
if (!m_Sections.TryGetValue(SectionName, out Section))
{
// *** If it doesn't, add it ***
Section = new Dictionary<string, string>();
m_Sections.Add(SectionName, Section);
}
// *** Modify the value ***
if (Section.ContainsKey(Key)) Section.Remove(Key);
Section.Add(Key, Value);
// *** Add the modified value to local modified values cache ***
if (!m_Modified.TryGetValue(SectionName, out Section))
{
Section = new Dictionary<string, string>();
m_Modified.Add(SectionName, Section);
}
if (Section.ContainsKey(Key)) Section.Remove(Key);
Section.Add(Key, Value);
// *** Automatic flushing : immediately write any modification to the file ***
if (m_AutoFlush) PerformFlush();
}
}
// *** Encode byte array ***
private string EncodeByteArray(byte[] Value)
{
if (Value == null) return null;
StringBuilder sb = new StringBuilder();
foreach (byte b in Value)
{
string hex = Convert.ToString(b, 16);
int l = hex.Length;
if (l > 2)
{
sb.Append(hex.Substring(l - 2, 2));
}
else
{
if (l < 2) sb.Append("0");
sb.Append(hex);
}
}
return sb.ToString();
}
// *** Decode byte array ***
private byte[] DecodeByteArray(string Value)
{
if (Value == null) return null;
int l = Value.Length;
if (l < 2) return new byte[] { };
l /= 2;
byte[] Result = new byte[l];
for (int i = 0; i < l; i++) Result[i] = Convert.ToByte(Value.Substring(i * 2, 2), 16);
return Result;
}
// *** Getters for various types ***
public bool ReadValue(string SectionName, string Key, bool DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, DefaultValue.ToString(System.Globalization.CultureInfo.InvariantCulture));
int Value;
if (int.TryParse(StringValue, out Value)) return (Value != 0);
return DefaultValue;
}
public int ReadValue(string SectionName, string Key, int DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
int Value;
if (int.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
return DefaultValue;
}
public long ReadValue(string SectionName, string Key, long DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
long Value;
if (long.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
return DefaultValue;
}
public double ReadValue(string SectionName, string Key, double DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
double Value;
if (double.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
return DefaultValue;
}
public byte[] ReadValue(string SectionName, string Key, byte[] DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, EncodeByteArray(DefaultValue));
try
{
return DecodeByteArray(StringValue);
}
catch (FormatException)
{
return DefaultValue;
}
}
public DateTime ReadValue(string SectionName, string Key, DateTime DefaultValue)
{
string StringValue = ReadValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
DateTime Value;
if (DateTime.TryParse(StringValue, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AssumeLocal, out Value)) return Value;
return DefaultValue;
}
// *** Setters for various types ***
public void WriteValue(string SectionName, string Key, bool Value)
{
WriteValue(SectionName, Key, (Value) ? ("1") : ("0"));
}
public void WriteValue(string SectionName, string Key, int Value)
{
WriteValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
}
public void WriteValue(string SectionName, string Key, long Value)
{
WriteValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
}
public void WriteValue(string SectionName, string Key, double Value)
{
WriteValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
}
public void WriteValue(string SectionName, string Key, byte[] Value)
{
WriteValue(SectionName, Key, EncodeByteArray(Value));
}
public void WriteValue(string SectionName, string Key, DateTime Value)
{
WriteValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
}
#endregion
}
WebRequestHelper.cs
using System.IO;
using System.Net;
using System.Text;
namespace Update
{
public static class WebRequestHelper
{
/// <summary>
/// 获取服务器比对信息
/// </summary>
/// <returns></returns>
public static string GetHttpConfigFile(string Url)
{
//Get请求中请求参数等直接拼接在url中
WebRequest request = WebRequest.Create(Url);
//返回对Internet请求的响应
WebResponse resp = request.GetResponse();
//从网络资源中返回数据流
Stream stream = resp.GetResponseStream();
StreamReader sr = new StreamReader(stream, Encoding.UTF8);
string result = sr.ReadToEnd();
sr.Dispose();
stream.Dispose();
resp.Dispose();
//将数据流转换文字符串
return result;
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Update
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Init();
}
WebClient wc = new WebClient();
/// <summary>
/// 下载地址
/// </summary>
string m_Address = "";
/// <summary>
/// 存储位置
/// </summary>
string m_SavefileName = "";
/// <summary>
/// 文件下载名
/// </summary>
string DownFileName = "";
/// <summary>
/// 所需删除资源名字
/// </summary>
string[] deleteFileNames = { };
/// <summary>
/// 初始化
/// </summary>
void Init()
{
if (!ConnectHelper.LocalConnectionStatus())
{
MessageBox.Show("请先连接网络!");
}
string newConfig = WebRequestHelper.GetHttpConfigFile(AppConst.HttpConfigPath + "config.ini");
string oldConfig = FileHelper.GetCurrentConfigFile(AppConst.LocalConfigFilePath);
InitINIParser(newConfig);
SetDownLoadPath(AppConst.HttpConfigPath + "config.ini", AppConst.LocalConfigFilePath);
if (newConfig != oldConfig)
{
MessageBox.Show("需要更新!");
FileHelper.DeleteFile(AppConst.LocalConfigFilePath);
loadFile();
}
else
{
MessageBox.Show("不需要更新!");
}
}
/// <summary>
/// 初始化数据层
/// </summary>
void InitINIParser(string content)
{
INIParser ini = new INIParser();
ini.OpenAdd(content);
DownFileName = ini.ReadValue("Setting","NewExeName","");
deleteFileNames = ini.ReadValue("Setting","DeleteOriginal","").Split(',');
}
/// <summary>
/// 按钮回调
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnDownLoad_Click(object sender, EventArgs e)
{
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
progressBar1.Value = 0;
label1.Text = "";
BtnCanel.Enabled = true;
BtnDownLoad.Enabled = false;
SetDownLoadPath(AppConst.HttpConfigPath + DownFileName + AppConst.CondenseEndName,Application.StartupPath + "/" + DownFileName + AppConst.CondenseEndName);
//使用线程启动
Thread td = new Thread(new ThreadStart(loadFile));
td.IsBackground = true;
td.Start();
}
/// <summary>
/// 重置下载路径
/// </summary>
/// <param name="address"></param>
/// <param name="savefileName"></param>
void SetDownLoadPath(string address,string savefileName)
{
m_Address = address;
m_SavefileName = savefileName;
}
/// <summary>
/// 下载文件
/// </summary>
private void loadFile()
{
if (wc.IsBusy)
{
wc.CancelAsync();
}
wc.DownloadFileAsync(new Uri(m_Address), m_SavefileName);
}
/// <summary>
/// 完成更新之后触发的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled)
this.Invoke(new DelComDownFileHandler(comDownFile), new object[] { false });
else
this.Invoke(new DelComDownFileHandler(comDownFile), new object[] { true });
}
/// <summary>
/// 下载完成取消回调
/// </summary>
/// <param name="isCompleted"></param>
private void comDownFile(bool isCompleted)
{
if (isCompleted)
{
int length = Application.StartupPath.LastIndexOf('\\');
string path = Application.StartupPath.Substring(0,length);
FileHelper.DeleteFiles(path + "\\", deleteFileNames);
MessageBox.Show("已经删除原始资源,请点击确认进行解压!");
bool isnew = CondenseHelper.UnRarOrZip(path + "\\", Application.StartupPath + "\\" + DownFileName, true,"");
MessageBox.Show(isnew.ToString());
label1.Text = "下载完成";
}
else
label1.Text = "下载取消";
progressBar1.Value = 0;
BtnDownLoad.Enabled = true;
BtnCanel.Enabled = false;
}
/// <summary>
/// 更新过程中触发的事件(在线程中不能直接操纵控件,因此用委托执行)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.Invoke(new delDownFileHandler(processShow), new object[] { (int)e.TotalBytesToReceive, (int)e.BytesReceived, e.ProgressPercentage });
}
/// <summary>
/// 委托执行 (进度条和字符标识)
/// </summary>
/// <param name="totalNum"></param>
/// <param name="num"></param>
/// <param name="proc"></param>
private void processShow(int totalNum, int num, int proc)
{
progressBar1.Maximum = totalNum;
progressBar1.Value = num;
label1.Text = "正在下载:" + (num / (1024)).ToString() + "KB/" + (totalNum / 1024).ToString() + "KB " + proc.ToString() + "%";
}
/// <summary>
/// 点击取消后
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnCanel_Click(object sender, EventArgs e)
{
wc.CancelAsync();
wc.Dispose();
}
}
}
总结
这里用到的工具比较多,我都封装了工具类,WindowForm的控件拖拽和事件处理我就不说了,去官网可以查到点击事件和Label的案例。
文章来源:https://blog.csdn.net/qq_42194657/article/details/135277930
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!