前言
说起安装程序,这也许是大家比较遗忘的部分,那么做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真是一个非常棒的工具.给我的印象就是非常的精干.所以,该工具已经一步步 ...
随机推荐
-
Remove Duplicate Letters I &; II
Remove Duplicate Letters I Given a string which contains only lowercase letters, remove duplicate le ...
-
java切换VPN让你像幽灵一样出现在全国各地
在很多情况下,有些网络应用的需求会要求模拟人在不同地区访问网站和应用.因而切换IP也就应运而生了,然而IP作为一种稀缺资源不是随便可以获得的.因而会想到应用程序切换VPN来达到全国不同地区访问网络.因 ...
-
当一个activity中按钮过多时怎么办?
这几天看极客学院的视频,跟视频中的老师学到的一些小技巧~~ .setOnClickListener(this) 通过重写this(我猜的是重写),下面有onClicked() package exam ...
-
label标签的属性
//label标签的属性 - (void)viewDidLoad { //初始化一个label1标签对象,初始化有很多方法,最原始的就是init,此处用带有frame的方法 UILabel *labe ...
-
android 回调机制实例!
详细实现为在类中定义接口.在接口的实现方法中传入參数(也能够不传). 在调用类中传入新建的接口.并实现未实现的方法. public class CallBackClass { //传入对应的接口作为參 ...
-
HTTP请求分析工具Fiddler
主要用于分析http头信息和响应头信息,以及具体的post数据和响应数据,可以监测电脑上http请求.
-
noi.ac309 Mas的童年
题目链接 题面 题目描述 \(Mas\)完成了一天的工作,走在回家的路上,看着路边的景色,他想起来自己的童年. 许许多多的记忆交错,丝丝缕缕的牵扯着\(Mas\). 在回忆的深处,\(Mas\)想起来 ...
-
Git之项目使用
现在最为盛行的版本控制器,非git莫属了, 那就看看在项目中我们是如何使用它的吧 一. 在已经存在秘钥对的情况下,我们需要在本地进行相关配置 git config --global user.name ...
-
POJ 2860
#include<iostream> #define MAXN 20 using namespace std; int a_1[MAXN]; int a_2[MAXN]; int main ...
-
Linux 系统的网络配置文件
系统的网络配置文件 方式一: 界面操作 setup -->界面配置网络,网关等 方式二: 修改配置文件 # 修改配置 vim /etc/sysconfig/network-scripts/ifc ...