示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FileExtractionTool
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
ApplicationException.Run(call); // 调用异常信息捕获类,进行异常信息的捕获
}
// 应用程序,入口逻辑
public static void call()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (Update.Updated()) Application.Run(new Form1());
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FileExtractionTool
{
class Update
{
//public static string ToolsName = "easyIcon"; // 工具名称
static string ToolsName = "FileExtractionTool(文件提取检测工具)"; // 工具名称
static long curVersion = 20160810; // 记录当前软件版本信息
/// <summary>
/// 检查工具是否已是最新版本, 不是则自动更新
/// </summary>
public static bool Updated()
{
try
{
// 获取版本配置信息 示例:scimence( Name1(6JSO-F2CM-4LQJ-JN8P) )scimence
string VersionInfo = WebSettings.getWebData("https://git.oschina.net/scimence/fileExtractionTool/raw/master/files/versionInfo.txt");
if (VersionInfo.Equals("")) return true;
// 获取版本更新信息
long lastVersion = long.Parse(WebSettings.getNodeData(VersionInfo, "version", true));
string url = WebSettings.getNodeData(VersionInfo, "url", true);
// 检测到新的版本
if (lastVersion > curVersion)
{
bool ok = (MessageBox.Show("检测到新的版本,现在更新?", "版本更新", MessageBoxButtons.OKCancel) == DialogResult.OK);
if (ok)
{
CheckUpdateEXE();
// 获取更新插件名
string update_EXE = curDir() + "UpdateFiles.exe";
if (System.IO.File.Exists(update_EXE))
{
// 获取url中对应的文件名
string fileName = curDir() + System.IO.Path.GetFileName(url);
// 生成更新时的显示信息
String info = "当前版本:" + curVersion + "\r\n" + "最新版本:" + lastVersion + "\r\n";
// 调用更新插件执行软件更新逻辑
String arg = "\"" + url + "\"" + " " + "\"" + fileName + "\"" + " " + "true" + " " + "\"" + info + "\"";
System.Diagnostics.Process.Start(update_EXE, arg);
return false;
}
else MessageBox.Show("未找到更新插件:\r\n" + update_EXE);
}
}
return true;
}
catch (Exception ex) { return true; } // 未获取到版本信息
}
// 检测更新插件UpdateFiles.exe是否存在,更新替换文件逻辑
private static void CheckUpdateEXE()
{
string info = "更新UpdateFiles.exe\r\n";
// 若文件不存在则自动创建
string file1 = curDir() + "UpdateFiles.exe";
string key = @"Scimence\" + ToolsName + @"\Set";
string value = Registry.RegistryStrValue(key, "文件更新");
if (!value.Contains(info) || !System.IO.File.Exists(file1))
{
Registry.RegistrySave(key, "文件更新", info);
// UpdateFiles.exe文件资源 https://git.oschina.net/scimence/UpdateFiles/raw/master/files/UpdateFiles.exe
Byte[] array = Properties.Resources.UpdateFiles.ToArray<Byte>();
SaveFile(array, file1);
}
}
/// <summary>
/// 保存Byte数组为文件
/// </summary>
public static void SaveFile(Byte[] array, string path)
{
// 创建输出流
System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Create);
//将byte数组写入文件中
fs.Write(array, 0, array.Length);
fs.Close();
}
/// <summary>
/// 更新文件逻辑,判定文件是否处于运行状态,关闭并删除后,创建新的文件
/// </summary>
private static void outPutFile(Byte[] array, string pathName)
{
// 若文件正在运行,则从进程中关闭
string fileName = System.IO.Path.GetFileName(pathName);
KillProcess(fileName);
// 删除原有文件
if (System.IO.File.Exists(pathName)) System.IO.File.Delete(pathName);
// 保存新的文件
SaveFile(array, pathName);
}
/// <summary>
/// 关闭名称为processName的所有进程
/// </summary>
public static void KillProcess(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
foreach (Process process in processes)
{
if (process.MainModule.FileName == processName)
{
process.Kill();
}
}
}
/// <summary>
/// 获取应用的当前工作路径
/// </summary>
public static String curDir()
{
string CurDir = System.AppDomain.CurrentDomain.BaseDirectory;
return CurDir;
}
}
// ------------------------------------------------------------------------------------
// 示例:scimence( Name1(6JSO-F2CM-4LQJ-JN8P) )scimence
// string url = "https://git.oschina.net/scimence/easyIcon/wikis/OnlineSerial";
//
// string data = getWebData(url);
// string str1 = getNodeData(data, "scimence", false);
// string str2 = getNodeData(str1, "Name1", true);
/// <summary>
/// 此类用于获取,在网络文件中的配置信息
/// </summary>
class WebSettings
{
#region 网络数据的读取
//从给定的网址中获取数据
public static string getWebData(string url)
{
try
{
System.Net.WebClient client = new System.Net.WebClient();
client.Encoding = System.Text.Encoding.Default;
string data = client.DownloadString(url);
return data;
}
catch (Exception) { return ""; }
}
#endregion
// 从自定义格式的数据data中,获取nodeName对应的节点数据
//p>scimence(
NeedToRegister(false)NeedToRegister
RegisterPrice(1)RegisterPrice
)scimence</p>
</div>
// NeedToRegister(false)
RegisterPrice(1) finalNode的数据格式
public static string getNodeData(string data, string nodeName, bool finalNode)
{
try
{
string S = nodeName + "(", E = ")" + (finalNode ? "" : nodeName);
int indexS = data.IndexOf(S) + S.Length;
int indexE = data.IndexOf(E, indexS);
return data.Substring(indexS, indexE - indexS);
}
catch (Exception) { return data; }
}
}
// ------------------------------------------------------------------------------------
/// <summary>
/// 此类用于实现对注册表的操作
/// </summary>
class Registry
{
# region 注册表操作
//设置软件开机启动项: RegistrySave(@"Microsoft\Windows\CurrentVersion\Run", "QQ", "C:\\windows\\system32\\QQ.exe");
/// <summary>
/// 记录键值数据到注册表subkey = @"Scimence\Email\Set";
/// </summary>
public static void RegistrySave(string subkey, string name, object value)
{
//设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
Microsoft.Win32.RegistryKey keyCur = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
if (keySet == null) keySet = keyCur.CreateSubKey(subkey); //键不存在时创建
keySet.SetValue(name, value); //保存键值数据
}
/// <summary>
/// 获取注册表subkey下键name的字符串值
/// <summary>
public static string RegistryStrValue(string subkey, string name)
{
object value = RegistryValue(subkey, name);
return value == null ? "" : value.ToString();
}
/// <summary>
/// 获取注册表subkey下键name的值
/// <summary>
public static object RegistryValue(string subkey, string name)
{
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
return (keySet == null ? null : keySet.GetValue(name, null));
}
/// <summary>
/// 判断注册表是否含有子键subkey
/// <summary>
public static bool RegistryCotains(string subkey)
{
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
return (keySet != null);
}
/// <summary>
/// 判断注册表subkey下是否含有name键值信息
/// <summary>
public static bool RegistryCotains(string subkey, string name)
{
//设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
if (keySet == null) return false;
else return keySet.GetValueNames().Contains<string>(name);
}
/// <summary>
/// 删除注册表subkey信息
/// <summary>
public static void RegistryRemove(string subkey)
{
//设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
Microsoft.Win32.RegistryKey keyCur = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
if (keySet != null) keyCur.DeleteSubKeyTree(subkey); //删除注册表信息
}
/// <summary>
/// 删除注册表subkey下的name键值信息
/// <summary>
public static void RegistryRemove(string subkey, string name)
{
//设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
if (keySet != null) keySet.DeleteValue(name, false);
}
# endregion
}
// ------------------------------------------------------------------------------------
// 示例:Program.cs
//static class Program
//{
// /// <summary>
// /// 应用程序的主入口点。
// /// </summary>
// [STAThread]
// static void Main()
// {
// ApplicationException.Run(call); // 调用异常信息捕获类,进行异常信息的捕获
// }
// // 应用程序,入口逻辑
// public static void call()
// {
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// if (Update.Updated())
// {
// DependentFiles.checksAll(); // 检测工具运行依赖文件
// ToolSetting.Instance(); // 载入工具的配置信息
// Application.Run(new Form4());
// }
// }
//}
/// <summary>
/// 此类用于捕获Application异常信息
/// </summary>
class ApplicationException
{
/// <summary>
/// 定义委托接口处理函数,调用此类中的Main函数为应用添加异常信息捕获
/// </summary>
public delegate void ExceptionCall();
public static void Run(ExceptionCall exCall)
{
try
{
//设置应用程序处理异常方式:ThreadException处理
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
//处理UI线程异常
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
//处理非UI线程异常
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
if (exCall != null) exCall();
}
catch (Exception ex)
{
string str = GetExceptionMsg(ex, string.Empty);
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
string str = GetExceptionMsg(e.Exception, e.ToString());
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
//bool ok = (MessageBox.Show(str, "系统错误,提交bug信息?", MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.OK);
//if (ok) sendBugToAuthor(str);
Update.Updated(); // 捕获运行异常后,检测是否有版本更新
//LogManager.WriteLog(str);
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string str = GetExceptionMsg(e.ExceptionObject as Exception, e.ToString());
MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
//bool ok = (MessageBox.Show(str, "系统错误,提交bug信息?", MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.OK);
//if (ok) sendBugToAuthor(str);
Update.Updated(); // 捕获运行异常后,检测是否有版本更新
//LogManager.WriteLog(str);
}
/// <summary>
/// 生成自定义异常消息
/// </summary>
/// <param name="ex">异常对象</param>
/// <param name="backStr">备用异常消息:当ex为null时有效</param>
/// <returns>异常字符串文本</returns>
static string GetExceptionMsg(Exception ex, string backStr)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("****************************异常文本****************************");
sb.AppendLine("【出现时间】:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
if (ex != null)
{
sb.AppendLine("【异常类型】:" + ex.GetType().Name);
sb.AppendLine("【异常信息】:" + ex.Message);
sb.AppendLine("【堆栈调用】:" + ex.StackTrace);
sb.AppendLine("【异常方法】:" + ex.TargetSite);
}
else
{
sb.AppendLine("【未处理异常】:" + backStr);
}
sb.AppendLine("***************************************************************");
Update.Updated(); // 捕获运行异常后,检测是否有版本更新
return sb.ToString();
}
}
}
将Update.exe修改后缀名,作为Resource资源添加到工程中
在Update.cs中指定versionInfo.txt文件,在versionInfo.txt设定工具在线更新地址。update.exe在运行时,会自动检测版本信息并更新。