c#自动更新+安装程序的制作

一、自动更新的实现

让客户端实现自动更新,通常做法是在客户端部署一个单独的自动更新程序。主程序启动后,访问服务端,检查配置文件是
否有更新版本,有更新版本就启动更新程序,由更新负责下载更新版本,并更新客户端程序,流程如下:

image当流程进行到红色部分的是后就调用更新程序进行更新。

1)版本判断:

客户端和服务端都部署同一个版本文件,客户端登陆时发送验证给服务端判断版本是否一致。

Version.xml代码

<iq xmlns="http://www.dynastech.com/xmtp" from="*@domcool.local/updater" to="*@domcool.local/updater" type="get"
id="508f3e88-4bb0-4585-a5c6-cc41ef57fef3"><query xmlns="http://www.dynastech.com/xmtp/disco#update" version="20090922" lastUpdateTime="2009-09-22"
fileUrl="http://172.0.0.1/UCCompanion/UCCompanionSetup(0922).zip    <">
x xmlns="http://www.dynastech.com/xmtp/item"></x></query>
</iq>
版本文件主要比较服务端Version.xml文件和客户端Version.xml文件中Version(版本号)是否一致,如果服务端Version属性
大于客户端的Version属性,则通过服务端的fileUrl属性获取新版本的下载地址。供更新程序使用。
 
2)删除原有更新包
所有客户端更新文件均下载到C:\Documents and Settings\当前用户名\Local Settings\Temp 文件夹内,当客户端运行后首先判
断是否有新更新包需要下载,如果没有则判断该临时文件夹内是否有旧有安装文件,如果存在,则删除旧有安装文件。
private void RemoveOldSetupFile(){try{string temp = System.Environment.GetEnvironmentVariable("TEMP");string folder = new DirectoryInfo(temp).FullName;if (File.Exists(folder + @"\" + setupName + ".exe")){File.Delete(folder + @"\" + setupName + ".exe");}if (File.Exists(folder + @"\" + setupName + ".msi")){File.Delete(folder + @"\" + setupName + ".msi");}}catch { }}

备注:关于获取系统特殊文件夹的方法见博客http://www.cnblogs.com/thornfield_he/archive/2009/09/22/1571719.html

3)启动下载程序

下载程序和客户端程序是相互独立的,可以通过客户端开启新线程启动下载程序。下载程序在文件下载结束后可以关掉客户端程序,
并开启新线程启动安装程序进行安装。

private void Update()
{if (ShouldUpdate(query.Version, this.version)){MessageBox.Show("请更新客户端文件到版本[" + query.Version + "]", "更新提示", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk);System.Diagnostics.Process.Start(Application.StartupPath + @"\AutoUpdater.exe", query.FileUrl);}else { RemoveOldSetupFile(); }
}private bool ShouldUpdate(string serverVersion, string localVersion)
{if (!string.IsNullOrEmpty(serverVersion) && !string.IsNullOrEmpty(localVersion)){return serverVersion.CompareTo(localVersion) > 0;}return true;
}
 
调用AutoUpdater.exe文件时需要传入文件下载地址。
System.Diagnostics.Process.Start(Application.StartupPath + @"\AutoUpdater.exe", query.FileUrl);
 
4)下载程序代码
下载程序界面
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;
using System.Diagnostics;namespace AutoUpdater
{public partial class MainForm : Form{private WebClient client;private string URl;private string fileName;private string path;private const string applicationFile = "Setup";public MainForm(string url){InitializeComponent();this.URl = url;client = new WebClient();client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);client.Proxy = WebRequest.DefaultWebProxy;client.Proxy.Credentials = new NetworkCredential();this.Hide();//Thread thread = new Thread(UpdateFile);//Thread.Sleep(15000);//thread.Start();UpdateFile();}public MainForm(){InitializeComponent();}/// <summary>/// 下载完成调用/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e){label1.Text = "文件接收完成";UnZip();RunUpdate();}/// <summary>/// 下载进度条/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){this.progressBar1.Value = e.ProgressPercentage;}/// <summary>/// 开始下载/// </summary>private void StartDownload(){fileName = URl.Substring(URl.LastIndexOf("/") + 1, URl.Length - URl.LastIndexOf("/") - 1);path = GetTempFolder();try{WebRequest myre = WebRequest.Create(URl);}catch (Exception ex){MessageBox.Show(ex.Message, "Error");}try{label1.Text = "开始下载文件...";client.DownloadFileAsync(new Uri(URl), path + @"\" + fileName);}catch (WebException exp){label1.Text = exp.Message;}}/// <summary>/// 解压压缩包,格式必须是*.zip,否则不能解压/// 因为是调用Windows内部api进行解压,只能够识别zip压缩包/// 必须添加C:\WINDOWS\system32\shell32.dll的引用/// </summary>private void UnZip(){try{Shell32.ShellClass sc = new Shell32.ShellClass();Shell32.Folder SrcFolder = sc.NameSpace(this.path + @"\" + this.fileName);Shell32.Folder DestFolder = sc.NameSpace(this.path);Shell32.FolderItems items = SrcFolder.Items();DestFolder.CopyHere(items, 20);}catch (Exception ex){MessageBox.Show(ex.Message);}}/// <summary>/// 获取下载文件夹地址及解压文件存放地址/// 此地址默认为C:\Documents and Settings\当前用户名\Local Settings\Temp 文件夹/// </summary>/// <returns></returns>private string GetTempFolder(){string folder = System.Environment.GetEnvironmentVariable("TEMP");return new DirectoryInfo(folder).FullName;}/// <summary>/// 开始下载文件/// </summary>private void UpdateFile(){this.Hide();//如果临时文件夹存在setup安装文件,就直接调用安装文件if (File.Exists(GetTempFolder() + @"\" + applicationFile + ".exe") && File.Exists(GetTempFolder() +
@"\" + applicationFile + ".msi")){label1.Text = "开始下载文件...";this.progressBar1.Value = this.progressBar1.Maximum;label1.Text = "文件接收完成";RunUpdate();}//如果临时文件夹不存在setup安装文件,就从网络下载else{RemoveSetupFile();StartDownload();}}/// <summary>/// 清除旧有已下载的安装文件/// </summary>private static void RemoveSetupFile(){try{string temp = System.Environment.GetEnvironmentVariable("TEMP");string folder = new DirectoryInfo(temp).FullName;if (File.Exists(folder + @"\" + applicationFile + ".exe")){File.Delete(folder + @"\" + applicationFile + ".exe");}if (File.Exists(folder + @"\" + applicationFile + ".msi")){File.Delete(folder + @"\" + applicationFile + ".msi");}}catch { }}/// <summary>/// 下载完毕,开始执行更新程序/// </summary>private void RunUpdate(){try{foreach (Process p in Process.GetProcesses()){if (p.ProcessName.ToLower().StartsWith("uccompanion")){if (MessageBox.Show("UCCompanion正在运行,是否关闭当前程序安装更新?", "安装UCCompanion",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes){p.Kill();Process.Start(GetTempFolder() + @"\" + applicationFile + ".exe");}else{MessageBox.Show("UCCompanion下载完成,将在下次启动时提醒更新!");}}}}catch (Exception ex){MessageBox.Show(ex.Message);}finally{this.Close();}}/// <summary>/// 重载WindProc判断点击关闭按钮(X)时,隐藏程序界面/// </summary>/// <param name="msg"></param>protected override void WndProc(ref Message msg){const int WM_SYSCOMMAND = 0x0112;const int SC_CLOSE = 0xF060;if (msg.Msg == WM_SYSCOMMAND && ((int)msg.WParam == SC_CLOSE)){this.Hide();return;}base.WndProc(ref msg);}/// <summary>/// 双击图标弹出界面/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void icon_notify_MouseDoubleClick(object sender, MouseEventArgs e){this.Show();this.WindowState = FormWindowState.Normal;}/// <summary>/// /// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void MainForm_SizeChanged(object sender, EventArgs e){if (this.WindowState == FormWindowState.Minimized){this.Hide();}}private void MainForm_Load(object sender, EventArgs e){this.Hide();}}static class Program{/// <summary>/// 启动,接收传入网址作为参数/// </summary>/// <param name="agr"></param>[STAThread]static void Main(string[] agr){if (agr.Length == 1 && agr[0].StartsWith(@"http://")){MainForm form = new MainForm(agr[0]);Application.Run(form);}}}
}

程序代码

将AutoUpdater项目生成的文件添加到客户端文件中,在客户端的Update()方法里调用updater,实现更新文件的下载。

以上就已经实现了自动更新功能,下面将讨论文件安装包的制作。
 

二、安装包的制作

1)创建安装项目

image

 

 

2)鼠标右击Setup项目选择>视图,可以看到制作安装包常见的视图有以下几个

image

最常用的视图有“文件系统”,“用户界面”和“启动条件”。

3)指定安装属性

鼠标左键单击项目名称,记住是左键单击,然后点击属性标签,注意:不是右击的属性

image

 

 

a.需要注意的是Version属性,每次版本更新时Version值必须后面的版本大于前面的版本。每次更改Version值时Projectcode会更改一次。

其中你修改安装项目的版本号时,比如从v1.00 到1.01,在你再次生成项目的时候,会提示你是否允许修改ProductCode,选择"是",
程序会自动修改ProductCode,选择否将保持相同的ProductCode,即不能自动卸载旧的版本.

b.在以后版本中要确认和以前的版本两个版本有不同的ProductCode和相同的UpgradeCode

c.manufacturer属性指定制造商名称。

d.detectnewerinstalledversion属性选择为true,

e.removepreviousversions选择为true

 

鼠标左键单击项目名称,此次是右键单击,然后点击属性,弹出属性页,选择“系统必备”。

在打开的系统必备页中,选中如下中的选择项,这个很重要!!!!!1!!!!!选上以后,在生成的安装文件
含.netframework组件.(这个选项默认是没有选中的)。

image

 

4)文件系统视图

文件系统视图左侧根目录树下有3个子节点。

a.应用程序文件夹:将所有待打包的应用程序的可执行文件和相应的类库和组件拖动到该目录下。该目录可以创建子
目录,项目安装完毕以后的文件夹结构会和该目录下结构一致。

如图:

image

然后右击左边的"应用程序文件夹"打开属性对话框,修改文件释放路径,[ProgramFilesFolder][Manufacturer]\[ProductName]。
安装程序默认安装目录会是"c:\programm file\制造商名称\安装解决方案名称";

image

b.用户的“程序”菜单和用户桌面:用于在开始菜单创建文件快捷方式

在应用程序文件夹中将需要生成的快捷方式的文件添加快捷方式并拖动到用户的“程序”菜单和用户桌面

 

 

 

image

c.添加文件卸载功能

在添加你的应用程序项目的时候,多添加一个msiexec.exe进去,这个文件在c:\windows\system32文件夹下。

为其在程序菜单添加一个快捷方式,把他的名字改成"Uninstall.exe",指定Icon快捷方式显示的图标。然后下面我们
要的做的就是查找这个部署项目的ProductCode了,鼠标左键单击项目名称,记住是左键单击,然后点击属性标签,注意:
不是右击的属性,这个区别很大,这时你就可以看到ProductCode了

image

 

 

 

然后打开你创建的那个卸载程序的快捷方式的属性对话框,在Aguements属性中输入"/x {ProductCode}"

5)用户界面视图

在“欢迎使用”后,“安装文件夹”前添加“许可协议”对话框。

licensefile选择协议,协议的格式为rtf。

image

6)启动条件视图

为启动安装程序制定最低framework要求。

image

7)实现安装、卸载过程中的其他额外的操作。比如安装结束后启动程序,卸载程序后同时删除网络下载打安装包等功能。

a.新建一个空的项目InstallCompenent,步骤为:解决方案->右键添加->新建项目->选择"空项目"->
输入名称"InstallCompenent"->确定,完成项目的添加.

b.在InstallCompenent项目中右键->添加->新建项->选择安装程序类->输入名称"Installer",完成installer类的添加.

修改代码为:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Reflection;
using System.IO;namespace InstallCompenent
{[RunInstaller(true)]public partial class UccompanionInstaller : Installer{private const string zipPacket = "UCCompanionSetup(0918).zip";/// <summary>   /// 应用程序入口   /// </summary>   public static void Main(){}/// <summary>   /// 构造函数   /// </summary>   public UccompanionInstaller(){InitializeComponent();}/// <summary>   /// 重写安装完成后函数   /// 实现安装完成后自动启动已安装的程序   /// </summary>   /// <param name="savedState"></param>   protected override void OnAfterInstall(IDictionary savedState){base.OnAfterInstall(savedState);Assembly asm = Assembly.GetExecutingAssembly();string path = asm.Location.Remove(asm.Location.LastIndexOf("\\")) + "\\";System.Diagnostics.Process.Start(path + "\\UCCompanion.exe");}/// <summary>   /// 重写安装过程方法   /// </summary>   /// <param name="stateSaver"></param>   public override void Install(IDictionary stateSaver){base.Install(stateSaver);}/// <summary>   /// 重写安装之前方法   /// </summary>   /// <param name="savedState"></param>   protected override void OnBeforeInstall(IDictionary savedState){base.OnBeforeInstall(savedState);}/// <summary>   /// 重写卸载方法   /// 卸载程序后也删除程序的安装包/// </summary>   /// <param name="savedState"></param>   public override void Uninstall(IDictionary savedState){string temp = System.Environment.GetEnvironmentVariable("TEMP");string folder = new DirectoryInfo(temp).FullName;if (File.Exists(folder + @"\setup.exe")){File.Delete(folder + @"\setup.exe");}if (File.Exists(folder + @"\setup.msi")){File.Delete(folder + @"\setup.msi");}if (File.Exists(folder + @"\"+zipPacket)){File.Delete(folder + @"\"+zipPacket);}base.Uninstall(savedState);}/// <summary>   /// 重写回滚方法   /// </summary>   /// <param name="savedState"></param>   public override void Rollback(IDictionary savedState){base.Rollback(savedState);}}
}

 

c.在安装项目中右键->添加项目输出->选择"项目"->InstallCompenent.完成主输出项目的添加.

d.打开自定义操作编辑器,在安装->右键->添加自定义操作->选择"应用程序文件夹"->选择"主输出来自InstallCompenent",完成添加.

好了,点击“生成解决方案”,即可以生成带有卸载功能的安装程序了。

 

转自:http://blog.csdn.net/myhuli120/article/details/6927588

转载于:https://www.cnblogs.com/elim/p/3968333.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492923.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国AI科研产出全球第一 但引文影响力低

来源&#xff1a;科学网 日前&#xff0c;爱思唯尔发布了《人工智能&#xff1a;知识的创造、转移与应用》报告&#xff0c;分析了全球人工智能科研的发展趋势。报告显示&#xff0c;2017年中国在人工智能领域出版的文章数量位列全球第一&#xff0c;科研产出已在2004年超过美国…

OpenCV--SIFT算法检测特征点

代码选自&#xff1a;http://blog.csdn.net/zhaocj/article/details/42124473 SIFT算法是用来检测图像中特征点的&#xff0c; 代码如下&#xff1a; opencv版本:2.4.9 #include "opencv2/opencv.hpp" #include "opencv2/imgproc/imgproc.hpp" #include…

对话 Geoffrey Hinton Demis Hassabis :人工智能离我们有多远?

来源&#xff1a;AI科技评论预测用户喜欢的音乐类型、检测出转移性肿瘤、生成脑癌的综合扫描、利用真实世界中拍摄的视频创造出虚拟环境、识别出被拐卖的人口、击败国际象棋大师以及专业的 Dota2 电竞团队、帮助 Alphabet 旗下的 Waymo 首次推出商业无人驾驶出租车服务、代替出…

SharePoint 2013 关于自定义显示列表表单的bug

1、在SharePoint 2013中&#xff0c;我们隐藏列表Dispform页面的ListFormWebPart部件&#xff0c;转而使用自定义显示列表表单进行展示&#xff0c;因为这样更容易定制我们需要的显示&#xff1b; 2、之后发现文件夹下的文档&#xff0c;查看属性会报错&#xff0c;如下图&…

SIFT算法中概念简单解释

尺度空间 真实世界的物体只有在一定尺度上才有意义&#xff0c;例如我们能够看到放在桌子上的水杯&#xff0c;但对于整个银河系&#xff0c;这个水杯是不存在的。物体的这种多尺度的本质在自然界中是普遍存在的。尺度空间就是试图在数字图像领域复制这个概念。又比如&#xf…

发布|CES 2019 科技趋势(附40页PPT)

来源&#xff1a;Robot未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能&#xff0c;互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0c;开展世界人工智能智商评测&#xff1b;开展互联网&#xff…

UVAL - 6755 - Swyper Keyboard

先上题目&#xff1a; https://icpcarchive.ecs.baylor.edu/external/67/6755.pdf 题目复制起来比较麻烦。 题意&#xff1a;定义一种操作&#xff1a;给出一个字符串&#xff0c;然后手指就按照给出的字符串的字符出现顺序不离开触摸屏那样移动&#xff0c;这样最后就会得到一…

Ransac算法简介

给定两个点p1与p2的坐标&#xff0c;确定这两点所构成的直线&#xff0c;要求对于输入的任意点p3&#xff0c;都可以判断它是否在该直线上。初中解析几何知识告诉我们&#xff0c;判断一个点在直线上&#xff0c;只需其与直线上任意两点点斜率都相同即可。实际操作当中&#xf…

2018年AI和ML(NLP、计算机视觉、强化学习)技术总结和2019年趋势

来源&#xff1a;网络大数据1、简介过去几年一直是人工智能爱好者和机器学习专业人士最幸福的时光。因为这些技术已经发展成为主流&#xff0c;并且正在影响着数百万人的生活。各国现在都有专门的人工智能规划和预算&#xff0c;以确保在这场比赛中保持优势。数据科学从业人员也…

仿射变换的原理

在条形码识别软件中有图像预览的功能。有时预览的图像需要进行转置&#xff08;旋转180度或者90度&#xff09;、缩放、镜像&#xff08;左右反转&#xff09;等操作。OpenCV提供了相应的函数进行以上操作。例如&#xff1a; 转置&#xff1a;cv::WarpAffine() 缩放&#xff…

拯救顽疾大作战!IDC绘中国医疗AI生态图谱,英伟达献医疗影像新杀器

来源&#xff1a;智东西摘要&#xff1a;中国千家医院部署AI系统&#xff01;IDC医疗AI报告详解行业趋势和五大药方。2018年是令人唏嘘的一年&#xff0c;台湾作家李敖、动画大师高畑勋、相声表演艺术家师胜杰、央视主持人李咏、微软联合创始人保罗艾伦、武侠小说宗师金庸等一个…

存在描述所有生命的方程吗?

○ 生物体既复杂又有序&#xff0c;就像这片亚麻茎的横截面。研究人员希望最终发展出描述所有生命的基本方程。来源&#xff1a;原理关于生命&#xff0c;没有什么是简单的。每一秒钟&#xff0c;都有数百万个缜密有序的化学反应发生在一个细胞内&#xff1b;数十亿个单细胞生物…

CSS3滤镜

今天在办公室亲眼目睹了同事使用CSS3滤镜为一张漂亮的照片轮廓加上了阴影&#xff0c;瞬间亮瞎了我的的双眼&#xff0c;见笑了。 所以也迅速尝试使用CSS3滤镜让最新出炉的MUI LOGO也性感一把&#xff0c;试图来愉悦一下大家的双眼。已经等不及了&#xff0c;赶紧奉上今天的测试…

全面认识“边缘云”,中国首份边缘云白皮书发布

来源&#xff1a;中国电子技术标准化研究院、阿里云摘要&#xff1a;《边缘云计算技术与标准化白皮书》近期发布&#xff0c;定义了边缘云计算的概念和标准等。中心云和边缘云相互配合&#xff0c;实现中心-边缘协同、全网算力调度、全网统一管控等能力&#xff0c;真正实现“无…

【Tech】Mac上安装MAMP打开本地网页

不知道为什么实验室老是用些奇葩的东西&#xff0c;这次是madserve&#xff0c;主要是用来统计移动端广告点击率的&#xff0c;基于PHP/MYSQL实现。 昨天很快在Windows上搭好一个xampp&#xff0c;并用它建立了一个virtual host把madserve跑起来了。但是在mac上xampp建立virtua…

中国10大最震撼的无人工厂,你吃的用的都是这么来的!

来源&#xff1a;工业机器人摘要&#xff1a;你吃的用的那么多东西&#xff0c;早已不是“人造”的&#xff01;1.上海通用金桥工厂&#xff1a;386台机器人图中展示的是上海通用金桥工厂。这里号称中国最先进的制造业工厂、中国智造的典范。即使从全球来看&#xff0c;这个水平…

对人工神经网络“开刀”,利用神经科学消融法检测人工神经网络

来源&#xff1a;DeepTech深科技摘要&#xff1a;当谈及人工神经网络&#xff0c;黑箱问题总会引起热议&#xff0c;人们对黑箱问题的评价褒贬不一。有人认为黑盒是神经网络的优势&#xff0c;这代表神经网络的自主学习性&#xff0c;代表其自动学习以及自动完善的特性。但大部…

从车联网到工业智联网

来源&#xff1a;智车科技摘要&#xff1a;本文从工业互联网的典型应用—车联网谈起&#xff0c;从工业网联技术发展过程的视角分析了工业智联网的构架、关键技术和前沿趋势&#xff0c;对智联网视域下的未来智联交通作出了展望。随着智能技术的发展&#xff0c;从工业互联网发…

清华发布《AI芯片技术白皮书》:新计算范式,挑战冯诺依曼、CMOS瓶颈

来源&#xff1a;机器人 悦智网摘要&#xff1a;在由北京未来芯片技术高精尖创新中心和清华大学微电子学研究所联合主办的第三届未来芯片论坛上&#xff0c;清华大学正式发布了《人工智能芯片技术白皮书(2018)》。《白皮书》首次整合了国际化的学术和产业资源&#xff0c;紧扣学…

这是一份 AI 界最强年终总结

来源&#xff1a;AI 科技评论圣诞节元旦假期过后&#xff0c;谷歌资深 Fellow、谷歌 AI 负责人 Jeff Dean 代表所有谷歌的研究部门发出了他们的 2018 年度科研研究年终总结。这一年&#xff0c;谷歌的科研人员们在人工智能、量子计算、计算图形学、算法理论、软件系统、TPU、开…