先引用dnlib.dll 更新程序先fody成一个文件
放置主程序资源文件 更新程序.exe
1 #region 2 3 using System; 4 using System.Diagnostics; 5 using System.IO; 6 using System.Linq; 7 using System.Runtime.InteropServices; 8 using System.Text; 9 using dnlib.DotNet; 10 using dnlib.DotNet.Resources; 11 using dnlib.DotNet.Writer; 12 using dnlib.IO; 13 14 #endregion 15 16 namespace 更新程序 17 { 18 internal class Program 19 { 20 private static string FileExt { get; set; } 21 private static string Filename { get; set; } 22 private static void Main() 23 { 24 FileExt = Path.GetExtension(Properties.Resources.FileName); 25 Filename = Path.GetFileNameWithoutExtension(Properties.Resources.FileName); 26 UpDateResx(); 27 DeleteItself(); 28 } 29 30 public static void UpDateResx() 31 { 32 string path = Properties.Resources.FileName; 33 string resxName = Properties.Resources.Name; 34 string resxValue = Properties.Resources.Value; 35 var processes = Process.GetProcesses(); 36 Stopwatch st = new Stopwatch(); 37 st.Start(); 38 39 while (processes.FirstOrDefault(s => Filename == s.ProcessName) != null) 40 { 41 if (st.Elapsed > TimeSpan.FromSeconds(10)) 42 { 43 return; 44 } 45 } 46 47 48 ModuleDefMD module = ModuleDefMD.Load(path); 49 50 EmbeddedResource resx = 51 (EmbeddedResource) module.Resources.Find(module.Assembly.Name + ".Properties.Resources.resources"); 52 53 ResourceElementSet elementSet = ResourceReader.Read(module, resx.Data); 54 try 55 { 56 ResourceElement element = elementSet.ResourceElements.First(s => s.Name == resxName); 57 element.ResourceData = new BuiltInResourceData(ResourceTypeCode.String, resxValue); 58 elementSet.Add(element); 59 60 MemoryStream ms = new MemoryStream(); 61 ResourceWriter.Write(module, ms, elementSet); 62 resx.Data = new MemoryImageStream(0, ms.GetBuffer(), 0, ms.GetBuffer().Length); 63 64 if (module.IsILOnly) 65 module.Write(Filename+"_tmp"+FileExt, new ModuleWriterOptions(module)); 66 else 67 module.NativeWrite(Filename + "_tmp" + FileExt); 68 } 69 catch (Exception e) 70 { 71 Console.WriteLine(e); 72 return; 73 } 74 module.Dispose(); 75 76 77 } 78 79 80 /// <summary> 81 /// 删除程序自身(本文地址:http://www.cnblogs.com/Interkey/p/DeleteItself.html)【推荐】 82 /// </summary> 83 private static void DeleteItself() 84 { 85 string selfName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName); 86 string vBatFile = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + "\DeleteItself.bat"; 87 using (StreamWriter vStreamWriter = new StreamWriter(vBatFile, false, Encoding.Default)) 88 { 89 vStreamWriter.Write(":move " + 90 $" move /Y {Filename}_tmp{FileExt} {Filename}{FileExt} " + 91 $"if exist {Filename}_tmp{FileExt} goto move " + 92 ":del " + 93 $" del {selfName} " + 94 $"if exist {selfName} goto del " + 95 "del %0 "); 96 } 97 98 //************ 执行批处理 99 WinExec(vBatFile, 0); 100 //************ 结束退出 101 Environment.Exit(0); 102 } 103 104 105 [DllImport("kernel32.dll")] 106 public static extern uint WinExec(string lpCmdLine, uint uCmdShow); 107 } 108 }
主程序结束时中使用下列方法自更新资源
1 public static void WriteUpdate(string name,string value) 2 { 3 string selfName =Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName); 4 5 ModuleDefMD module = ModuleDefMD.Load(Properties.Resources.更新程序); 6 7 EmbeddedResource resx = 8 (EmbeddedResource)module.Resources.Find(module.Assembly.Name + ".Properties.Resources.resources"); 9 10 ResourceElementSet elementSet = dnlib.DotNet.Resources.ResourceReader.Read(module, resx.Data); 11 try 12 { 13 ResourceElement element = elementSet.ResourceElements.First(s => s.Name == "FileName"); 14 element.ResourceData = new BuiltInResourceData(ResourceTypeCode.String, selfName); 15 elementSet.Add(element); 16 17 ResourceElement element1 = elementSet.ResourceElements.First(s => s.Name == "Name"); 18 element1.ResourceData = new BuiltInResourceData(ResourceTypeCode.String, name); 19 elementSet.Add(element1); 20 21 ResourceElement element2 = elementSet.ResourceElements.First(s => s.Name == "Value"); 22 element2.ResourceData = new BuiltInResourceData(ResourceTypeCode.String, value); 23 elementSet.Add(element2); 24 25 26 MemoryStream ms = new MemoryStream(); 27 dnlib.DotNet.Resources.ResourceWriter.Write(module, ms, elementSet); 28 resx.Data = new MemoryImageStream(0, ms.GetBuffer(), 0, ms.GetBuffer().Length); 29 30 if (module.IsILOnly) 31 module.Write("更新程序.exe", new ModuleWriterOptions(module)); 32 else 33 module.NativeWrite("更新程序.exe"); 34 } 35 catch (Exception e) 36 { 37 Console.WriteLine(e); 38 return; 39 } 40 module.Dispose(); 41 ProcessStartInfo psi = new ProcessStartInfo("更新程序.exe"); 42 psi.WindowStyle = ProcessWindowStyle.Hidden; 43 psi.CreateNoWindow = true; 44 Process.Start(psi); 45 Environment.Exit(0); 46 }