C#WPF程序实现打开后版本自动更新(.net4.0以上)

##C# WPF程序实现打开版本自动更新
由于项目需要,需要实现本地的WPF软件开启后自动检测版本,并进行版本的更新。
下面分享一下这部分功能实现的逻辑和代码,比较简单,但能实现功能。
A程序为目标程序(即要被更新的程序),B程序为版本更新程序。
先写一个简单的A程序界面:
在这里插入图片描述

然后在A程序后端代码中调用B程序:

    public partial class MainWindow : Window
    {
    
    
        public MainWindow()
        {
    
    
            InitializeComponent();

            //获取当前软件版本(用以在B程序中对比软件版本是否有更新),程序路径(用以在B程序中将文件拷贝到此路径下), 程序名字(用以在B程序中Kill掉A)
            var version = Application.ResourceAssembly.GetName().Version.ToString();
            var dirPath = System.IO.Directory.GetCurrentDirectory();
            var exeName = this.GetType().Assembly.Location.Substring(dirPath.Length+1).Split('.');

            //获得B程序的启动程序路径
            var path = @"C:\Fan021\Code\Practise\VersionUpdate\VersionUpdateTool\VersionUpdateTool\bin\Debug\VersionUpdateTool.exe";
            //合并参数传入B程序中
            var para = dirPath+' '+ exeName[0] + ' ' + version;

            //以下代码用以Run起B程序
            ProcessStartInfo versionUpdatePrp = new ProcessStartInfo(path, para);
            Process newProcess = new Process();
            newProcess.StartInfo = versionUpdatePrp;
            newProcess.Start();

        }
    }

至此,A端程序代码完成,主要的版本检测和版本更新由B程序完成。

B程序也为WPF项目,创建完项目后在App.xaml中重写OnStartup方法,用以接收A程序传过来的参数:
在这里插入图片描述

   public partial class App : Application
    {
    
    
        //创建静态变量给后台程序调用
        public static string[] Args= {
    
    };

        protected override void OnStartup(StartupEventArgs e)
        {
    
    
            if (e.Args != null && e.Args.Count() > 0)
            {
    
    
                //将A传过来的参数赋给上面创建的静态变量Args
                Args = e.Args;
            }
            base.OnStartup(e);
        }
    }

随后简单的绘制B程序的界面:
在这里插入图片描述
在B程序后台构造函数中,获取要更新的版本号,可以从数据库,XML或其他配置文件中获取,这里不写详细获取过程,各位小伙伴按自己需求获取就行。A程序版本为1.0.0.0,这里为了触发版本更新,模拟获取的版本为1.0.0.1。

   public MainWindow()
        {
    
    
            InitializeComponent();

            if (App.Args.Count() != 0)
            {
    
    
                //获取最新的软件版本,可以从数据库或配置文件中获得,此处省略获得过程,只模拟“1.0.0.1“;
                var newVersion = "1.0.0.1";

                //对比版本是否需要更新
                if (App.Args[2] != newVersion)
                {
    
    
                    //以下为在界面上显示的信息
                    this.Topmost = true;
                    Message.Text += ("发现新的版本:" + newVersion + "\r\n");
                    Message.Text += ("目前软件的版本为:" + App.Args[2] + "\r\n");
                    Message.Text += ("请确认是否更新?" + "\r\n");
                }
                else
                {
    
    
                    this.Close();
                }

            }
        }

这里说明一下,App.Args这个数组中包含着所有A程序传过来的参数,App.Args[0]对应A程序中dirPath变量,储存A程序的文件夹路径,App.Args[1]对应A程序中exeName变量,储存A程序启动程序的名字,App.Args[2]对应A程序中的version变量,对应A程序目前的版本号。

B程序中更新按钮的click事件代码如下,逻辑见注释:

   private void Update_Click(object sender, RoutedEventArgs e)
        {
    
    
            try
            {
    
    
                //通过A传递的启动程序名kill掉A程序
                Process[] processes = Process.GetProcessesByName(App.Args[1]);
                foreach (var item in processes)
                {
    
    
                    item.Kill();
                }


                Message.Text += ("软件更新中,请不要关闭本程序!" + "\r\n");
                Message.Text += ("************************************************************************************" + "\r\n");
                Thread.Sleep(1000);

                //获取A程序最新版本所在的文件夹路径
                var updateExeDir = @"C:\Fan021\Code\Practise\VersionUpdate\WpfApp1\WpfApp1\bin\Debug";
                var files = Directory.GetFiles(updateExeDir);

                //将A程序最新版本所在文件夹里的文件依次逐个拷贝到A程序现有版本所在文件夹里
                //A程序现有版本所在文件夹的路径也是由A传递过来的
                foreach (var item in files)
                {
    
    
                    string fName = item.Substring(updateExeDir.Length + 1);
                    File.Copy(System.IO.Path.Combine(updateExeDir, fName), System.IO.Path.Combine(App.Args[0], fName), true);
                }
                Message.Text += ("软件更新完成,请关闭本程序,重启目标程序!" + "\r\n");
            }
            catch (Exception ex)
            {
    
    
                MessageBox.Show(ex.Message);
            }

        }

B程序代码到这里就结束了,此时到A程序文件下运行A程序,会跳出B程序,并如下显示:
在这里插入图片描述
在这里插入图片描述
这里点击更新,更新完成后界面如下,这时只有B程序的界面了,A程序的进程已经被kill掉了:
在这里插入图片描述
此时再回看A程序文件夹中文件,发现虽然名字还是一样,但是时间已经被更新了:
在这里插入图片描述
再次打开A程序,发现程序界面的“+”号已经被更改成最新版本的“-”号了:
在这里插入图片描述

至此程序版本更新完成。

这里的更新是要操作人员在B程序的界面上点一下“更新”按钮的,是有人工干预的。这主要是考虑到使用方可能不需要立即使用最新版本的程序,可能需要老版本软件再使用一段时间。
如果没有这方面考虑,各位可以把“更新”按钮下的逻辑直接添加到B程序的构造函数里,直接在逻辑最后加个this.close(),这样即可实现真正意义上的自动更新。

以上代码使用VS2017,.net 4.0完成和测试。
欢迎小伙伴留言讨论…

转载请注明出处,谢谢~

猜你喜欢

转载自blog.csdn.net/weixin_44239774/article/details/122992739