Product deploy using NAnt and NSIS

参考网址

运行环境配置

解压缩附件NAnt和NSIS到一个固定目录(不能带空格的目录),例如:D:\Programs

配置 MSBUILD

将C:\WINDOWS\Microsoft.NET\Framework\v3.5加入环境变量

验证方式:命令行运行msbuild, 看到版本信息则为成功。

配置NAnt

将D:\Programs\NAnt\bin加入环境变量

验证方式:命令行运行nant, 看到版本信息则为成功。

配置NSIS

将D:\Programs\NSIS加入环境变量

验证方式:命令行运行makensis, 看到版本信息则为成功。

NAnt

ant是一个类似于bat和make的批处理工具,在.Net应用中称为NAnt。和其他工具不同的是,NAnt使用XML配置文件的形式作为工具的语言,更容易上手。详细介绍可参见http://nant.sourceforge.net

NAnt配置文件

NAnt的默认配置文件称为default.build(也可通过参数指定读取一个自定义的build文件),使用命令行进入 default.build所在的目录,直接执行nant,即可自动运行配置文件中的默认任务(target)。

<?xml version="1.0" encoding="utf-8" ?>

<project name="MySolution" default="deploy">

    <property name="build.dir" value="build" />

    <property name="deploy.dir" value="deploy" />

    <property name="nsis.script" value="deploy.nsi" />

    <property name="sln.dir" value="." />

    <property name="sln.name" value="MySolution.sln" />

    <property name="bin.dir" value="${sln.dir}\MySolution\bin\Release" />

    <target name="compile" description="compiles everything to release">

        <exec program="msbuild" commandline="${sln.dir}\${sln.name} /t:Rebuild /p:Configuration=Release" />

    </target>

    <target name="clean">

        <delete dir="${build.dir}" if="${directory::exists(build.dir)}"/>

        <delete dir="${deploy.dir}" if="${directory::exists(deploy.dir)}"/>

    </target>

    <target name="init" depends="clean" description="initial compilation setup">

        <mkdir dir="${build.dir}" />

        <mkdir dir="${deploy.dir}" />

    </target>

    <target name="rebuild" depends="compile, init">

        <copy todir="${build.dir}\MySolution">

            <fileset basedir="${bin.dir}">

                <exclude name="*.vshost.exe"/>

                <exclude name="*.vshost.exe.config"/>

                <include name="*.exe"/>

                <include name="*.dll"/>

                <include name="*.config"/>

            </fileset>

        </copy>

    </target>

    <target name="deploy" depends="rebuild">

        <exec program="makensis" commandline=' /X"SetCompressor /FINAL lzma" ${nsis.script}' />

    </target>

</project>

NAnt语法解释

设置项目名称,配置默认target。

<project name="MySolution" default="deploy">

定义属性名称,可以在下文中引用,例如"${sln.dir}\${sln.name}",效果等价于".\MySolution.sln"。

<property name="build.dir" value="build" />

<property name="deploy.dir" value="deploy" />

<property name="nsis.script" value="deploy.nsi" />

<property name="sln.dir" value="." />

<property name="sln.name" value="MySolution.sln" />

<property name="bin.dir" value="${sln.dir}\MySolution\bin\Release" />

定义一个名为compile的target,内容为执行msbuild,参数为".\MySolution.sln /t:Rebuild /p:Configuration=Release",这个任务表示Release编译MySolution.sln。之后在命令行中执行"nant compile",则会完成项目Release编译任务。

<target name="compile" description="compiles everything to release">

    <exec program="msbuild" commandline="${sln.dir}\${sln.name} /t:Rebuild /p:Configuration=Release" />

</target>

定义一个名为clean的target,内容为删除build和deploy这两个文件夹,如果文件夹存在的话。

<target name="clean">

    <delete dir="${build.dir}" if="${directory::exists(build.dir)}"/>

    <delete dir="${deploy.dir}" if="${directory::exists(deploy.dir)}"/>

</target>

定义一个名为init的target,这个任务依赖于clean任务,意思就是在执行init之前,会自动先执行clean任务。init任务内容是创建build和deploy文件夹。

<target name="init" depends="clean" description="initial compilation setup">

    <mkdir dir="${build.dir}" />

    <mkdir dir="${deploy.dir}" />

</target>

定义一个名为rebuild的target,这个任务依赖于先依赖于compile再依赖于init,那么在执行rebuile任务时,其实是按照 compile->init->rebuild的顺序执行。rebuild任务内容是将compile任务编译好的文件复制到 build\MySolution文件夹下,复制过程中只复制exe,dll,config,并且排除了 vshost.exe,vshost.exe.config文件。

<target name="rebuild" depends="compile, init">

    <copy todir="${build.dir}\MySolution">

        <fileset basedir="${bin.dir}">

            <exclude name="*.vshost.exe"/>

            <exclude name="*.vshost.exe.config"/>

            <include name="*.exe"/>

            <include name="*.dll"/>

            <include name="*.config"/>

        </fileset>

    </copy>

</target>

定义一个名为deploy的target,任务依赖于rebuild,它的最终执行顺序便是 compile->init->rebuild->deploy。任务内容是使用makensis命令进行程序打包。 commandline中的内容是makensis的运行参数,设置了打包的脚本文件名,打包的压缩算法,压缩级别,makensis的具体运行参数说明可参见http://nsis.sourceforge.net

<target name="deploy" depends="rebuild">

    <exec program="makensis" commandline=' /X"SetCompressor /FINAL lzma" ${nsis.script}' />

</target>

NSIS

NSIS(Nullsoft Scriptable Install System),它是一个脚本化的安装程序打包工具,它的优势在于支持脚本化配置安装程序打包,这样就有利于和其他部署工具配合使用。详细介绍可参见http://nsis.sourceforge.net

NSIS脚本

在上文中的NAnt中有说到makensis命令读取脚本文件进行打包。下面就是一个比较典型的程序打包脚本。

!include WordFunc.nsh

!insertmacro VersionCompare

!include LogicLib.nsh



!ifndef COMPRESS_DIR

!define COMPRESS_DIR ".\build"

!define TOOL_DIR     ".\tool"

!endif



!define PRODUCT_NAME_CN "测试程序"

!define PRODUCT_NAME_EN "MySolution"

!define PRODUCT_VERSION "V1.0"

!define PRODUCT_PUBLISHER_CN "上海金桥信息工程有限公司"

!define PRODUCT_PUBLISHER_EN "SHGBIT"

!define INSTALL_NAME "测试程序-${PRODUCT_VERSION}"



; The default installation directory

InstallDir $PROGRAMFILES\${PRODUCT_PUBLISHER_EN}\${PRODUCT_NAME_EN}



Name "${PRODUCT_NAME_EN}"

# name the installer

outFile ".\deploy\${INSTALL_NAME}.exe"

!include "MUI.nsh"



!define MUI_ICON ".\install-res\ico-inst.ico"

!define MUI_UNICON ".\install-res\ico-uninst.ico"

!define MUI_WELCOMEFINISHPAGE_BITMAP ".\install-res\side.bmp"

!define MUI_HEADERIMAGE

!define MUI_HEADERIMAGE_BITMAP ".\install-res\header.bmp"

;!define MUI_FINISHPAGE_RUN "$INSTDIR\xxx.exe"



;Install Pages (1-6)

!insertmacro MUI_PAGE_WELCOME

!insertmacro MUI_PAGE_LICENSE ".\install-res\LICENSE"

!insertmacro MUI_PAGE_DIRECTORY

!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_PAGE_FINISH

;Uninstall Pages (1-2)

!insertmacro MUI_UNPAGE_CONFIRM

!insertmacro MUI_UNPAGE_INSTFILES



;Languages

!insertmacro MUI_LANGUAGE "SimpChinese" # first language is the default language

# !insertmacro MUI_LANGUAGE "English"



BrandingText "${INSTALL_NAME}"

DirText "安装程序将安装 $(^NameDA) 在下列文件夹。要安装到不同文件夹,单击 [浏览(B)] 并选择其他的文件夹。 $_CLICK" 



Section "All Components " AllSection

    SetOutPath "$INSTDIR"

    File /r "${COMPRESS_DIR}\MySolution\*.*"

SectionEnd



Section -PostInstallSection

    WriteUninstaller "$INSTDIR\Uninstall.exe"

    CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME_EN}"

    CreateShortCut "$DESKTOP\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"

    CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME_EN}\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"

    CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME_EN}\卸载.lnk" "$INSTDIR\Uninstall.exe"

    CreateShortCut "$SMSTARTUP\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"



    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "DisplayName" "${PRODUCT_NAME_EN}"

    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "UninstallString" "$INSTDIR\uninstall.exe"

    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "DisplayIcon" "$INSTDIR\ico-inst.ico"

SectionEnd



Section Uninstall

    RMDir /r /REBOOTOK "$INSTDIR"

    RMDir /r /REBOOTOK "$SMPROGRAMS\${PRODUCT_NAME_EN}"

    Delete /REBOOTOK "$DESKTOP\${INSTALL_NAME}.lnk"

    Delete /REBOOTOK "$SMSTARTUP\${INSTALL_NAME}.lnk"



    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}"

SectionEnd



Function .onInit

  !insertmacro MUI_LANGDLL_DISPLAY

FunctionEnd



Function .onInstSuccess

;    MessageBox MB_YESNO|MB_ICONQUESTION "安装完成,系统重启后才能生效,是否立即重启?" IDNO +2

;        Reboot

FunctionEnd 



Function un.onInit

  !insertmacro MUI_UNGETLANGUAGE

FunctionEnd



Function un.onUninstSuccess

;    MessageBox MB_YESNO|MB_ICONQUESTION "安装完成,系统重启后才能生效,是否立即重启?" IDNO +2

;        Reboot

FunctionEnd

NSIS脚本语法解释

符号说明

!XXXX     NSIS脚本的关键字
;和# NSIS脚本注释标记

定义COMPRESS_DIR和TOOL_DIR两个变量,用来保存目录位置

!ifndef COMPRESS_DIR

!define COMPRESS_DIR ".\build"

!define TOOL_DIR     ".\tool"

!endif

定义几个变量,用来保存程序名称,版本号,公司名称

!define PRODUCT_NAME_CN "测试程序"

!define PRODUCT_NAME_EN "MySolution"

!define PRODUCT_VERSION "V1.0"

!define PRODUCT_PUBLISHER_CN "上海金桥信息工程有限公司"

!define PRODUCT_PUBLISHER_EN "SHGBIT"

定义变量保存打包生成的安装程序的文件名

!define INSTALL_NAME "测试程序-${PRODUCT_VERSION}"

设置程序安装的默认目录,$PROGRAMFILES=X:\Program Files,是NSIS自带的变量

InstallDir $PROGRAMFILES\${PRODUCT_PUBLISHER_EN}\${PRODUCT_NAME_EN}

设置程序名称,这个名称将在安装包的标题栏上显示

Name "${PRODUCT_NAME_EN}"

设置生成安装包的具体路径

outFile ".\deploy\${INSTALL_NAME}.exe"

设置安装过程中显示的图片文件

!define MUI_ICON ".\install-res\ico-inst.ico"

!define MUI_UNICON ".\install-res\ico-uninst.ico"

!define MUI_WELCOMEFINISHPAGE_BITMAP ".\install-res\side.bmp"

!define MUI_HEADERIMAGE

!define MUI_HEADERIMAGE_BITMAP ".\install-res\header.bmp"

设置是否安装完成后运行程序

;!define MUI_FINISHPAGE_RUN "$INSTDIR\xxx.exe"

设置安装过程的步骤,下面定义了5个步骤,分别为欢迎、许可协议、设置安装目录、安装进度、完成安装。

!insertmacro MUI_PAGE_WELCOME

!insertmacro MUI_PAGE_LICENSE ".\install-res\LICENSE"

!insertmacro MUI_PAGE_DIRECTORY

!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_PAGE_FINISH

设置卸载过程的步骤,下面定义了5个步骤,分别为卸载确认、卸载完成。

!insertmacro MUI_UNPAGE_CONFIRM

!insertmacro MUI_UNPAGE_INSTFILES

设置安装过程的语言选择界面,下面只定义了一种语言(简体中文)。

!insertmacro MUI_LANGUAGE "SimpChinese"

# first language is the default language#  !insertmacro MUI_LANGUAGE "English"

设置安装过程中界面下方虚线上写的名称

BrandingText "${INSTALL_NAME}"

设置安装过程中,选择安装目录阶段时显示的提示文字信息

DirText "安装程序将安装 $(^NameDA) 在下列文件夹。要安装到不同文件夹,单击 [浏览(B)] 并选择其他的文件夹。 $_CLICK"

Section有些相当于C#中Event的意思,下面这段表示在所有Section中设置输出路径为"$INSTDIR",设置需要打包的文件为"${COMPRESS_DIR}\MySolution\*.*",/r表示自动覆盖已存在文件。SetOutPath和File都是NSIS的内置函数,还有之前出现过的BrandingText、DirText之类的都是内置函数。

Section "All Components " AllSection

    SetOutPath "$INSTDIR"

    File /r "${COMPRESS_DIR}\MySolution\*.*"

SectionEnd

这是安装过程中文件复制阶段完成后的事件(注:并非点击完成按钮后整个安装过程结束时的事件),下面这段在事件里生成了uninstall.exe 程序,开始菜单添加了快捷方式,桌面添加了快捷方式,系统开机启动里添加了快捷方式,系统注册表中添加了软件安装信息(用于在控制面板的添加删除程序里找到MySolution这个软件)

Section -PostInstallSection

    WriteUninstaller "$INSTDIR\Uninstall.exe"

    CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME_EN}"

    CreateShortCut "$DESKTOP\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"

    CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME_EN}\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"

    CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME_EN}\卸载.lnk" "$INSTDIR\Uninstall.exe"

    CreateShortCut "$SMSTARTUP\${INSTALL_NAME}.lnk" "$INSTDIR\MySolution.exe"



    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "DisplayName" "${PRODUCT_NAME_EN}"

    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "UninstallString" "$INSTDIR\uninstall.exe"

    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}" "DisplayIcon" "$INSTDIR\ico-inst.ico"

SectionEnd

这是程序卸载过程中文件删除阶段完成后的事件,下面这段根据之前的PostInstallSection中写的内容依次进行了删除,这里需要注意卸载过程的完整,否则就成了卸载不干净的垃圾软件了^.^。/r表示递归删除文件夹,/REBOOTOK表示如果文件被占用,则重启之后自动删除。

Section Uninstall

    RMDir /r /REBOOTOK "$INSTDIR"

    RMDir /r /REBOOTOK "$SMPROGRAMS\${PRODUCT_NAME_EN}"

    Delete /REBOOTOK "$DESKTOP\${INSTALL_NAME}.lnk"

    Delete /REBOOTOK "$SMSTARTUP\${INSTALL_NAME}.lnk"



    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_EN}"

SectionEnd

这是双击安装程序时的事件,这里设置为双击之后出现语言选择界面

Function .onInit

 !insertmacro MUI_LANGDLL_DISPLAY

FunctionEnd

这是安装程序退出时的事件,这里将多语言资源卸载

Function un.onInit

  !insertmacro MUI_UNGETLANGUAGE

FunctionEnd

这是安装成功的事件,可以在这个阶段弹出是否要重启的确定框。

Function .onInstSuccess

;    MessageBox MB_YESNO|MB_ICONQUESTION "安装完成,系统重启后才能生效,是否立即重启?" IDNO +2

;        Reboot

FunctionEnd

这是卸载成功的事件,可以在这个阶段弹出是否要重启的确定框。

Function un.onUninstSuccess

;    MessageBox MB_YESNO|MB_ICONQUESTION "安装完成,系统重启后才能生效,是否立即重启?" IDNO +2

;        Reboot

FunctionEnd

你可能感兴趣的:(deploy)