C# 为应用添加自动更新和运行异常信息捕获

来源:互联网 发布:mac 可以当修容的眼影 编辑:程序博客网 时间:2024/06/08 19:32

示例:

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)NeedToRegisterRegisterPrice(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在运行时,会自动检测版本信息并更新。

0 0
原创粉丝点击