zoukankan      html  css  js  c++  java
  • Product deploy using NAnt and NSIS [技术点滴]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://canmusic.blogbus.com/logs/63480254.html

    参考网址

    Example

    运行环境配置

    解压缩附件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="gb2312" ?>

    <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

    历史上的今天:

    UDP Multicast 2010年05月13日
    TreeView In WPF 2010年05月13日
    MVCNetwork Introduction 2010年05月13日

    收藏到:Del.icio.us




  • 相关阅读:
    在Win10中通过命令行打开UWP应用
    前端学习Docker
    Puppeteer的使用
    taro教程
    22种开源Vue模板和主题框架「干货」
    36种免费React模板和主题「干货」
    移动端1px显示异常解决方案
    前端性能优化(二)
    Vue.set()和this.$set()源码解析
    2018年8月7日 乐视2 X621 刷机包下载链接
  • 原文地址:https://www.cnblogs.com/kevinzhwl/p/1850503.html
Copyright © 2011-2022 走看看