NSIS制作Windows8风格安装界面(模仿Visual Studio 2012的主题和颜色)

NSIS借助一些插件可以制作出界面很漂亮的安装程序,SkinSE就是使用的比较多的一个插件,迅雷和QQ的安装程序就是NSIS+SkinSE制作的。我比较喜欢windows8风格的界面,所以这次模仿一个Visual Studio2012界面的安装程序。

这次模仿只修改了使用到的控件的主题,未使用的控件图片不进行修改(我PS不是很好,修改图片很痛苦的),修改内容包括Button,CheckBox,最大化按钮,最小化按钮,菜单,滚动条,窗体背景图,分隔符,进度条。在修改的过程中遇到3个问题暂时还没法解决:

1.控件获取焦点后的文字的颜色没法修改,现在颜色默认为黑色,通过几种方式修改均未发现有效果

2.选择安装目录的界面,如果使用SkinSE,界面默认只能看见背景图片,需要将鼠标移动过去才会显示其他信息(这个只会在windows7才出现,windows xp下正常)。如下图所示

3.安装进度界面如果使用自定义页面没法获取安装的具体进度

有能解决以上3个问题的朋友请告诉我一下。

下面是安装界面的截图和脚本代码(安装程序的文字说明和图片使用即将发布的一款软件里面的截图和描述):

主题图片下载:https://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
posted @ 2012-09-18 23:05  loyldg  阅读(7780)  评论(3编辑  收藏  举报