c# winform自动更新的一点问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# winform自动更新的一点问题相关的知识,希望对你有一定的参考价值。

111.exe 读取服务器信息之后下载新版本在同一目录下并命名为au.exe (这一步我已经实现)现在的问题是,如何实现最终结果是删除111.exe,把au.exe命名为111.exe并执行呢?PS:不用单独的更新程序

为什么不换个思路~~
把au.exe下载到临时文件夹,然后执行au.exe退出111.exe,au.exe执行判断当前所处路径,如果是临时文件夹就删除原有的111.exe文件,并copy au.exe到程序执行路径命名为111.exe,然后执行111.exe退出au.exe 同样有判断当前所处路径,如果是程序执行路径就判断临时文件夹是否存在au.exe 存在则删除 实现你单个exe更新的目的,就是来回折腾了一下,程序需要做两次路径判断而已
参考技术A W1你的主程序,W2更新用的窗体。

W1上面有一个按钮说有更新(有没有这个你自己知道,下载你也实现了),点击更新后
System.Diagnostics.Process p = System.Diagnostics.Process.Start(@"D:\project\Mytest\W2\bin\Debug\W2.exe"); //打开W2
this.Close();//关闭W1

W2上有按钮,点击开始更新
if (File.Exists(@"D:\project\Mytest\W1\bin\Debug\W1.exe"))

File.Delete(@"D:\project\Mytest\W1\bin\Debug\W1.exe");//删除W1

File.Copy(@"D:\project\Mytest\W2\bin\Debug\W1.exe", @"D:\project\Mytest\W1\bin\Debug\W1.exe");//复制你下载的文件 Copy方法第二个参数可以改任意文件名
MessageBox.Show("后台更新完成");
System.Diagnostics.Process p = System.Diagnostics.Process.Start(@"D:\project\Mytest\W1\bin\Debug\W1.exe");//打开复制更新过去的W1
this.Close();//关闭W2
参考技术B exe程序在运行的时候是不能删除或者改名的,这种更新通常要借助其他程序,如clickonce,或者调用脚本之类的方法。 参考技术C 一般实现这样的程序都是有一个外壳,
使用外壳程序启动,在外壳程序里面重命名并删除au.exe 再调用111.exe
参考技术D 没看明白。。。

C#关于winform线程更新form的文本框输出的问题

我需要写一个winform执行一套根据数据库表遍历文件并执行增删的功能。
现在需要在winform每检索一个文件,都在winform的textbox中输出一行"XXX文件未找到"、"XXX文件已删除"
因为处理需要几分钟事件,如果直接在button的click事件里写,winform会卡住,程序未响应,直到检索完数据库以后工作完成,才会在textbox里一次性显示所有的文字。
我现在想要达到的效果是,点击button后,winform不会卡住未响应,并且每处理数据库里的一条记录,都在textbox里显示一条"ID为XXX的记录文件未找到"或者"ID为XXX的记录文件已删除"。
我了解到需要新增一个工作线程处理这些耗时的工作,但是我并不知道如何去写这些代码,求指点如何使用新线程处理这份工作,新线程怎么才能操作form的文本框文字让她能够动态显示?

使用多线程和委托。

你的目的其实概括来说,就是后台线程去处理文件, 当“找到”或者“未找到”时,通知UI去更新文本为“XX找到”“XX未找到”。

伪代码:

//定义一个事件 

public delegate void MyDelegate(bool isDone, string requestResult);
//这里定义一个委托,有两个参数, 一个是是否结束,第二个是返回的结果值(string)
public event MyDelegate  myEvent = null;// 注册事件



var thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>

     //这里去遍历啊  执行啊 乱七八糟的  最好封装成函数  
     // rst是提示的文本, 需要你前面函数里面返回,比如"xx找到了";       
      myEvent.Invoke(true, rst);
      //当执行结束时, 返回false
      //myEvent.Invoke(false,rst);
)) 
 IsBackground = true ;
thread.Start();
sysbusyEvent += (state, result) =>

      Application.Current.Dispatcher.BeginInvoke(new Action(() =>
      
           if(result!=string.Empty)
           
               //前台UI更新
               myTextBox.Text = result ;
           
           if (state == false)
           
               sysbusyEvent = null; //清理事件
           
      ));
;

这样后台线程会去处理他的事情,每当他处理掉一件,就会Invoke回来一个状态给前台,

而UI线程(主线程)会一直监听这个事件,当有回调(Invoke)时,去处理这些信息,

就可以达到你要求的目的,即UI线程不阻塞(不会卡死),且后台还在执行一些耗时的运算。

参考技术A

百度搜索一下   

BackgroundWorker 简单使用教程

你只需要把bw_DoWork中的方法体换成你自己的循环和遍历就行了

当你处理完一个文件,要输出时,记得在那个bw_DoWork中用这种写法


 this.Invoke((MethodInvoker)delegate
 
 textBox1.AppendText"XXX文件未找到\\n");
textBox1.ScrollToCaret();
  );

以上是关于c# winform自动更新的一点问题的主要内容,如果未能解决你的问题,请参考以下文章

C# - Winforms - Combobox - 避免选择更新数据源的第一项

winform安装后,自动更新

我希望我的 C# Windows 服务自动更新

使用 advanced installer 为 winform 做自动更新

C# Winform要怎么做在线更新!(50分求个例子)

Winform 打包 混淆 自动更新