NSIS借助一些插件可以制作出界面很漂亮的安装程序,SkinSE就是使用的比较多的一个插件,迅雷和QQ的安装程序就是NSIS+SkinSE制作的。我比较喜欢windows8风格的界面,所以这次模仿一个Visual Studio2012界面的安装程序。
这次模仿只修改了使用到的控件的主题,未使用的控件图片不进行修改(我PS不是很好,修改图片很痛苦的),修改内容包括Button,CheckBox,最大化按钮,最小化按钮,菜单,滚动条,窗体背景图,分隔符,进度条。在修改的过程中遇到3个问题暂时还没法解决:
1.控件获取焦点后的文字的颜色没法修改,现在颜色默认为黑色,通过几种方式修改均未发现有效果
2.选择安装目录的界面,如果使用SkinSE,界面默认只能看见背景图片,需要将鼠标移动过去才会显示其他信息(这个只会在windows7才出现,windows xp下正常)。如下图所示
3.安装进度界面如果使用自定义页面没法获取安装的具体进度
有能解决以上3个问题的朋友请告诉我一下。
下面是安装界面的截图和脚本代码(安装程序的文字说明和图片使用即将发布的一款软件里面的截图和描述):
主题图片下载:http://files.cnblogs.com/loyldg/skin.rar
NSIS脚本:
!system '>blank set/p=MSCF< ' !packhdr temp.dat 'cmd /c Copy /b temp.dat /b + blank && del blank' !AddPluginDir . SetCompressor /solid lzma SetCompressorDictSize 32 !include "MUI2.nsh" !include "LogicLib.nsh" !include "LoadRTF.nsh" !define MUI_UI MetroUI.exe !define MUI_FINISHPAGE_RUN "$INSTDIR\AutoCall.exe" !define PRODUCT_VERSION "1.0.0.0" !define PRODUCT_PUBLISHER "Loyldg" !define PRODUCT_WEB_SITE "http://www.loyldg.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\AutoCall\autocall.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define EM_SETBKGNDCOLOR 1091 !define MUI_PAGE_HEADER_TEXT " " !define MUI_PAGE_HEADER_SUBTEXT " " !define TextColor "999999" !define MUI_ICON "img\AutoCall.ico" Name "AutoCall" OutFile "MetroUITest.exe" AutoCloseWindow true Caption "AutoCall安装" RequestExecutionLevel admin ShowInstDetails nevershow ShowUninstDetails NeverShow SilentUnInstall silent MiscButtonText "上一歩" "下一步" "取消" "完成" InstallButtonText "下一歩" BrandingText " " InstProgressFlags smooth !define MUI_CUSTOMFUNCTION_GUIINIT myGuiInit Page custom WelcomePage Page custom ChooseInstallDirPage !define MUI_PAGE_CUSTOMFUNCTION_SHOW CreateStaticRect1 !insertmacro MUI_PAGE_INSTFILES Page custom InstallFinishPage AfterInstallFinish !insertmacro MUI_LANGUAGE "SimpChinese" InstallDir "$PROGRAMFILES\Loyldg\AutoCall" Var ImageHandle Var Checkbox1 var Checkbox2 Var steps var rtxt Function .onInit InitPluginsDir File "/oname=$PLUGINSDIR\step1.bmp" "img\a\step1.bmp" File "/oname=$PLUGINSDIR\step2.bmp" "img\a\step2.bmp" File "/oname=$PLUGINSDIR\step3.bmp" "img\a\step3.bmp" File "/oname=$PLUGINSDIR\step4.bmp" "img\a\step4.bmp" File "/oname=$PLUGINSDIR\multiTheme.bmp" "img\a\multiTheme.bmp" File "/oname=$PLUGINSDIR\main.bmp" "img\a\main.bmp" File "/oname=$PLUGINSDIR\tasklist.bmp" "img\a\tasklist.bmp" File "/oname=$PLUGINSDIR\about.bmp" "img\a\about.bmp" File "/oname=$PLUGINSDIR\line.bmp" "img\a\line.bmp" File "/oname=$PLUGINSDIR\license.rtf" "license.rtf" FunctionEnd #=======================初始化界面皮肤====================================================================================================== Function myGuiInit InitPluginsDir File "/oname=$PLUGINSDIR\theme.zip" "theme\theme.zip" File "/oname=$PLUGINSDIR\SkinSE.dll" "SkinSE.dll" SetOutPath $PLUGINSDIR SkinSE_NSIS::setskinpath /NOUNLOAD "$PLUGINSDIR\theme.zip" System::Call SkinSE::SkinSE_Menu_EnableSkin(i1) ;创建互斥防止重复运行 System::Call 'kernel32::CreateMutexA(i 0, i 0, t "autocall_installer") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "已经有一个AutoCall安装向导正在运行! " Abort FunctionEnd Function .onGUIEnd SkinSE::UnstallSkinSE System::Call Kernel32::GetModuleHandle(t"SkinSE_NSIS.dll")i.s System::Call Kernel32::FreeLibrary(is) System::Call Kernel32::SetCurrentDirectory(t"$EXEDIR\") FunctionEnd #===============================欢迎界面==================================================================================== Function WelcomePage SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:AutoCall 欢迎安装AutoCall" nsDialogs::Create /NOUNLOAD 1018 Pop $0 ${If} $0 == error Abort ${EndIf} System::Call SkinSE::SkinSE_Init(i$HWNDPARENT,i1) ${NSD_CreateLabel} 10u 14u 290u 8u "在安装软件前,请仔细阅读下面的软件许可协议" Pop $0 SetCtlColors $0 ${TextColor} transparent nsDialogs::CreateControl "RichEdit20A" \ "${DEFAULT_STYLES}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_READONLY}" \ "${WS_EX_WINDOWEDGE}|${WS_EX_CLIENTEDGE}" 9u 28u 337u 132u "" Pop $rtxt ${LoadRTF} "$PLUGINSDIR\license.rtf" $rtxt ${NSD_CreateCheckbox} 10u 166u 155u 15u "我已阅读并同意软件许可协议书" Pop $Checkbox1 ${NSD_OnClick} $Checkbox1 onCheckbox1 setctlcolors $Checkbox1 "999999" transparent SendMessage $rtxt ${EM_SETBKGNDCOLOR} 0 0x303030 GetDlgItem $steps $HWNDPARENT 1 EnableWindow $steps 0 ${NSD_CreateBitmap} 0u 210u 100% 1u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\line.bmp $ImageHandle ${NSD_CreateBitmap} 245u 190u 100% 100% "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\step1.bmp $ImageHandle nsDialogs::Show ${NSD_FreeImage} $ImageHandle FunctionEnd #---------------------------------------------------------------------------------------------------------------------# #=======================选择安装目录=================================================================================== Function ChooseInstallDirPage SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:AutoCall 选择安装路径" nsDialogs::Create /NOUNLOAD 1018 Pop $0 ${If} $0 == error Abort ${EndIf} ${NSD_CreateLabel} 10u 27u 70u 10u "程序安装目录" Pop $0 SetCtlColors $0 ${TextColor} transparent ${NSD_CreateBitmap} 0u 10u 100% 1u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\line.bmp $ImageHandle ${NSD_CreateDirRequest} 60u 23u 225u 12u $INSTDIR Pop $1 ${NSD_CreateButton} 300u 23u 45u 15u "浏览(&B)" Pop $0 ${NSD_OnClick} $0 OnDirRequest ${NSD_CreateBitmap} 10u 55u 100% 5u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\multiTheme.bmp $ImageHandle SetCtlColors $0 "" transparent ${NSD_CreateBitmap} 0u 210u 100% 1u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\line.bmp $ImageHandle ${NSD_CreateBitmap} 245u 190u 100% 100% "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\step2.bmp $ImageHandle System::Call SkinSE::SkinSE_Init(i$HWNDPARENT,i1) nsDialogs::Show ${NSD_FreeImage} $ImageHandle FunctionEnd #-----------------------------------------------------------------------------------------# Function onCheckbox1 Pop $Checkbox1 SendMessage $Checkbox1 ${BM_GETCHECK} 0 0 $0 EnableWindow $steps $0 FunctionEnd function onCheckbox2 pop $Checkbox2 sendmessage $checkbox2 ${BM_GETCHECK} 0 0 $0 functionend #-----------------------------------------------------------# Function OnDirRequest nsDialogs::SelectFolderDialog /NOUNLOAD "$\n请选择目录" "" Pop $0 ${If} $0 != error ${NSD_SetText} $1 $0 ${EndIf} FunctionEnd #-----------------------------------------------------------# #=========================显示主界面图片================================================================= Function CreateStaticRect1 SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:AutoCall 正在安装..." FindWindow $0 "#32770" "" $HWNDPARENT GetDlgItem $R0 $0 59 ${NSD_SetImage} $R0 "$PLUGINSDIR\main.bmp" $ImageHandle functionend Function HideImageCtrl FindWindow $0 "#32770" "" $HWNDPARENT GetDlgItem $R0 $0 59 ShowWindow $R0 ${SW_HIDE} GetDlgItem $R0 $0 1202 ShowWindow $R0 ${SW_HIDE} functionend #==============================安装完成页面======================================================================== Function InstallFinishPage SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:AutoCall 安装完成" call HideImageCtrl GetDlgItem $0 $HWNDPARENT 3 ShowWindow $0 ${SW_HIDE} nsDialogs::Create /NOUNLOAD 1018 Pop $0 ${If} $0 == error Abort ${EndIf} ${NSD_CreateLabel} 10u 18u 60u 10u "安装完成" Pop $0 SetCtlColors $0 ${TextColor} transparent ${NSD_CreateBitmap} 0u 10u 100% 1u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\line.bmp $ImageHandle ${NSD_CreateBitmap} 0u 55u 100% 5u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\about.bmp $ImageHandle ${NSD_CreateCheckbox} 68u 32u 140u 15u "立即运行AutoCall" Pop $Checkbox2 ${NSD_Check} $Checkbox2 ${NSD_OnClick} $Checkbox2 onCheckbox2 setctlcolors $Checkbox2 "" C5DEF0 ${NSD_CreateBitmap} 0u 210u 100% 1u "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\line.bmp $ImageHandle ${NSD_CreateBitmap} 245u 190u 100% 100% "" Pop $0 ${NSD_SetImage} $0 $PLUGINSDIR\step4.bmp $ImageHandle System::Call SkinSE::SkinSE_Init(i$HWNDPARENT,i1) nsDialogs::Show ${NSD_FreeImage} $ImageHandle FunctionEnd #-----------------------------------------------------------------------------------------# #=======================安装完成后要执行的操作============================================ Function AfterInstallFinish ${NSD_GetState} $Checkbox2 $0 ${if} $0 == 1 exec "$INSTDIR\AutoCall.exe" ${endif} quit FunctionEnd #========================卸载=================================================================== Function un.onInit InitPluginsDir System::Call 'kernel32::CreateMutexA(i 0, i 0, t "autocall_uninstaller") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "已经有一个AutoCall卸载向导正在运行! " Abort MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,其及所有的组件? " /SD IDYES IDNO +7 execwait "$INSTDIR\NetAssistant.Uninstall.exe" $0 ${if} $0 == 1 Abort ${elseif} $0 == 2 goto End1 ${endif} Abort End1: FunctionEnd Function un.onGUIEnd FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。 " FunctionEnd #=======================安装的具体操作====================================================== Section Main SetOutPath "$INSTDIR" SetOverwrite try File /r "files\*.*" sleep 5000 SectionEnd #-----------------------------------------------------------------------------------------# Section -Addtion CreateShortCut "$DESKTOP\AutoCall.lnk" "$INSTDIR\AutoCall.exe" "" "" "" "" "" "AutoCall" CreateDirectory "$SMPROGRAMS\AutoCall" CreateShortCut "$SMPROGRAMS\AutoCall\AutoCall.lnk" "$INSTDIR\AutoCall.exe" CreateShortCut "$SMPROGRAMS\AutoCall\AutoCall卸载.lnk" "$INSTDIR\uninst.exe" GetDlgItem $0 $HWNDPARENT 1 EnableWindow $0 1 SendMessage $0 ${BM_CLICK} 0 0 sectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" SectionEnd Section Uninstall sleep 1000 Delete "$INSTDIR\*.*" RMDir "$INSTDIR" Delete "$SMPROGRAMS\AutoCall\AutoCall.lnk" Delete "$SMPROGRAMS\AutoCall\AutoCall卸载.lnk" RMDir "$SMPROGRAMS\AutoCall" Delete "$DESKTOP\AutoCall.lnk" SetAutoClose true SectionEnd