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真是一个非常棒的工具.给我的印象就是非常的精干.所以,该工具已经一步步 ...
随机推荐
- 利用Jenkins自动部署工具间接构建kettle的调度平台
关于Jenkins的介绍我就不说了,自己百度,因为这个工具调用脚本只是他的功能的冰山一角,其他功能我也不能理解,因为不是那个领域. 下面我就介绍一下为什么我们需要一个调度平台,以及学习完 ...
- 在JAVA中 System.getProperty 和 System.setProperty 方法.
今天着手研究TOMCAT源码. 在刚開始的时候Startup类中init方法中调用非常多次System.getProperty和System.setProperty的方法. 后来经过网上搜索才得知,这 ...
- [Angular 2] Using a Value from the Store in a Reducer
RxJS allows you to combine streams in various ways. This lesson shows you how to take a click stream ...
- [Javascript] Advanced Reduce: Flatten, Flatmap and ReduceRight
Learn a few advanced reduction patterns: flatten allows you to merge a set of arrays into a single a ...
- JVM内存回收对象及引用分析
自动垃圾回收是Java相较于C++的一个重要的特点,想了解JVM的垃圾回收机制,首先我们要知道垃圾回收是回收什么地方的垃圾,我在我的上一篇博客<JVM内存区域划分>里面有写到JVM里面的内 ...
- c#委托中另外一种用法
在c#委托中,经常可能遇到函数重载的情况,可是又需要在一个函数中调用这些函数,一般我都是根据多个函数重载个数,也写上这么多个函数重载.比如 public double T1(int r) { retu ...
- 获取web路径的几种方式
1.string str1 = Request.ApplicationPath.ToString(); 返回路径为:\HolterClientWeb 2.HttpServerUti ...
- OD: DEP & Ret2Libc
Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...
- vmware-tools(vmware workstation 10.0.4)安装的时候遇到的bug
有个GitHub,专门解决C++编译的时候出的问题 地址
- 关于slideup和slidedown 鼠标多次滑过累积的动画效果
stop() 方法停止当前正在运行的动画 包括animation动画和slideup/slidedown动画 例如:鼠标经过一个元素时,执行一个slide动画,多次快速经过,不处理的话这个元素会保留累 ...