原文: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 自己动手来做安装卸载程序的更多相关文章

  1. 帮同事写了几行代码,在 安装/卸载 程序里 注册/卸载 OCX控件

    写了个小控制台程序,这个程序用来注册 / 卸载OCX控件,用在Inno Setup做的安装卸载程序里. #include "stdafx.h" #include <windo ...

  2. 使用Powershell实现自动化安装/卸载程序

    最近需要制作软件安装包,需要附带VC运行时和.Net Framework的安装,但又不想让用户自己点下一步,所以就有了以下操作. 微软提供了一个程序叫msiexec.exe,位于C:\Windows\ ...

  3. centos7 安装卸载程序rpm使用方法

    1.安装 rpm 包: ➢ 基本语法 rpm -ivh RPM 包全路径名称 2.卸载 rpm 包: ➢ 基本语法 rpm -e RPM 包的名称 ➢ 应用案例 删除 firefox 软件包 rpm ...

  4. 用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]

    // InstallWDFDriver.cpp : Defines the entry point for the console application. // #include "std ...

  5. Linux如何安装卸载软件

    Linux 中如何卸载已安装的软件. Linux软件的安装和卸载一直是困扰许多新用户的难题.在Windows中,我们可以使用软件自带的安装卸载程序或在控制面板中的“添加/删除程 序” 来实现.与其相类 ...

  6. C#:手把手教你用C#打包应用程序(安装程序卸载程序)

    摘要:本文介绍在C#中手把手教你用C#打包应用程序(安装程序卸载程序) 1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点 ...

  7. inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效

    inno安装卸载时检测程序是否正在运行卸载完成后自动打开网页-代码无效 inno setup 安装卸载时检测程序是佛正在运行卸载完成后自动打开网页-代码无效 --------------------- ...

  8. Inno Setup 在安装程序开始前和卸载程序开始前,检查并关闭运行的进程

    (2011-12-29 11:54:56) 转载▼ 标签: innosetup it 分类: 开发工具经验累积 Inno Setup在安装程序前,如果有使用的进程在运行,会有错误提示,而使得Insta ...

  9. InnoSetup打包exe安装应用程序,并添加卸载图标 转

    http://blog.csdn.net/guoquanyou/article/details/7445773 InnoSetup真是一个非常棒的工具.给我的印象就是非常的精干.所以,该工具已经一步步 ...

随机推荐

  1. Java中迭代列表中数据时几种循环写法的效率比较

    Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较.虽然网上已经有了类似的文章,但是对他们的结论并不认同. 常见的实现方法: 1.for循环: for(int i = 0; i ...

  2. Android 单指触控拖拽,两指触控缩放

    import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view. ...

  3. Android BroadcastReceiver实例Demo(有序广播的发送)

    上一篇简介了广播的发送,这篇主要介绍下,有序广播的发送. 设置完相关属性的时候,广播就会依照有序的方式进行发送: 发送顺序: 先发送第二条广播: 再发送第一条广播: 最后发送第三条广播. 代码例如以下 ...

  4. 利用ParameterizedType获取泛型参数类型

    //利用ParameterizedType获取java泛型的参数类型 public class Demo {     public static void main(String[] args) { ...

  5. C# 面向对象 , 类与对象

    一,类的字段 类的字段, 就是类里面的 数据. 二,类的方法 1 , 函数的重载 , 如何判断:  是由两个或多个同名函数组成的,但是函数要有不同的参数.或个数.(参数  是函数的输入的东西) shu ...

  6. YII框架中php入口文件隐藏

    Apache配置修改 主要修改下httpd文件中的两个地方 1.启用mod_rewrite.so模块,在Apache的配置文件中找到如下行,去掉前面的字符"#",保存 #LoadM ...

  7. 基于脚本的动画的计时控制(“requestAnimationFrame”)(转)

    requestAnimationFrame 方法的支持,该方法通过在系统准备好绘制动画帧时调用该帧,从而为创建动画网页提供了一种更平滑更高效的方法.在此 API 之前,使用 setTimeout 和  ...

  8. SAE下的Memcache使用方法

    SAE里面有Memcache,可以较大幅度改善数据库的鸭梨~ 之前一直想学习Memcache,却愁于不知如何下手,对这个名词完全没有概念,同时在SAE的文档里面,也很少对于Memcache的使用教程~ ...

  9. jQuery mini ui 2

    1.<a class="mini-button" iconCls="icon-add" onclick="addRow()" plai ...

  10. java.io.FileNotFoundException: class path resource [bean/test/User.hbm.xml] cannot be opened because it does not exist

    确定下 WEB-INF/classes下有没有,不是src下哦 工程的src下创建后,会发布到tomcat下项目下的classes中