• 【原创】 c#单文件绿色资源自更新


    先引用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         }
  • 相关阅读:
    npm start报错
    npm install 错误
    vue父子组件间传值
    vue-devtools安装过程的坑
    用js进行排序
    筛选表格数据
    基于ElementUI封装可复用的表格组件
    小程序头部滑动切换
    DisneyDiffuse解析
    基于URP的ScreenSpaceDecal的实现(其实和URP没啥关系)
  • 原文地址:https://www.cnblogs.com/yzpopulation/p/7093376.html
Copyright © 2020-2023  润新知