转自:http://blog.csdn.net/lee353086/article/details/45919901

NSIS学习笔记
Date:2015-05-20
Author:kagula
Env:VS2013Update4、nsis-2.46.5-Unicode-setup.exe、CoolSoft_NSISDialogDesigner_1.4.0、eclipse-jee-kepler-SR2-win32、Win7-64bits

设置NSIS环境
Step1:(编译NSIS脚本)

从http://www.scratchpaper.com/网站下载“nsis-2.46.5-Unicode-setup.exe”文件并安装。

Step2:(NSIS脚本语法高亮)
参考资料[3]为Eclipse安装NSIS插件,用来编译NSIS脚本。
[Eclipse main menu]->[Help]->[Install new software...]->type the nsis http address and select component to install.
这里要注意的是
 [1]Eclipse NSIS插件不支持JDK1.8或更高版本。不支持Windows8或更高版本。
 [2]要先建一个空的project,然后通过向导添加NSIS Script会报错。错误信息为空。
 [3]通过向导添加Install Options文件(ini)文件

输出文件名必须为[/"项目名"/"你文件的事名字"]这种形式,否则会报输出文件名非法的提示。

[4]你可能通过outline子窗口,快速定位NSI脚本中的变量与函数。

现在你可以直接把nsi文件拖入Eclipse中编辑了。
最新版本(不稳定版)可以直接从下面网址下载
https://github.com/henrikor2/eclipsensis

Step3:(自定义GUI)
参考资料[1]下载"CoolSoft_NSISDialogDesigner_1.4.0.exe",我们需要这个工具来自定义安装界面。

最简单的流程是
第一步:先在EclipseNSIS(或其它NSIS脚本编辑器)里把脚本写好.
第二步:启动NSIS compiler。[NSIS Menu]->[Compiler]->[compiler NSI scripts]。
第三步:把nsi文件,拖到NSIS compiler里,NSIS compiler会自动编译,setup.exe的生成。

要使用NSIS首先得学会使用它的脚本语言,NSIS脚本的每一行代表命令,源文件扩展名为nsi,头文件扩展名为.nsh。

一个软件可能有很多组件组成,NSIS用section代表每个组件。示例代码如下:
Section "My Program"
  SetOutPath $INSTDIR
  File "My Program.exe"
  File "Readme.txt"
SectionEnd

下面是一个典型的NSIS示例代码,除了自定义页面风格,该有的都有了。

  1. # All the other settings can be tweaked by editing the !defines at the top of this script
  2. !define APPNAME "比价系统"
  3. !define COMPANYNAME "浙江天下商邦科技股份有限公司"
  4. !define SETUPFILENAME "setup.exe"
  5. !define DESCRIPTION ""
  6.  
  7. !define APPEXENAME "cat8637_priceComparingSystem.exe"
  8.  
  9. # These three must be integers
  10. # 这里定义的是安装包的版本,应该和当前主程序(EXE文件)的版本一致
  11. !define VERSIONMAJOR
  12. !define VERSIONMINOR
  13. !define VERSIONBUILD
  14. !define VERSIONREVISION
  15.  
  16. #定义当前软件(EXE文件)的版本
  17. !define VERSIONLONG "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}.${VERSIONREVISION}"
  18.  
  19. #安装程序ico文件名和位置
  20. !define ICOFILENAME "cat8637_brand2.ico"
  21. !define ICOFULLPATH "..\PriceComparingSystem\res\${ICOFILENAME}"
  22.  
  23. # These will be displayed by the "Click here for support information" link in "Add/Remove Programs"
  24. # It is possible to use "mailto:" links in here to open the email client
  25. !define HELPURL "http://www.8637.com/" # "Support Information" link
  26. !define UPDATEURL "http://www.8637.com/" # "Product Updates" link
  27. !define ABOUTURL "http://www.8637.com/" # "Publisher" link
  28.  
  29. # This is the size (in kB) of all the files copied into "Program Files"
  30. # issue 目录的大小
  31. !define INSTALLSIZE
  32.  
  33. RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
  34.  
  35. InstallDir "$PROGRAMFILES\${COMPANYNAME}\${APPNAME}"
  36.  
  37. # rtf or txt file - remember if it is txt, it must be in the DOS text format (\r\n)
  38.  
  39. #MUI macro define
  40. !define MUI_PAGE_HEADER_TEXT ${COMPANYNAME}
  41. !define MUI_PAGE_HEADER_SUBTEXT '${APPNAME} v${VERSIONLONG}'
  42. !define MUI_ICON ${ICOFULLPATH}
  43.  
  44. # This will be in the installer/uninstaller's title bar
  45. Name "${APPNAME}"
  46. Icon "${ICOFULLPATH}"
  47. outFile "${SETUPFILENAME}"
  48. ;BrandingText '${APPNAME} v${VERSIONLONG}'
  49. BrandingText '$0'
  50.  
  51. !include LogicLib.nsh
  52. !include nsProcess.nsh
  53.  
  54. #include custom page reference
  55. !include "MUI2.nsh"
  56. !include "nsDialogs.nsh"
  57. !include "kagulaWelcomePage.nsdinc"
  58.  
  59. # Just three pages - license agreement, install location, and installation
  60. #!insertmacro MUI_PAGE_WELCOME
  61. ;Page custom fnc_kagulaWelcomePage_Show
  62. ;page license
  63. ;page directory
  64. ;Page instfiles
  65. !insertmacro MUI_PAGE_LICENSE "license.rtf"
  66. !insertmacro MUI_PAGE_DIRECTORY
  67. !insertmacro MUI_PAGE_INSTFILES
  68.  
  69. !insertmacro MUI_UNPAGE_CONFIRM
  70. !insertmacro MUI_UNPAGE_INSTFILES
  71. !insertmacro MUI_UNPAGE_FINISH
  72.  
  73. !insertmacro MUI_LANGUAGE "SimpChinese"
  74.  
  75. !macro VerifyUserIsAdmin
  76. UserInfo::GetAccountType
  77. pop $
  78. ${If} $ != "admin" ;Require admin rights on NT4+
  79. messageBox mb_iconstop "需要管理员权限!"
  80. setErrorLevel ;ERROR_ELEVATION_REQUIRED
  81. quit
  82. ${EndIf}
  83. !macroend
  84.  
  85. !include "FileFunc.nsh"
  86. Var VersionNumber
  87.  
  88. Function VerCheck
  89. pop $
  90. ;${GetFileVersion} "$INSTDIR\${APPEXENAME}" $VersionNumber
  91. ${GetFileVersion} "$0" $VersionNumber
  92. FunctionEnd
  93.  
  94. Function VersionCompare
  95. !define VersionCompare `!insertmacro VersionCompareCall`
  96.  
  97. !macro VersionCompareCall _VER1 _VER2 _RESULT
  98. Push `${_VER1}`
  99. Push `${_VER2}`
  100. Call VersionCompare
  101. Pop ${_RESULT}
  102. !macroend
  103.  
  104. Exch $
  105. Exch
  106. Exch $
  107. Exch
  108. Push $
  109. Push $
  110. Push $
  111. Push $
  112. Push $
  113. Push $
  114.  
  115. begin:
  116. StrCpy $ -
  117. IntOp $ $ +
  118. StrCpy $ $ $
  119. StrCmp $ '' +
  120. StrCmp $ '.' -
  121. StrCpy $ $ $
  122. IntOp $ $ +
  123. StrCpy $ $ '' $
  124.  
  125. StrCpy $ -
  126. IntOp $ $ +
  127. StrCpy $ $ $
  128. StrCmp $ '' +
  129. StrCmp $ '.' -
  130. StrCpy $ $ $
  131. IntOp $ $ +
  132. StrCpy $ $ '' $
  133.  
  134. StrCmp $$ '' equal
  135.  
  136. StrCpy $ -
  137. IntOp $ $ +
  138. StrCpy $ $ $
  139. StrCmp $ '' -
  140. StrCmp $ '' +
  141. StrCpy $
  142.  
  143. StrCpy $ -
  144. IntOp $ $ +
  145. StrCpy $ $ $
  146. StrCmp $ '' -
  147. StrCmp $ '' +
  148. StrCpy $
  149.  
  150. StrCmp $ +
  151. StrCmp $ begin newer2
  152. StrCmp $ newer1
  153. IntCmp $ $ newer1 newer2
  154.  
  155. StrCpy $ '1$4'
  156. StrCpy $ '1$5'
  157. IntCmp $ $ begin newer2 newer1
  158.  
  159. equal:
  160. StrCpy $
  161. goto end
  162. newer1:
  163. StrCpy $
  164. goto end
  165. newer2:
  166. StrCpy $
  167.  
  168. end:
  169. Pop $
  170. Pop $
  171. Pop $
  172. Pop $
  173. Pop $
  174. Pop $
  175. Pop $
  176. Exch $
  177. FunctionEnd
  178.  
  179. function .onInit
  180. setShellVarContext all
  181. !insertmacro VerifyUserIsAdmin
  182.  
  183. #check program running.
  184. ${nsProcess::FindProcess} ${APPEXENAME} $R0
  185. ${If} $R0 == ""
  186. # it's running
  187. MessageBox MB_OK "软件正在运行,按确定退出!"
  188. Quit
  189. ${EndIf}
  190.  
  191. ; MessageBox MB_OK "当前软件的版本为:${VERSIONLONG}"
  192. #check version from custom install place
  193. ReadRegStr $ HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "MainProgramLocation"
  194. ${If} $ != ""
  195. ; MessageBox MB_OK "文件位置:$0"
  196. ${If} ${FileExists} $
  197. ; #if installed version is greater, return 2
  198. ; #else if equality, return 0.
  199. ; #else if less, return 1 and resume install process.
  200. ; #MessageBox MB_OK "Version=$R0"
  201. ; MessageBox MB_OK "before push the parameter for VerCheck function.$0"
  202. push $
  203. Call VerCheck
  204. ${VersionCompare} $VersionNumber ${VERSIONLONG} $R0
  205. ${if} $R0 != ""
  206. MessageBox MB_OK "你已经安装同版本或较新版本${APPNAME}软件,按确定退出安装!"
  207. Quit
  208. ${Endif}
  209. ${EndIf}
  210. ; ${Else}
  211. ; MessageBox MB_ICONSTOP "Not found"
  212. ${EndIf}
  213. functionEnd
  214.  
  215. section "install"
  216. # Files for the install directory - to build the installer, these should be in the same directory as the install script (this file)
  217. setOutPath $INSTDIR
  218.  
  219. # Files added here should be removed by the uninstaller (see section "uninstall")
  220. File /r "..\issue\"
  221. file "${ICOFULLPATH}"
  222. # Add any other files for the install directory (license files, app data, etc) here
  223.  
  224. # Uninstaller - See function un.onInit and section "uninstall" for configuration
  225. writeUninstaller "$INSTDIR\uninstall.exe"
  226.  
  227. # Start Menu
  228. createDirectory "$SMPROGRAMS\${COMPANYNAME}"
  229. createShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" "$INSTDIR\${APPEXENAME}" "" "$INSTDIR\${ICOFILENAME}"
  230.  
  231. # create a shortcut named "new shortcut" in the start menu programs directory
  232. # point the new shortcut at the program uninstaller
  233. CreateShortCut "$SMPROGRAMS\${COMPANYNAME}\卸载.lnk" "$INSTDIR\uninstall.exe"
  234.  
  235. # Registry information for add/remove programs
  236. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${COMPANYNAME} - ${APPNAME} - ${DESCRIPTION}"
  237. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
  238. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
  239. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$\"$INSTDIR$\""
  240. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\${ICOFILENAME}$\""
  241. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "$\"${COMPANYNAME}$\""
  242. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "HelpLink" "$\"${HELPURL}$\""
  243. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "$\"${UPDATEURL}$\""
  244. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\""
  245. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "$\"${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}.${VERSIONREVISION}$\""
  246. WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR}
  247. WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR}
  248.  
  249. # There is no option for modifying or repairing the install
  250. WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify"
  251. WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair"
  252.  
  253. # Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size
  254. WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE}
  255.  
  256. #Write file install location to register table.
  257. WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "MainProgramLocation" "$INSTDIR\${APPEXENAME}"
  258. sectionEnd
  259.  
  260. # Uninstaller
  261.  
  262. function un.onInit
  263. SetShellVarContext all
  264.  
  265. #Verify the uninstaller - last chance to back out
  266. MessageBox MB_OKCANCEL "确定要移除 ${APPNAME} 吗?" IDOK next
  267. Abort
  268. next:
  269. !insertmacro VerifyUserIsAdmin
  270. functionEnd
  271.  
  272. section "uninstall"
  273.  
  274. # Remove Start Menu launcher
  275. delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk"
  276. delete "$SMPROGRAMS\${COMPANYNAME}\卸载.lnk"
  277.  
  278. # Try to remove the Start Menu folder - this will only happen if it is empty
  279. rmDir "$SMPROGRAMS\${COMPANYNAME}"
  280.  
  281. # Remove files
  282. delete $INSTDIR\${ICOFILENAME}
  283.  
  284. # Always delete uninstaller as the last action
  285. delete $INSTDIR\uninstall.exe
  286.  
  287. # Try to remove the install directory - this will only happen if it is empty
  288. rmDir /r $INSTDIR
  289.  
  290. # Remove uninstaller information from the registry
  291. DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}"
  292. sectionEnd

Q1、中文问题
参考资料[1]里的nsis-3.0b1-setup.exe是不支持中文的,得下载nsis-2.46.5-Unicode-setup.exe。
源文件设为utf-8编码类型。
采用下面的代码测试
     CreateShortCut "$SMPROGRAMS\中文测试.lnk" "$INSTDIR\uninstall.exe"
     MessageBox MB_OK  "中文测试" 
是可以正常显示中文的。

参考下面的代码段,把安装界面弄成中文
!include "MUI2.nsh"
..................
!insertmacro MUI_LANGUAGE "SimpChinese"

Q2、如何测试进程已经运行?
A:需要四个步骤。
第一步:从“http://nsis.sourceforge.net/NsProcess_plugin”下载nsProcess_1_6.7z
第二步:覆盖NSIS Unicode安装目录的目录树
第三步:把当前plugin目录中的nsProcessW.dll文件复制到Plugins目录并重命名为nsProcess.dll。
第四步:参数下面的代码修改即可
    ${nsProcess::FindProcess} "calc.exe" $R0
    ${If} $R0 == "0"
        # it's running
        MessageBox MB_OK "程序已经运行,按确定退出!"
        Quit
    ${EndIf}

Q3、如何使用NSISDialogDesigner
A1:
使用NSISDialogDesigner生成kagulaWelcomePage.nsdinc文件
在你的nsi主文件里,专门放Page命令的地方,添加下面的代码
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "kagulaWelcomePage.nsdinc"

Page custom fnc_kagulaWelcomePage_Show
就会显示你自定义的页面,不过你会发现它是在frame里面。

Q4、关于Modern User Interface同NSIS传统的区别
显示license页面,MUI采用下面这行命令:
LicenseData "license.rtf"
page license
MUI方式采用下面这个命令。
!insertmacro MUI_PAGE_LICENSE "license.rtf"

Q5 如何实现高压缩比

SetCompressor lzma

Q6 NSIS 打包 win7 中无法删除快捷方式

http://www.cnblogs.com/08shiyan/archive/2011/01/10/1931766.html

参数资料
[1]NSIS Dialog Designer
http://coolsoft.altervista.org/en/nsisdialogdesigner#download
[2]NSIS home page
http://nsis.sourceforge.net/Main_Page
[3]Eclipse NSIS
http://eclipsensis.sourceforge.net/index.shtml
[4]Auto-uninstall old before installing new
http://nsis.sourceforge.net/Auto-uninstall_old_before_installing_new
[5]NSIS常见问题集锦 推荐新手参考学习
http://www.jb51.net/softjc/33522.html
[6]Unicode NSIS调用nsProcess插件报错
http://tunps.com/nsis-unicode-nsprocess-error
[7]NSIS detection of a 32-bit process in Win 7 x64
http://stackoverflow.com/questions/5353666/nsis-detection-of-a-32-bit-process-in-win-7-x64
[8]NSIS Modern User Interface
http://nsis.sourceforge.net/Docs/Modern%20UI/Readme.html#examples
[9]Customizing an exsisting NSIS MUI2 page
http://stackoverflow.com/questions/6531115/customizing-an-exsisting-nsis-mui2-page
[10]A sample script that uses several cool functions (replace txt, mutually exclusive functions, MUI, patch install, etc.)
http://nsis.sourceforge.net/A_sample_script_that_uses_several_cool_functions_(replace_txt,_mutually_exclusive_functions,_MUI,_patch_install,_etc.)
[11]NSIS 自定义安装界面准确获取安装进度完美解决方案
http://blog.csdn.net/shuijing_0/article/details/8291299
[12]DB 数据库地址及路径配置函数
http://www.cnblogs.com/freeliver54/archive/2010/11/26/1888902.html
[13]NSIS软件安装完成界面添加“设置主页”代码
http://www.veryhuo.com/a/view/40444.html

NSIS学习笔记(转)的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. Data Flow ->> CDC Control Task, CDC Source, CDC Splitter

    CDC Control Task可以从控制CDC数据同步,比如初始化加载.LSN范围的管理.它可以代替另一种做法,就是通过调用一批CDC函数来完成同样的事情.从SSIS的角度来完成,事情编程简单,和另 ...

  2. Linux系统中的load average

    1. load average 定义 linux系统中的Load对当前CPU工作量的度量.简单的说是进程队列的长度. Load Average 就是一段时间 (1 分钟.5分钟.15分钟) 内平均 L ...

  3. notepad++使用技巧及插件汇总

    NppAutoIndent 自动缩进CCompletion 自动补全.TextFX 插件nppFTP 运行程序 ============================================ ...

  4. Linux操作系统基础(四)保护模式内存管理(2)【转】

    转自:http://blog.csdn.net/rosetta/article/details/8570681 Linux操作系统基础(四)保护模式内存管理(2) 转载请注明出处:http://blo ...

  5. 日期工具类 - DateUtil.java

    日期工具类,提供对日期的格式化和转换方法.获取区间日期.指定日期.每月最后一天等. 源码如下:(点击下载 -DateUtil.java.commons-lang-2.6.jar ) import ja ...

  6. 二叉搜索树的两种实现(数组模拟,STL)

    书上实现: 二叉搜索数的特点:高效实现 插入一个数值,查询是否包含某个数值,删除某一个数值. 所有的节点都满足左子树上的所有节点都比自己的小,而右子树上的所有节点都比自己大的特点. 查询:如果当前数值 ...

  7. POJ -3050 Hopscotch

    http://poj.org/problem?id=3050 给定一个5×5矩阵,问选6个数的不同排列总数是多少! 二维的搜索,注意要判重,数据量很小,直接用map就好. #include<cs ...

  8. How to: Synchronize Files by Using Managed Code

    The examples in this topic focus on the following Sync Framework types: FileSyncProvider FileSyncOpt ...

  9. leetcode:Swap Nodes in Pairs

    Given a linked list, swap every two adjacent(相邻的) nodes and return its head. For example,Given 1-> ...

  10. HTML的列表标签

    一.上下层列表标签:<dl>..</dl>: 上层dt 下层dd:封装的内容会被自动缩进的效果 <dl> <dt>运动户外</dt> < ...