欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
C# 为应用添加自动更新和运行异常信息捕获
2017/3/10
南通科迅教育
318
南通Java培训|如何选择一家靠谱Java培训机构

示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace FileExtractionTool
{
    staticclassProgram
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        staticvoidMain()
        {
            ApplicationException.Run(call);    // 调用异常信息捕获类,进行异常信息的捕获
        }
 
        // 应用程序,入口逻辑
        publicstaticvoidcall()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if(Update.Updated()) Application.Run(newForm1());
        }
    }
 
}

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
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
{
 
    classUpdate
    {
        //public static string ToolsName = "easyIcon";                          // 工具名称
        staticstring ToolsName ="FileExtractionTool(文件提取检测工具)";    // 工具名称
        staticlongcurVersion =20160810;                                     // 记录当前软件版本信息
 
 
        /// <summary>
        /// 检查工具是否已是最新版本, 不是则自动更新
        /// </summary>
        publicstaticbool 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(""))returntrue;
 
                // 获取版本更新信息
                longlastVersion =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);
 
                            returnfalse;
                        }
                        elseMessageBox.Show("未找到更新插件:\r\n"+ update_EXE);
                    }
                }
 
                returntrue;
            }
            catch(Exception ex) {returntrue; } // 未获取到版本信息
        }
 
        // 检测更新插件UpdateFiles.exe是否存在,更新替换文件逻辑
        privatestaticvoidCheckUpdateEXE()
        {
            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>
        publicstaticvoidSaveFile(Byte[] array, string path)
        {
            // 创建输出流
            System.IO.FileStream fs =newSystem.IO.FileStream(path, System.IO.FileMode.Create);
 
            //将byte数组写入文件中
            fs.Write(array,0, array.Length);
            fs.Close();
        }
 
        /// <summary>
        /// 更新文件逻辑,判定文件是否处于运行状态,关闭并删除后,创建新的文件
        /// </summary>
        privatestaticvoidoutPutFile(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>
        publicstaticvoidKillProcess(string processName)
        {
            Process[] processes = Process.GetProcessesByName(processName);
 
            foreach (Process process in processes)
            {
                if(process.MainModule.FileName == processName)
                {
                    process.Kill();
                }
            }
        }
 
        /// <summary>
        /// 获取应用的当前工作路径
        /// </summary>
        publicstaticString curDir()
        {
            string CurDir = System.AppDomain.CurrentDomain.BaseDirectory;
            returnCurDir;
        }
    }
 
 
 
    // ------------------------------------------------------------------------------------
 
 
    // 示例:scimence( Name1(6JSO-F2CM-4LQJ-JN8P) )scimence
    //
    // string data = getWebData(url);
    // string str1 = getNodeData(data, "scimence", false);
    // string str2 = getNodeData(str1, "Name1", true);
 
    /// <summary>
    /// 此类用于获取,在网络文件中的配置信息
    /// </summary>
    classWebSettings
    {
        #region 网络数据的读取
 
        //从给定的网址中获取数据
        publicstaticstring getWebData(string url)
        {
            try
            {
                System.Net.WebClient client =newSystem.Net.WebClient();
                client.Encoding = System.Text.Encoding.Default;
                string data = client.DownloadString(url);
                returndata;
            }
            catch(Exception) {return""; }
        }
 
        #endregion
 
 
        // 从自定义格式的数据data中,获取nodeName对应的节点数据
        //p>scimence(
NeedToRegister(false)NeedToRegister
RegisterPrice(1)RegisterPrice
)scimence<p> </p>
 
        // NeedToRegister(false)
RegisterPrice(1)   finalNode的数据格式
        publicstaticstring getNodeData(string data, string nodeName, bool finalNode)
        {
            try
            {
                string S = nodeName +"(", E =")"+ (finalNode ?"": nodeName);
                intindexS = data.IndexOf(S) + S.Length;
                intindexE = data.IndexOf(E, indexS);
 
                returndata.Substring(indexS, indexE - indexS);
            }
            catch(Exception) {returndata; }
        }
    }
 
 
 
    // ------------------------------------------------------------------------------------
 
 
    /// <summary>
    /// 此类用于实现对注册表的操作
    /// </summary>
    classRegistry
    {
        # region 注册表操作
        //设置软件开机启动项: RegistrySave(@"Microsoft\Windows\CurrentVersion\Run", "QQ", "C:\\windows\\system32\\QQ.exe"); 
 
        /// <summary>
        /// 记录键值数据到注册表subkey = @"Scimence\Email\Set";
        /// </summary>
        publicstaticvoidRegistrySave(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>
        publicstaticstring RegistryStrValue(string subkey, string name)
        {
            object value = RegistryValue(subkey, name);
            returnvalue ==null?"": value.ToString();
        }
 
        /// <summary>
        /// 获取注册表subkey下键name的值
        /// <summary>
        publicstaticobject 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>
        publicstaticbool RegistryCotains(string subkey)
        {
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey,true);
            return(keySet !=null);
        }
 
        /// <summary>
        /// 判断注册表subkey下是否含有name键值信息
        /// <summary>
        publicstaticbool RegistryCotains(string subkey, string name)
        {
            //设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey,true);
 
            if(keySet ==null)returnfalse;
            elsereturnkeySet.GetValueNames().Contains<string>(name);
        }
 
        /// <summary>
        /// 删除注册表subkey信息
        /// <summary>
        publicstaticvoidRegistryRemove(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>
        publicstaticvoidRegistryRemove(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>
    classApplicationException
    {
        /// <summary>
        /// 定义委托接口处理函数,调用此类中的Main函数为应用添加异常信息捕获
        /// </summary>
        publicdelegatevoidExceptionCall();
 
        publicstaticvoidRun(ExceptionCall exCall)
        {
            try
            {
                //设置应用程序处理异常方式:ThreadException处理
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                //处理UI线程异常
                Application.ThreadException +=newSystem.Threading.ThreadExceptionEventHandler(Application_ThreadException);
                //处理非UI线程异常
                AppDomain.CurrentDomain.UnhandledException +=newUnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
 
                if(exCall !=null) exCall();
            }
            catch(Exception ex)
            {
                string str = GetExceptionMsg(ex, string.Empty);
                MessageBox.Show(str,"系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
 
 
        staticvoidApplication_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);
        }
 
        staticvoidCurrentDomain_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 name="backStr">备用异常消息:当ex为null时有效
        /// <returns>异常字符串文本</returns>
        staticstring GetExceptionMsg(Exception ex, string backStr)
        {
            StringBuilder sb =newStringBuilder();
            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();     // 捕获运行异常后,检测是否有版本更新
 
            returnsb.ToString();
        }
    }
}</summary></summary></summary></summary></string></summary></summary></summary></summary></summary></summary></summary></summary></byte>

 

将Update.exe修改后缀名,作为Resource资源添加到工程中

加载中...

在Update.cs中指定versionInfo.txt文件,在versionInfo.txt设定工具在线更新地址。update.exe在运行时,会自动检测版本信息并更新。

77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-