WPF 自己动手来做安装卸载程序
前言
说起安装程序,这也许是大家比较遗忘的部分,那么做C/S是小伙伴们,难道你们的程序真的不需要一个炫酷的安装程序么?
声明在先
本文旨在教大家以自己的方式实现安装,至于炫酷部分概不负责.
剖析
我们经常安装形形色色的程序,而碰到的安装步骤基本可概括为一下几种
1,欢迎界面 - 无剖析可言
2,选择路径页 - 无剖析可言
3,安装页 - 包括解压、添加注册表
4,完成页 - 创建快捷方式、开机启动、运行
根据实际使用不同适当修改.
经过剖析我们发现,其实一个高大上的安装程序真的没有技术可言,其实就是一个解压操作,写入注册表而已!!!
那么根据剖析结果我们一步一步去实现安装
解压
这里使用第三方的ICSharpCode.SharpZipLib.Zip进行解压,
具体用法大家可以自行搜索了解,这里贴一个现成的方法
/// <summary>
/// 解压缩文件
/// </summary>
/// <param name="sourceFile">源目录</param>
/// <param name="destinationFile">目标目录</param>
public void DeCompressFile(string sourceFile, string destinationFile, Action call)
{
try
{
if (!System.IO.File.Exists(sourceFile))
{
return;
} if (Directory.Exists(destinationFile))
{
Directory.Delete(destinationFile, true);
} // 读取压缩文件(zip文件),准备解压缩
ZipInputStream s = new ZipInputStream(System.IO.File.OpenRead(sourceFile.Trim()));
ZipEntry theEntry;
string path = destinationFile; // 解压出来的文件保存的路径
string rootDir = " "; // 根目录下的第一个子文件夹的名称
while ((theEntry = s.GetNextEntry()) != null)
{
rootDir = System.IO.Path.GetDirectoryName(theEntry.Name); // 得到根目录下的第一级子文件夹的名称
if (rootDir.IndexOf("\\") >= )
{
rootDir = rootDir.Substring(, rootDir.IndexOf("\\") + );
}
string dir = System.IO.Path.GetDirectoryName(theEntry.Name); // 根目录下的第一级子文件夹的下的文件夹的名称
string fileName = System.IO.Path.GetFileName(theEntry.Name); // 根目录下的文件名称
if (dir != " ")
// 创建根目录下的子文件夹,不限制级别
{
if (!Directory.Exists(destinationFile + "\\" + dir))
{
path = destinationFile + "\\" + dir; // 在指定的路径创建文件夹
Directory.CreateDirectory(path);
}
}
else if (dir == " " && fileName != "")
// 根目录下的文件
{
path = destinationFile;
}
else if (dir != " " && fileName != "")
// 根目录下的第一级子文件夹下的文件
{
// 指定文件保存的路径
if (dir.IndexOf("\\") > )
{
path = destinationFile + "\\" + dir;
}
} // 判断是不是需要保存在根目录下的文件
if (dir == rootDir)
{
path = destinationFile + "\\" + rootDir;
} // 以下为解压缩zip文件的基本步骤
// 基本思路就是遍历压缩文件里的所有文件,创建一个相同的文件。
if (fileName != String.Empty)
{
FileStream streamWriter = System.IO.File.Create(path + "\\" + fileName); int size = ;
byte[] data = new byte[];
while (true)
{
size = s.Read(data, , data.Length);
if (size > )
{
streamWriter.Write(data, , size);
}
else
{
break;
}
} streamWriter.Close();
}
}
s.Close();
call.Invoke();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
注册表
相信有些同学对安装注册表这块不太了解,你可以打开控制面板-程序和功能看到你所安装的程序都出现在这里,那么是怎么出现在这里的呢?
其实就是在注册表SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall的位置添加了应用的信息,当然我们的程序也不例外,
可以根据其它程序的注册信息研究发下,如下几个节点
/// <summary>
/// 注册应用信息
/// </summary>
/// <param name="setupPath">安装路径</param>
public void AddRegedit(string setupPath)
{
try
{
RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", true);
RegistryKey software = key.CreateSubKey(RegeditKey); // 图标
software.SetValue("DisplayIcon", setupPath + "\\" + AppExe); // 显示名
software.SetValue("DisplayName", DisplayName); // 版本
software.SetValue("DisplayVersion", Version); // 程序发行公司
software.SetValue("Publisher", Publisher); // 安装位置
software.SetValue("InstallLocation", setupPath); // 安装源
software.SetValue("InstallSource", setupPath); // 帮助电话
// software.SetValue("HelpTelephone", "123456789"); // 卸载路径
software.SetValue("UninstallString",setupPath + "/uninstall.exe");
software.Close();
key.Close();
} catch (Exception) { }
}
可对应写入自己程序信息,这里重点说一下UninstallString,这个值为卸载程序的指向,即在控制面板-程序和功能里选择卸载时调用的程序
原则上来说,我们有安装那么就需要对应的写一个卸载程序(用来删除注册表,程序目录,快捷等等)这里不做赘述
创建快捷方式
/// <summary>
/// 创建快捷方式
/// </summary>
/// <param name="setupPath">安装目录</param>
/// <param name="isDesktop">是否创建到桌面(默认创建到安装目录)</param>
public void CreateLnk(string setupPath, bool isDesktop)
{
string path = setupPath; if (isDesktop)
{
path = Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory);
} // 注:如果桌面有现准备创建的快捷键方式,当程序执行创建语句时会修改桌面已有快捷键方式,程序不会出现异常 WshShell shell = new WshShell(); // 快捷键方式创建的位置、名称
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(path + "\\" + DisplayName + ".lnk"); // 目标文件
shortcut.TargetPath = setupPath + "\\" + AppExe; // 该属性指定应用程序的工作目录,当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。
shortcut.WorkingDirectory = setupPath;// System.Environment.CurrentDirectory; // 目标应用程序的窗口状态分为普通、最大化、最小化【1,3,7】
// shortcut.WindowStyle = 1; // 描述
shortcut.Description = Description; // 快捷方式图标
shortcut.IconLocation = setupPath + "\\" + AppIco; shortcut.Arguments = ""; // 快捷键
//shortcut.Hotkey = "CTRL+ALT+F11"; // 保存
shortcut.Save();
}
开机启动
而开机启动无非也就是在在注册表的指定位置去添加启动
我这里开机启动的时候调用的是快捷方式,而非exe程序
/// <summary>
/// 添加开机启动
/// </summary>
/// <param name="setupPath">安装目录</param>
public void AddRun(string setupPath)
{
try
{
RegistryKey runkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); // 打开注册表子项
if (runkey == null) // 如果该项不存在的话,则创建该子项
{
runkey = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
} // 设置为开机启动
runkey.SetValue(RegeditKey, "\"" + setupPath + "\\" + DisplayName + ".lnk\"");
runkey.Close();
}
catch (Exception)
{ }
}
运行
public void RunApp(string setupPath)
{
System.Diagnostics.Process.Start(setupPath + "\\" + DisplayName + ".lnk");
}
做完安装后,你会想我最终其实只想得到一个安装的exe程序,而非安装程序的整个文件列表,对于这里我也没找到太好的解决方案,只能通过WinRar等程序把这个包压缩成一个可执行程序.
完结
至此我们炫酷的安装程序就结束了,怎么又提炫酷,好的好的,这篇文章根本就没提界面的事情~!
需要注意一下,因涉及到注册表操作,所以我们的安装程序是需要以管理员身份运行的(设置程序以管理员身份运行的方法自行搜索).
附
如有需要demo的同学可以留下邮箱,一星期左右发出(现在没有现成的demo).如果你觉得这篇文章写的可以不妨推荐一下.
WPF 自己动手来做安装卸载程序的更多相关文章
- 帮同事写了几行代码,在 安装/卸载 程序里 注册/卸载 OCX控件
写了个小控制台程序,这个程序用来注册 / 卸载OCX控件,用在Inno Setup做的安装卸载程序里. #include "stdafx.h" #include <windo ...
- 使用Powershell实现自动化安装/卸载程序
最近需要制作软件安装包,需要附带VC运行时和.Net Framework的安装,但又不想让用户自己点下一步,所以就有了以下操作. 微软提供了一个程序叫msiexec.exe,位于C:\Windows\ ...
- centos7 安装卸载程序rpm使用方法
1.安装 rpm 包: ➢ 基本语法 rpm -ivh RPM 包全路径名称 2.卸载 rpm 包: ➢ 基本语法 rpm -e RPM 包的名称 ➢ 应用案例 删除 firefox 软件包 rpm ...
- 用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]
// InstallWDFDriver.cpp : Defines the entry point for the console application. // #include "std ...
- Linux如何安装卸载软件
Linux 中如何卸载已安装的软件. Linux软件的安装和卸载一直是困扰许多新用户的难题.在Windows中,我们可以使用软件自带的安装卸载程序或在控制面板中的“添加/删除程 序” 来实现.与其相类 ...
- C#:手把手教你用C#打包应用程序(安装程序卸载程序)
摘要:本文介绍在C#中手把手教你用C#打包应用程序(安装程序卸载程序) 1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点 ...
- inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效
inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效 inno setup 安装卸载时检测程序是佛正在运行卸载完成后自动打开网页-代码无效 --------------------- ...
- Inno Setup 在安装程序开始前和卸载程序开始前,检查并关闭运行的进程
(2011-12-29 11:54:56) 转载▼ 标签: innosetup it 分类: 开发工具经验累积 Inno Setup在安装程序前,如果有使用的进程在运行,会有错误提示,而使得Insta ...
- InnoSetup打包exe安装应用程序,并添加卸载图标 转
http://blog.csdn.net/guoquanyou/article/details/7445773 InnoSetup真是一个非常棒的工具.给我的印象就是非常的精干.所以,该工具已经一步步 ...
随机推荐
- validator 对象
validate方法返回Validator对象,Validator对象有很多种有用的方法: Validator.form()验证表单是否有效,返回true/false Validator.elemen ...
- 告诉你LTE-FDD与LTE-TDD的区别
[PConline 技术分析]移动早在去年已经拿下了TD-LTE的4G牌照,而中国联通与中国电信的FDD-LTE的牌照在近日正式拿下,而对于4G网络,有多少真正了解呢?接下来笔者就为大家解释一下4G的 ...
- C primer plus 读书笔记第五章
本章的标题是运算符,表达式和语句.主要研究如何处理数据. 示例代码展示了一个使用简单的while循环的代码,难度不大. 下面简单介绍本章的基本概念. 1.基本运算符. 基本运算符有:赋值运算符(C语言 ...
- windows下Socket链接溢出
最近在windows下使用通过多线程使用jdbc操作数据库,在线程数设置为5,并且每个线程执行完成后Sleep(1000),在这种情况下,竟然还会报错: java.net.SocketExceptio ...
- Java基础知识强化90:Date类之Data类中日期和毫秒相互转换
1.Date两个方法: public long getTime():获取时间,以毫秒为单位 public void setTime(long time):设置时间 2. 代码示例: package c ...
- Counting Lines, Words, and Characters with wc
Counting Lines, Words, and Characters with wc When working with text files, you sometimes get a ...
- linux定时任务2-at命令
定时执行命令: [root@rheltest1 ~]# at now + 1 minute //一分钟后执行下面的任务 at> date >> /tmp/test_date.log ...
- Python迭代--笔记
<python3 程序开发指南> 迭代子.迭代操作 迭代子是一个对象,该对象可提供_next_()方法,该方法依次返回每个相继的数据项,并在没有数据项时产生StopIteration()异 ...
- 使用静态资源设置UI信息
首先建立一个文件存放样式设置(资源字典),所有风格设置都可以这里进行 加入以下代码: <ResourceDictionary xmlns="http://schemas.microso ...
- yii2 添加模块过程
本文以Yii2基本应用程序模板为例,介绍下向该框架下加入新模块的过程: 1. 新建模块相关目录与文件 step 1: 新建目录结构 首先在根目录下新建modules目录,然后在该目录下面添加模块目 ...