Added /Build

This commit is contained in:
Birunthan Mohanathas
2012-03-14 21:18:19 +02:00
parent 8e4d37a8ea
commit 7a0ec6c129
104 changed files with 5889 additions and 8 deletions

BIN
Build/Installer/Header.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
Build/Installer/Icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,937 @@
!verbose 3
!addplugindir ".\"
!ifndef VER
!define VER "0.0"
!define REV "000"
!endif
!ifdef BETA
!define OUTFILE "Rainmeter-${VER}-r${REV}-beta.exe"
!else
!define OUTFILE "Rainmeter-${VER}.exe"
!endif
Name "Rainmeter"
VIAddVersionKey "ProductName" "Rainmeter"
VIAddVersionKey "FileDescription" "Rainmeter Installer"
VIAddVersionKey "FileVersion" "${VER}.0"
VIAddVersionKey "ProductVersion" "${VER}.0.${REV}"
VIAddVersionKey "OriginalFilename" "${OUTFILE}"
VIAddVersionKey "LegalCopyright" "Copyright (C) 2009-2012 - All authors"
VIProductVersion "${VER}.0.${REV}"
BrandingText " "
SetCompressor /SOLID lzma
RequestExecutionLevel user
InstallDirRegKey HKLM "SOFTWARE\Rainmeter" ""
XPStyle on
OutFile "..\${OUTFILE}"
ReserveFile "${NSISDIR}\Plugins\LangDLL.dll"
ReserveFile "${NSISDIR}\Plugins\nsDialogs.dll"
ReserveFile "${NSISDIR}\Plugins\System.dll"
ReserveFile ".\UAC.dll"
!include "MUI2.nsh"
!include "x64.nsh"
!include "ProcFunc.nsh"
!include "FileFunc.nsh"
!include "WordFunc.nsh"
!include "WinVer.nsh"
!include "UAC.nsh"
!define BCM_SETSHIELD 0x0000160c
!define MUI_HEADERIMAGE
!define MUI_ICON ".\Icon.ico"
!define MUI_UNICON ".\Icon.ico"
!define MUI_HEADERIMAGE_BITMAP ".\Header.bmp"
!define MUI_HEADERIMAGE_UNBITMAP ".\Header.bmp"
!define MUI_WELCOMEFINISHPAGE_BITMAP ".\Wizard.bmp"
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION FinishRun
!define MUI_PAGE_CUSTOMFUNCTION_SHOW PageWelcomeOnShow
!insertmacro MUI_PAGE_WELCOME
Page custom PageOptions PageOptionsOnLeave
!define MUI_PAGE_CUSTOMFUNCTION_SHOW PageDirectoryOnShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE PageDirectoryOnLeave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
UninstPage custom un.PageOptions un.GetOptions
!insertmacro MUI_UNPAGE_INSTFILES
!macro IncludeLanguage LANGUAGE CUSTOMLANGUAGE
; Modified variant of the MUI_LANGUAGE macro in Localization.h
; Uses "EnglishLangName (LocalizedLangName)" instead of "LocalizedLangName" for the language selection dialog
!insertmacro MUI_INSERT
LoadLanguageFile "${NSISDIR}\Contrib\Language files\${LANGUAGE}.nlf"
; Include language file
!insertmacro LANGFILE_INCLUDE_WITHDEFAULT "${NSISDIR}\Contrib\Language files\${LANGUAGE}.nsh" "${NSISDIR}\Contrib\Language files\English.nsh"
;Add language to list of languages for selection dialog
!ifndef MUI_LANGDLL_LANGUAGES
!define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' "
!define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_IDNAME} - ${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' "
!else
!ifdef MUI_LANGDLL_LANGUAGES_TEMP
!undef MUI_LANGDLL_LANGUAGES_TEMP
!endif
!define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}"
!undef MUI_LANGDLL_LANGUAGES
!ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP
!undef MUI_LANGDLL_LANGUAGES_CP_TEMP
!endif
!define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}"
!undef MUI_LANGDLL_LANGUAGES_CP
!define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}"
!define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_IDNAME} - ${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}"
!endif
!insertmacro LANGFILE_INCLUDE "..\..\Language\${CUSTOMLANGUAGE}.nsh"
!macroend
!include "Languages.nsh"
; Error levels (for silent install)
!define ERROR_UNSUPPORTED 3
!define ERROR_NOTADMIN 4
!define ERROR_WRITEFAIL 5
!define ERROR_NOVCREDIST 6
!define ERROR_CLOSEFAIL 7
Var ctlDesktop
Var ctlStartup
Var ctlAllUsers
Var ctlDelete
Var ctlStandard
Var ctlPortable
Var ctlBit32
Var ctlBit64
Var instArc
Var instType
Var defLang
; Install
; --------------------------------------
Function .onInit
${If} ${RunningX64}
${EnableX64FSRedirection}
${EndIf}
${IfNot} ${UAC_IsInnerInstance}
${If} ${IsWin2000}
${If} ${Silent}
SetErrorLevel ${ERROR_UNSUPPORTED}
${Else}
MessageBox MB_OK|MB_ICONINFORMATION "$(WIN2KERROR)"
${EndIf}
Quit
${ElseIf} ${IsWinXP}
${AndIf} ${AtMostServicePack} 1
${If} ${Silent}
SetErrorLevel ${ERROR_UNSUPPORTED}
${Else}
MessageBox MB_OK|MB_ICONINFORMATION "$(WINXPS2ERROR)"
${EndIf}
Quit
${ElseIf} ${IsWin2003}
${AndIf} ${AtMostServicePack} 0
${If} ${Silent}
SetErrorLevel ${ERROR_UNSUPPORTED}
${Else}
MessageBox MB_OK|MB_ICONINFORMATION "$(WIN2003SP1ERROR)"
${EndIf}
Quit
${EndIf}
StrCpy $R0 $LANGUAGE
StrCpy $defLang "0"
ReadRegDWORD $0 HKLM "SOFTWARE\Rainmeter" "NonDefault"
${If} $0 == 1
; Rainmeter already installed and user selected non-default language last time
ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" "Language"
${If} $0 != ""
StrCpy $LANGUAGE $0
${EndIf}
${EndIf}
${IfNot} ${Silent}
LangDLL::LangDialog "$(^SetupCaption)" "Please select the installer language.$\n$(SELECTLANGUAGE)" AC ${MUI_LANGDLL_LANGUAGES_CP} ""
Pop $LANGUAGE
${If} $LANGUAGE == "cancel"
Abort
${EndIf}
${If} $LANGUAGE == $R0
; User selected default language
StrCpy $defLang "1"
${EndIf}
${Else}
${GetParameters} $R1
ClearErrors
${GetOptions} $R1 "/LANGUAGE=" $0
${IfNot} ${Errors}
StrCpy $LANGUAGE $0
${EndIf}
${If} $LANGUAGE == $R0
; User selected default language
StrCpy $defLang "1"
${EndIf}
${GetOptions} $R1 "/DESKTOPSHORTCUT=" $0
${If} $0 = 1
StrCpy $ctlDesktop "1"
${EndIf}
${GetOptions} $R1 "/STARTUP=" $0
${If} $0 = 1
StrCpy $ctlStartup "1"
${EndIf}
${GetOptions} $R1 "/ALLUSERS=" $0
${If} $0 = 1
StrCpy $ctlAllUsers "1"
${EndIf}
${GetOptions} $R1 "/PORTABLE=" $0
${If} $0 = 1
StrCpy $instType "P"
${Else}
${IfNot} ${UAC_IsAdmin}
SetErrorLevel ${ERROR_NOTADMIN}
Quit
${EndIf}
StrCpy $instType "S"
${EndIf}
${GetOptions} $R1 "/VERSION=" $0
${If} $0 = 64
StrCpy $instArc "x64"
${If} $INSTDIR == ""
StrCpy $INSTDIR "$PROGRAMFILES64\Rainmeter"
${EndIf}
${Else}
StrCpy $instArc "x86"
${If} $INSTDIR == ""
StrCpy $INSTDIR "$PROGRAMFILES\Rainmeter"
${EndIf}
${EndIf}
ClearErrors
CreateDirectory "$INSTDIR"
WriteINIStr "$INSTDIR\_rainmeter_writetest.tmp" "1" "1" "1"
Delete "$INSTDIR\_rainmeter_writetest.tmp"
${If} ${Errors}
SetErrorLevel ${ERROR_WRITEFAIL}
Quit
${EndIf}
${EndIf}
${Else}
; Sync variables with user instance
!insertmacro UAC_AsUser_Call Function ExchangeVars ${UAC_SYNCREGISTERS}
StrCpy $instType "S"
StrCpy $ctlDesktop $0
StrCpy $ctlStartup $1
StrCpy $ctlAllUsers $2
StrCpy $instArc $3
StrCpy $defLang $4
StrCpy $LANGUAGE $5
${EndIf}
FunctionEnd
Function ExchangeVars
StrCpy $0 $ctlDesktop
StrCpy $1 $ctlStartup
StrCpy $2 $ctlAllUsers
StrCpy $3 $instArc
StrCpy $4 $defLang
StrCpy $5 $LANGUAGE
HideWindow
FunctionEnd
Function PageWelcomeOnShow
; Skip to the directory page if we're the elevated process
${If} ${UAC_IsInnerInstance}
${If} ${UAC_IsAdmin}
SendMessage $HWNDPARENT "0x408" "2" ""
${Else}
MessageBox MB_OK|MB_ICONSTOP "$(ADMINERROR) (Inner)"
Quit
${EndIf}
${EndIf}
FunctionEnd
Function PageOptions
!insertmacro MUI_HEADER_TEXT "$(INSTALLOPTIONS)" "$(INSTALLOPTIONSDESC)"
nsDialogs::Create 1018
nsDialogs::SetRTL $(^RTL)
${NSD_CreateRadioButton} 0 0u 310u 12u "$(STANDARDINST)"
Pop $ctlStandard
${NSD_AddStyle} $ctlStandard ${WS_GROUP}
SendMessage $ctlStandard ${WM_SETFONT} $mui.Header.Text.Font 0
${NSD_OnClick} $ctlStandard setStandard
${NSD_CreateLabel} 12u 12u 285u 12u "$(STANDARDINSTDESC)"
${NSD_CreateRadioButton} 0 24u 310u 12u "$(PORTABLEINST)"
Pop $ctlPortable
${NSD_AddStyle} $ctlPortable ${WS_TABSTOP}
SendMessage $ctlPortable ${WM_SETFONT} $mui.Header.Text.Font 0
${NSD_OnClick} $ctlPortable setPortable
${NSD_CreateLabel} 12u 36u 285u 32u "$(PORTABLEINSTDESC)"
${NSD_CreateGroupBox} 0 72u 200u 54u "$(ADDITIONALOPTIONS)"
Push $ctlDesktop
${NSD_CreateCheckbox} 6u 84u 190u 12u "$(DESKTOPSHORTCUT)"
Pop $ctlDesktop
Pop $0
StrCmp $0 "1" 0 +2
${NSD_Check} $ctlDesktop
Push $ctlAllUsers
${NSD_CreateCheckbox} 6u 96u 190u 12u "$(ALLUSERSSHORTCUT)"
Pop $ctlAllUsers
Pop $0
StrCmp $0 "1" 0 +2
${NSD_Check} $ctlAllUsers
Push $ctlStartup
${NSD_CreateCheckbox} 6u 108u 190u 12u "$(AUTOSTARTUP)"
Pop $ctlStartup
Pop $0
StrCmp $0 "1" 0 +2
${NSD_Check} $ctlStartup
${NSD_CreateGroupBox} 205u 72u 94u 40u "$(RAINMETERVERSION)"
${NSD_CreateRadioButton} 211u 82u 80u 12u "$(32BIT)"
Pop $ctlBit32
${NSD_AddStyle} $ctlBit32 ${WS_GROUP}
${NSD_CreateRadioButton} 211u 94u 80u 12u "$(64BIT)"
Pop $ctlBit64
ReadRegStr $0 HKLM "Software\Rainmeter" ""
${If} $0 == ""
${NSD_Check} $ctlStartup
${NSD_Check} $ctlAllUsers
${Else}
SetShellVarContext all
Call GetEnvPaths
StrCpy $R1 $1
StrCpy $R2 $2
StrCpy $R3 $3
SetShellVarContext current
!insertmacro UAC_AsUser_Call Function GetEnvPaths ${UAC_SYNCREGISTERS}
${If} ${FileExists} "$R1\Rainmeter\Rainmeter.lnk"
${NSD_Check} $ctlAllUsers
${EndIf}
${If} ${FileExists} "$R2\Rainmeter.lnk"
${OrIf} ${FileExists} "$2\Rainmeter.lnk"
${NSD_Check} $ctlStartup
${EndIf}
${If} ${FileExists} "$R3\Rainmeter.lnk"
${OrIf} ${FileExists} "$3\Rainmeter.lnk"
${NSD_Check} $ctlDesktop
${EndIf}
${EndIf}
${If} $instType == "P"
${NSD_Check} $ctlPortable
Call SetPortable
${Else}
Call SetStandard
${NSD_Check} $ctlStandard
${EndIf}
nsDialogs::Show
FunctionEnd
Function SetStandard
EnableWindow $ctlDesktop 1
EnableWindow $ctlAllUsers 1
EnableWindow $ctlStartup 1
${If} ${RunningX64}
${If} ${FileExists} "$INSTDIR\Rainmeter.exe"
MoreInfo::GetProductVersion "$INSTDIR\Rainmeter.exe"
Pop $0
StrCpy $0 $0 2 -7
${If} $0 == "32"
${NSD_Check} $ctlBit32
${NSD_UnCheck} $ctlBit64
EnableWindow $ctlBit64 0
${Else}
${NSD_Check} $ctlBit64
${NSD_UnCheck} $ctlBit32
EnableWindow $ctlBit32 0
${EndIf}
${Else}
${NSD_Check} $ctlBit64
${EndIf}
${Else}
${NSD_Check} $ctlBit32
${NSD_UnCheck} $ctlBit64
EnableWindow $ctlBit64 0
${EndIf}
${IfNot} ${UAC_IsAdmin}
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${BCM_SETSHIELD} 0 1
${EndIf}
FunctionEnd
Function SetPortable
EnableWindow $ctlDesktop 0
EnableWindow $ctlAllUsers 0
EnableWindow $ctlStartup 0
EnableWindow $ctlBit32 1
${If} ${RunningX64}
EnableWindow $ctlBit64 1
${Endif}
${IfNot} ${UAC_IsAdmin}
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${BCM_SETSHIELD} 0 0
${EndIf}
FunctionEnd
Function PageOptionsOnLeave
GetDlgItem $0 $HWNDPARENT 1
EnableWindow $0 0
${NSD_GetState} $ctlDesktop $ctlDesktop
${NSD_GetState} $ctlStartup $ctlStartup
${NSD_GetState} $ctlAllUsers $ctlAllUsers
${NSD_GetState} $ctlStandard $0
${If} $0 == ${BST_CHECKED}
StrCpy $instType "S"
${Else}
StrCpy $instType "P"
${EndIf}
${NSD_GetState} $ctlBit32 $0
${If} $0 == ${BST_CHECKED}
StrCpy $instArc "x86"
${Else}
StrCpy $instArc "x64"
${EndIf}
${If} $instType == "S"
${IfNot} ${UAC_IsAdmin}
; UAC_IsAdmin seems to return incorrect result sometimes. Recheck with UserInfo::GetAccountType to be sure.
UserInfo::GetAccountType
Pop $0
${If} $0 != "Admin"
UAC_TryAgain:
!insertmacro UAC_RunElevated
${Switch} $0
${Case} 0
${IfThen} $1 = 1 ${|} Quit ${|}
${IfThen} $3 <> 0 ${|} ${Break} ${|}
${If} $1 = 3
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(ADMINERROR)" /SD IDNO IDOK UAC_TryAgain IDNO 0
${EndIf}
${Case} 1223
Quit
${Case} 1062
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(LOGONERROR)"
Quit
${Default}
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(UACERROR) ($0)"
Quit
${EndSwitch}
${EndIf}
${EndIf}
${EndIf}
FunctionEnd
Function PageDirectoryOnShow
${If} $instType == "P"
${GetRoot} "$WINDIR" $0
${NSD_SetText} $mui.DirectoryPage.Directory "$0\Rainmeter"
${Else}
${If} $INSTDIR == ""
; Fresh install
${If} $instArc == "x86"
${If} ${RunningX64}
${NSD_SetText} $mui.DirectoryPage.Directory "$PROGRAMFILES32\Rainmeter"
${Else}
${NSD_SetText} $mui.DirectoryPage.Directory "$PROGRAMFILES\Rainmeter"
${EndIf}
${Else}
${NSD_SetText} $mui.DirectoryPage.Directory "$PROGRAMFILES64\Rainmeter"
${EndIf}
${Else}
; Upgrade install
EnableWindow $mui.DirectoryPage.Directory 0
EnableWindow $mui.DirectoryPage.BrowseButton 0
; Set focus on the Install button
GetDlgItem $0 $HWNDPARENT 1
System::Call "user32::SetFocus(i$0)"
${EndIf}
${EndIf}
FunctionEnd
Function PageDirectoryOnLeave
${If} $instType == "P"
ClearErrors
CreateDirectory "$INSTDIR"
WriteINIStr "$INSTDIR\_rainmeter_writetest.tmp" "1" "1" "1"
${If} ${Errors}
MessageBox MB_OK|MB_ICONEXCLAMATION "$(WRITEERROR)"
Abort
${EndIf}
Delete "$INSTDIR\_rainmeter_writetest.tmp"
${EndIf}
FunctionEnd
!macro InstallFiles DIR
File "..\..\TestBench\${DIR}\Release\Rainmeter.exe"
File "..\..\TestBench\${DIR}\Release\Rainmeter.dll"
File "..\..\TestBench\${DIR}\Release\SkinInstaller.exe"
SetOutPath "$INSTDIR\Plugins"
File /x *Example*.dll "..\..\TestBench\${DIR}\Release\Plugins\*.dll"
!macroend
!macro RemoveShortcuts
; $1=$SMPROGRAMS, $2=$SMSTARTUP, $3=$DESKTOP
Delete "$1\Rainmeter\Rainmeter.lnk"
Delete "$1\Rainmeter\Rainmeter Help.lnk"
Delete "$1\Rainmeter\Rainmeter Help.URL"
Delete "$1\Rainmeter\Remove Rainmeter.lnk"
Delete "$1\Rainmeter\RainThemes.lnk"
Delete "$1\Rainmeter\RainThemes Help.lnk"
Delete "$1\Rainmeter\RainBrowser.lnk"
Delete "$1\Rainmeter\RainBackup.lnk"
Delete "$1\Rainmeter\Rainstaller.lnk"
Delete "$1\Rainmeter\Skin Installer.lnk"
Delete "$1\Rainmeter\Rainstaller Help.lnk"
RMDir "$1\Rainmeter"
Delete "$2\Rainmeter.lnk"
Delete "$3\Rainmeter.lnk"
!macroend
Section
SetOutPath "$PLUGINSDIR"
SetShellVarContext current
${If} $instType == "S"
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\VisualStudio\10.0\VC\VCRedist\$instArc" "Bld"
${VersionCompare} "$0" "40219" $1
ReadRegDWORD $2 HKLM "SOFTWARE\Microsoft\VisualStudio\10.0\VC\VCRedist\$instArc" "Installed"
; Download and install VC++ redist if required
${If} $1 == "2"
${OrIf} $2 != "1"
${If} ${Silent}
SetErrorLevel ${ERROR_NOVCREDIST}
Quit
${EndIf}
${If} $instArc == "x86"
NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/C/6/D/C6D0FD4E-9E53-4897-9B91-836EBA2AACD3/vcredist_x86.exe" "$PLUGINSDIR\vcredist.exe"
Pop $0
${Else}
NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/A/8/0/A80747C3-41BD-45DF-B505-E9710D2744E0/vcredist_x64.exe" "$PLUGINSDIR\vcredist.exe"
Pop $0
${EndIf}
${If} $0 != "cancel"
${AndIf} $0 != "success"
; download from MS failed, try from rainmter.net
Delete "$PLUGINSDIR\vcredist.exe"
${If} $instArc == "x86"
NSISdl::download /TIMEOUT=30000 "http://rainmeter.net/redist/vc10SP1redist_x86.exe" "$PLUGINSDIR\vcredist.exe"
Pop $0
${Else}
NSISdl::download /TIMEOUT=30000 "http://rainmeter.net/redist/vc10SP1redist_x64.exe" "$PLUGINSDIR\vcredist.exe"
Pop $0
${EndIf}
${EndIf}
${If} $0 == "success"
ExecWait '"$PLUGINSDIR\vcredist.exe" /q /norestart' $0
Delete "$PLUGINSDIR\vcredist.exe"
${If} $0 == "3010"
SetRebootFlag true
${ElseIf} $0 != "0"
MessageBox MB_OK|MB_ICONSTOP "$(VCINSTERROR)"
Quit
${EndIf}
${ElseIf} $0 == "cancel"
Quit
${Else}
MessageBox MB_OK|MB_ICONSTOP "$(VCINSTERROR)"
Quit
${EndIf}
${EndIf}
; Download and install .NET if required
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install"
${If} $0 != "1"
${If} $instArc == "x86"
NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe" "$PLUGINSDIR\dotnetfx.exe"
${Else}
NSISdl::download /TIMEOUT=30000 "http://download.microsoft.com/download/a/3/f/a3f1bf98-18f3-4036-9b68-8e6de530ce0a/NetFx64.exe" "$PLUGINSDIR\dotnetfx.exe"
${EndIf}
Pop $0
${If} $0 != "cancel"
${AndIf} $0 != "success"
Delete "$PLUGINSDIR\dotnetfx.exe"
${If} $instArc == "x86"
NSISdl::download /TIMEOUT=30000 "http://rainmeter.net/redist/dotnetfx.exe" "$PLUGINSDIR\dotnetfx.exe"
${Else}
NSISdl::download /TIMEOUT=30000 "http://rainmeter.net/redist/NetFx64.exe" "$PLUGINSDIR\dotnetfx.exe"
${EndIf}
Pop $0
${EndIf}
${If} $0 == "success"
ExecWait '"$PLUGINSDIR\dotnetfx.exe" /q:a /c:"install /q"' $0
Delete "$PLUGINSDIR\dotnetfx.exe"
${If} $0 == "3010"
SetRebootFlag true
${ElseIf} $0 != "0"
MessageBox MB_OK|MB_ICONSTOP "$(DOTNETINSTERROR)"
Quit
${EndIf}
${ElseIf} $0 == "cancel"
Quit
${Else}
MessageBox MB_OK|MB_ICONSTOP "$(DOTNETINSTERROR)"
Quit
${EndIf}
${EndIf}
${EndIf}
SetOutPath "$INSTDIR"
FindWindow $0 "RainmeterTrayClass"
${If} $0 != "0"
Exec '"$INSTDIR\Rainmeter.exe" !Quit'
; Wait up to for up to 5 seconds for Rainmeter to close
StrCpy $1 "0"
${DoWhile} ${ProcessExists} "Rainmeter.exe"
IntOp $1 $1 + 1
${If} $1 >= "10"
${If} ${Silent}
SetErrorLevel ${ERROR_CLOSEFAIL}
Quit
${Else}
MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2
Quit
${EndIf}
${EndIf}
Sleep 500
SendMessage $0 ${WM_CLOSE} 0 0
${Loop}
${EndIf}
; Check if Rainmeter.ini is located in the installation folder and
; if the installation folder is in Program Files
${IfNot} ${Silent}
${AndIf} ${FileExists} "$INSTDIR\Rainmeter.ini"
${If} $instType == "S"
!ifdef X64
StrCmp $INSTDIR "$PROGRAMFILES64\Rainmeter" 0 RainmeterIniDoesntExistLabel
!else
StrCmp $INSTDIR "$PROGRAMFILES\Rainmeter" 0 RainmeterIniDoesntExistLabel
!endif
MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(SETTINGSFILEERROR)" IDNO RainmeterIniDoesntExistLabel
CreateDirectory $APPDATA\Rainmeter
Rename "$INSTDIR\Rainmeter.ini" "$APPDATA\Rainmeter\Rainmeter.ini"
${If} ${Errors}
MessageBox MB_OK|MB_ICONSTOP "$(SETTINGSMOVEERROR)"
${EndIf}
${Else}
ReadINIStr $0 "$INSTDIR\Rainmeter.ini" "Rainmeter" "SkinPath"
${If} $0 == "$INSTDIR\Skins\"
DeleteINIStr "$INSTDIR\Rainmeter.ini" "Rainmeter" "SkinPath"
${EndIf}
${EndIf}
${EndIf}
RainmeterIniDoesntExistLabel:
SetOutPath "$INSTDIR"
Delete "$INSTDIR\Rainmeter.exe.config"
Delete "$INSTDIR\Rainmeter.chm"
Delete "$INSTDIR\Default.ini"
${If} $instArc == "x86"
!insertmacro InstallFiles "x32"
${Else}
!insertmacro InstallFiles "x64"
${EndIf}
RMDir /r "$INSTDIR\Languages"
SetOutPath "$INSTDIR\Languages"
File "..\..\TestBench\x32\Release\Languages\*.*"
RMDir /r "$INSTDIR\Addons\Rainstaller"
SetOutPath "$INSTDIR\Skins"
RMDir /r "$INSTDIR\Skins\illustro"
Delete "$INSTDIR\Skins\*.txt"
File /r /x .svn ".\Skins\*.*"
SetOutPath "$INSTDIR\Themes"
File /r /x .svn ".\Themes\*.*"
SetOutPath "$INSTDIR"
${If} $instType == "S"
ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" ""
WriteRegStr HKLM "SOFTWARE\Rainmeter" "" "$INSTDIR"
WriteRegStr HKLM "SOFTWARE\Rainmeter" "Language" "$LANGUAGE"
${If} $defLang == "1"
DeleteRegValue HKLM "SOFTWARE\Rainmeter" "NonDefault"
${Else}
WriteRegDWORD HKLM "SOFTWARE\Rainmeter" "NonDefault" 1
${EndIf}
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayName" "Rainmeter"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayIcon" "$INSTDIR\Rainmeter.exe,0"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "URLInfoAbout" "http://rainmeter.net"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "UninstallString" "$INSTDIR\uninst.exe"
!ifdef BETA
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayVersion" "${VER} beta r${REV}"
!else
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter" "DisplayVersion" "${VER} r${REV}"
!endif
WriteRegStr HKCR ".rmskin" "" "Rainmeter skin"
WriteRegStr HKCR "Rainmeter skin" "" "Rainmeter skin file"
WriteRegStr HKCR "Rainmeter skin\shell" "" "open"
WriteRegStr HKCR "Rainmeter skin\DefaultIcon" "" "$INSTDIR\SkinInstaller.exe,0"
WriteRegStr HKCR "Rainmeter skin\shell\open\command" "" '"$INSTDIR\SkinInstaller.exe" %1'
WriteRegStr HKCR "Rainmeter skin\shell\edit" "" "Install Rainmeter skin"
WriteRegStr HKCR "Rainmeter skin\shell\edit\command" "" '"$INSTDIR\SkinInstaller.exe" %1'
; Refresh shell icons if new install
${If} $0 == ""
System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
${EndIf}
; Remove all shortcuts
${If} $ctlAllUsers == "1"
SetShellVarContext current
Call GetEnvPaths
!insertmacro RemoveShortcuts
!insertmacro UAC_AsUser_Call Function GetEnvPaths ${UAC_SYNCREGISTERS}
!insertmacro RemoveShortcuts
SetShellVarContext all
Call GetEnvPaths
!insertmacro RemoveShortcuts
${Else}
SetShellVarContext all
Call GetEnvPaths
!insertmacro RemoveShortcuts
SetShellVarContext current
Call GetEnvPaths
!insertmacro RemoveShortcuts
!insertmacro UAC_AsUser_Call Function GetEnvPaths ${UAC_SYNCREGISTERS}
!insertmacro RemoveShortcuts
${EndIf}
; Create shortcuts ($1=$SMPROGRAMS, $2=$SMSTARTUP, $3=$DESKTOP)
CreateDirectory "$1\Rainmeter"
CreateShortCut "$1\Rainmeter\Rainmeter.lnk" "$INSTDIR\Rainmeter.exe" "" "$INSTDIR\Rainmeter.exe" 0
SetOutPath "$INSTDIR"
${If} $ctlStartup == "1"
CreateShortCut "$2\Rainmeter.lnk" "$INSTDIR\Rainmeter.exe" "" "$INSTDIR\Rainmeter.exe" 0
${EndIf}
${If} $ctlDesktop == "1"
CreateShortCut "$3\Rainmeter.lnk" "$INSTDIR\Rainmeter.exe" "" "$INSTDIR\Rainmeter.exe" 0
${EndIf}
WriteUninstaller "$INSTDIR\uninst.exe"
${Else}
${IfNot} ${FileExists} "Rainmeter.ini"
CopyFiles /SILENT "$INSTDIR\Themes\illustro default\Rainmeter.thm" "$INSTDIR\Rainmeter.ini"
${EndIf}
WriteINIStr "$INSTDIR\Rainmeter.ini" "Rainmeter" "Language" "$LANGUAGE"
${EndIf}
SectionEnd
Function GetEnvPaths
StrCpy $1 $SMPROGRAMS
StrCpy $2 $SMSTARTUP
StrCpy $3 $DESKTOP
FunctionEnd
Function FinishRun
!insertmacro UAC_AsUser_ExecShell "" "$INSTDIR\Rainmeter.exe" "" "" ""
FunctionEnd
; Uninstall
; --------------------------------------
Function un.onInit
UAC_TryAgain:
; Request administrative rights
!insertmacro UAC_RunElevated
${Switch} $0
${Case} 0
${IfThen} $1 = 1 ${|} Quit ${|}
${IfThen} $3 <> 0 ${|} ${Break} ${|}
${If} $1 = 3
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(ADMINERROR)" /SD IDNO IDOK UAC_TryAgain IDNO 0
${EndIf}
${Case} 1223
Quit
${Case} 1062
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(LOGONERROR)"
Quit
${Default}
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND "$(UACERROR) ($0)"
Quit
${EndSwitch}
ReadRegStr $0 HKLM "SOFTWARE\Rainmeter" "Language"
${If} $0 != ""
StrCpy $LANGUAGE $0
${EndIf}
FunctionEnd
Function un.PageOptions
!insertmacro MUI_HEADER_TEXT "$(UNSTALLOPTIONS)" "$(UNSTALLOPTIONSDESC)"
nsDialogs::Create 1018
nsDialogs::SetRTL $(^RTL)
${NSD_CreateCheckbox} 0 0u 95% 12u "$(UNSTALLRAINMETER)"
Pop $0
EnableWindow $0 0
${NSD_Check} $0
${NSD_CreateCheckbox} 0 15u 70% 12u "$(UNSTALLSETTINGS)"
Pop $ctlDelete
${NSD_CreateLabel} 16 26u 95% 12u "$(UNSTALLSETTINGSDESC)"
nsDialogs::Show
FunctionEnd
Function un.GetOptions
${NSD_GetState} $ctlDelete $ctlDelete
FunctionEnd
Section Uninstall
FindWindow $0 "RainmeterTrayClass"
${If} $0 != "0"
Exec '"$INSTDIR\Rainmeter.exe" !RainmeterQuit'
; Wait up to for up to 5 seconds for Rainmeter to close
StrCpy $1 "0"
${DoWhile} ${ProcessExists} "Rainmeter.exe"
IntOp $1 $1 + 1
${If} $1 >= "10"
MessageBox MB_RETRYCANCEL|MB_ICONSTOP "$(RAINMETERCLOSEERROR)" IDRETRY +2
Quit
${EndIf}
Sleep 500
${Loop}
${EndIf}
RMDir /r "$TEMP\Rainmeter-Cache"
RMDir /r "$INSTDIR\Skins\Gnometer"
RMDir /r "$INSTDIR\Skins\Tranquil"
RMDir /r "$INSTDIR\Skins\Enigma"
RMDir /r "$INSTDIR\Skins\Arcs"
RMDir /r "$INSTDIR\Skins\illustro"
Delete "$INSTDIR\Skins\*.txt"
RMDir "$INSTDIR\Skins"
RMDir /r "$INSTDIR\Addons\RainThemes"
RMDir /r "$INSTDIR\Addons\RainBrowser"
RMDir /r "$INSTDIR\Addons\RainBackup"
RMDir /r "$INSTDIR\Addons\Rainstaller"
RMDir "$INSTDIR\Addons"
Delete "$INSTDIR\Plugins\*.*"
Delete "$INSTDIR\Plugins\Dependencies\*.*"
RMDir "$INSTDIR\Plugins"
RMDir /r "$INSTDIR\Languages"
RMDir /r "$INSTDIR\Themes"
Delete "$INSTDIR\*.*"
${If} $ctlDelete == "1"
RMDir /r "$INSTDIR\Skins"
RMDir /r "$INSTDIR\Addons"
RMDir /r "$INSTDIR\Plugins"
RMDir /r "$INSTDIR\Fonts"
${EndIf}
RMDir "$INSTDIR"
SetShellVarContext all
RMDir /r "$APPDATA\Rainstaller"
SetShellVarContext current
Call un.GetEnvPaths
!insertmacro RemoveShortcuts
${If} $ctlDelete == "1"
RMDir /r "$APPDATA\Rainmeter"
RMDir /r "$DOCUMENTS\Rainmeter\Skins"
RMDir "$DOCUMENTS\Rainmeter"
RMDir /r "$1\Rainmeter"
${EndIf}
!insertmacro UAC_AsUser_Call Function un.GetEnvPaths ${UAC_SYNCREGISTERS}
!insertmacro RemoveShortcuts
${If} $ctlDelete == "1"
RMDir /r "$APPDATA\Rainmeter"
RMDir /r "$DOCUMENTS\Rainmeter\Skins"
RMDir "$DOCUMENTS\Rainmeter"
${EndIf}
SetShellVarContext all
Call un.GetEnvPaths
!insertmacro RemoveShortcuts
DeleteRegKey HKLM "SOFTWARE\Rainmeter"
DeleteRegKey HKCR ".rmskin"
DeleteRegKey HKCR "Rainmeter skin"
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Rainmeter"
System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
SectionEnd
Function un.GetEnvPaths
StrCpy $1 $SMPROGRAMS
StrCpy $2 $SMSTARTUP
StrCpy $3 $DESKTOP
FunctionEnd

Binary file not shown.

View File

@ -0,0 +1,835 @@
/*
_____________________________________________________________________________
Process Functions Header v2.2
_____________________________________________________________________________
2008-2010 Erik Pilsits aka wraithdu
License: zlib/libpng
See documentation for more information about the following functions.
Usage in script:
1. !include "ProcFunc.nsh"
2. [Section|Function]
${ProcFunction} "Param1" "Param2" "..." $var
[SectionEnd|FunctionEnd]
ProcFunction=[GetProcessPID|GetProcessPath|GetProcessParent|GetProcessName|
EnumProcessPaths|ProcessWait|ProcessWait2|ProcessWaitClose|
CloseProcess|TerminateProcess|Execute]
There is also a LogicLib extension:
${If} ${ProcessExists} file.exe
...
${EndIf}
_____________________________________________________________________________
Thanks to:
_____________________________________________________________________________
Some functions based on work by Donald Miller and Phoenix1701@gmail.com
_____________________________________________________________________________
Individual documentation:
_____________________________________________________________________________
${ProcessExists} "[process]"
"[process]" ; Name or PID
Use with a LogicLib conditional command like If or Unless.
Evaluates to true if the process exists or false if it does not or
the CreateToolhelp32Snapshot fails.
${GetProcessPID} "[process]" $var
"[process]" ; Name or PID
$var(output) ; -2 - CreateToolhelp32Snapshot failed
; 0 - process does not exist
; >0 - PID
${GetProcessPath} "[process]" $var
"[process]" ; Name or PID
$var(output) ; -2 - CreateToolhelp32Snapshot failed
; -1 - OpenProcess failed
; 0 - process does not exist
; Or path to process
${GetProcessParent} "[process]" $var
"[process]" ; Name or PID
$var(output) ; -2 - CreateToolhelp32Snapshot failed
; 0 - process does not exist
; Or PPID
${GetProcessName} "[PID]" $var
"[PID]" ; PID
$var(output) ; -2 - CreateToolhelp32Snapshot failed
; 0 - process does not exist
; Or process name
${EnumProcessPaths} "Function" $var
"Function" ; Callback function
$var(output) ; -2 - EnumProcesses failed
; 1 - success
Function "Function"
Pop $var1 ; matching path string
Pop $var2 ; matching process PID
...user commands
Push [1/0] ; must return 1 on the stack to continue
; must return some value or corrupt the stack
; DO NOT save data in $0-$9
FunctionEnd
${ProcessWait} "[process]" "[timeout]" $var
"[process]" ; Name
"[timeout]" ; -1 - do not timeout
; >0 - timeout in milliseconds
$var(output) ; -2 - CreateToolhelp32Snapshot failed
; -1 - operation timed out
; Or PID
${ProcessWait2} "[process]" "[timeout]" $var
"[process]" ; Name
"[timeout]" ; -1 - do not timeout
; >0 - timeout in milliseconds
$var(output) ; -1 - operation timed out
; Or PID
${ProcessWaitClose} "[process]" "[timeout]" $var
"[process]" ; Name
"[timeout]" ; -1 - do not timeout
; >0 - timeout in milliseconds
$var(output) ; -1 - operation timed out
; 0 - process does not exist
; Or PID of ended process
${CloseProcess} "[process]" $var
"[process]" ; Name or PID
$var(output) ; 0 - process does not exist
; Or PID of ended process
${TerminateProcess} "[process]" $var
"[process]" ; Name or PID
$var(output) ; -1 - operation failed
; 0 - process does not exist
; Or PID of ended process
${Execute} "[command]" "[working_dir]" $var
"[command]" ; '"X:\path\to\prog.exe" arg1 arg2 "arg3 with space"'
"[working_dir]" ; Working directory ("X:\path\to\dir") or nothing ("")
$var(output) ; 0 - failed to create process
; Or PID
*/
;_____________________________________________________________________________
;
; Macros
;_____________________________________________________________________________
;
; Change log window verbosity (default: 3=no script)
;
; Example:
; !include "ProcFunc.nsh"
; ${PROCFUNC_VERBOSE} 4 # all verbosity
; ${PROCFUNC_VERBOSE} 3 # no script
!ifndef PROCFUNC_INCLUDED
!define PROCFUNC_INCLUDED
!include Util.nsh
!include LogicLib.nsh
!verbose push
!verbose 3
!ifndef _PROCFUNC_VERBOSE
!define _PROCFUNC_VERBOSE 3
!endif
!verbose ${_PROCFUNC_VERBOSE}
!define PROCFUNC_VERBOSE `!insertmacro PROCFUNC_VERBOSE`
!verbose pop
!macro PROCFUNC_VERBOSE _VERBOSE
!verbose push
!verbose 3
!undef _PROCFUNC_VERBOSE
!define _PROCFUNC_VERBOSE ${_VERBOSE}
!verbose pop
!macroend
!define PROCESS_QUERY_INFORMATION 0x0400
!define PROCESS_TERMINATE 0x0001
!define PROCESS_VM_READ 0x0010
!define SYNCHRONIZE 0x00100000
!define WAIT_TIMEOUT 0x00000102
!ifdef NSIS_UNICODE
!define _PROCFUNC_WSTRING "&w260"
!else
!define _PROCFUNC_WSTRING "&w520"
!endif
!macro ProcessExists
!error "ProcessExists has been renamed to GetProcessPID"
!macroend
!macro _ProcessExists _a _b _t _f
!insertmacro _LOGICLIB_TEMP
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${_b}`
${CallArtificialFunction} LLProcessExists_
IntCmp $_LOGICLIB_TEMP 0 `${_f}`
Goto `${_t}`
!verbose pop
!macroend
!define ProcessExists `"" ProcessExists`
!macro GetProcessPID
!macroend
!define GetProcessPID "!insertmacro GetProcessPIDCall"
!macro GetProcessPIDCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push 0
Push `${process}`
!ifdef CallArtificialFunction_TYPE ; macro nesting disallowed, breaks otherwise if used from WaitClose
${CallArtificialFunction2} ProcFuncs_
!else
${CallArtificialFunction} ProcFuncs_
!endif
Pop ${outVar}
!verbose pop
!macroend
!macro GetProcessPath
!macroend
!define GetProcessPath "!insertmacro GetProcessPathCall"
!macro GetProcessPathCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push 1
Push `${process}`
${CallArtificialFunction} ProcFuncs_
Pop ${outVar}
!verbose pop
!macroend
!macro GetProcessParent
!macroend
!define GetProcessParent "!insertmacro GetProcessParentCall"
!macro GetProcessParentCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push 2
Push `${process}`
${CallArtificialFunction} ProcFuncs_
Pop ${outVar}
!verbose pop
!macroend
!macro GetProcessName
!macroend
!define GetProcessName "!insertmacro GetProcessNameCall"
!macro GetProcessNameCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push 6
Push `${process}`
${CallArtificialFunction} ProcFuncs_
Pop ${outVar}
!verbose pop
!macroend
!macro EnumProcessPaths
!macroend
!define EnumProcessPaths "!insertmacro EnumProcessPathsCall"
!macro EnumProcessPathsCall user_func outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push $0
GetFunctionAddress $0 `${user_func}`
Push `$0`
${CallArtificialFunction} EnumProcessPaths_
Exch
Pop $0
Pop ${outVar}
!verbose pop
!macroend
!macro ProcessWait
!macroend
!define ProcessWait "!insertmacro ProcessWaitCall"
!macro ProcessWaitCall process timeout outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${timeout}`
Push `${process}`
${CallArtificialFunction} ProcessWait_
Pop ${outVar}
!verbose pop
!macroend
!macro ProcessWait2
!macroend
!define ProcessWait2 "!insertmacro ProcessWait2Call"
!macro ProcessWait2Call process timeout outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${timeout}`
Push `${process}`
${CallArtificialFunction} ProcessWait2_
Pop ${outVar}
!verbose pop
!macroend
!macro ProcessWaitClose
!macroend
!define ProcessWaitClose "!insertmacro ProcessWaitCloseCall"
!macro ProcessWaitCloseCall process timeout outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${timeout}`
Push `${process}`
${CallArtificialFunction} ProcessWaitClose_
Pop ${outVar}
!verbose pop
!macroend
!macro CloseProcess
!macroend
!define CloseProcess "!insertmacro CloseProcessCall"
!macro CloseProcessCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${process}`
${CallArtificialFunction} CloseProcess_
Pop ${outVar}
!verbose pop
!macroend
!macro TerminateProcess
!macroend
!define TerminateProcess "!insertmacro TerminateProcessCall"
!macro TerminateProcessCall process outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${process}`
${CallArtificialFunction} TerminateProcess_
Pop ${outVar}
!verbose pop
!macroend
!macro Execute
!macroend
!define Execute "!insertmacro ExecuteCall"
!macro ExecuteCall cmdline wrkdir outVar
!verbose push
!verbose ${_PROCFUNC_VERBOSE}
Push `${wrkdir}`
Push `${cmdline}`
${CallArtificialFunction} Execute_
Pop ${outVar}
!verbose pop
!macroend
!macro ProcFuncs_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process / PID
Pop $1 ; mode
Push 0 ; set return value if not found
; set mode of operation in $1
${Select} $1 ; mode 0 = GetProcessPID, mode 1 = GetProcessPath, mode 2 = GetProcessParent
${Case} 0
StrCpy $2 $0 4 -4
${If} $2 == ".exe"
; exists from process name
StrCpy $1 0
${Else}
; exists from pid
StrCpy $1 1
${EndIf}
${Case} 1
StrCpy $2 $0 4 -4
${If} $2 == ".exe"
; get path from process name
StrCpy $1 2
${Else}
; get path from pid
StrCpy $1 3
${EndIf}
${Case} 2
StrCpy $2 $0 4 -4
${If} $2 == ".exe"
; get parent from process name
StrCpy $1 4
${Else}
; get parent from pid
StrCpy $1 5
${EndIf}
${EndSelect}
System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure
; take system process snapshot in $3
System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3'
${Unless} $3 = -1
System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4'
${Unless} $4 = 0
${Do}
${Select} $1
${Case3} 0 2 4
; get process name in $5
System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)'
${Case4} 1 3 5 6
; get process PID in $5
System::Call '*$2(i,i,i .r5)'
${EndSelect}
; is this process the one we are looking for?
${If} $5 == $0 ; string test works ok for numeric PIDs as well
${Select} $1 ; mode 0/1 = GetProcessPID, mode 2/3 = GetProcessPath, mode 4/5 = GetProcessParent, mode 6 = GetProcessName
${Case2} 0 1
; return pid
Pop $5 ; old return value
System::Call '*$2(i,i,i .s)'; process pid to stack
${Case2} 2 3
; return full path
Pop $5
; open process
System::Call '*$2(i,i,i .s)'; process pid to stack
System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i s)i .r5' ; process handle to $5
${Unless} $5 = 0
; full path to stack
System::Call 'psapi::GetModuleFileNameExW(i r5, i 0, w .s, i ${NSIS_MAX_STRLEN})'
System::Call 'kernel32::CloseHandle(i r5)'
${Else}
Push -1 ; OpenProcess failure return value
${EndUnless}
${Case2} 4 5
; return parent PID
Pop $5
System::Call '*$2(i,i,i,i,i,i,i .s)'; parent pid to stack
${Case} 6
; return base name
Pop $5
System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .s)'
${EndSelect}
${Break}
${EndIf}
System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4'
${LoopUntil} $4 = 0
System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot
${EndUnless}
${Else}
Pop $5
Push -2 ; function failure return value
${EndUnless}
System::Free $2 ; free buffer
System::Store "l" ; restore registers
!macroend
!macro EnumProcessPaths_
System::Store "s" ; store registers in System's private stack
Pop $0 ; user_func
StrCpy $1 1 ; OK to loop
System::Alloc 1024
Pop $2 ; process list buffer
; get an array of all process ids
System::Call 'psapi::EnumProcesses(i r2, i 1024, *i .r3)i .r4' ; $3 = sizeof buffer
${Unless} $4 = 0
IntOp $3 $3 / 4 ; Divide by sizeof(DWORD) to get $3 process count
IntOp $3 $3 - 1 ; decrement for 0 base loop
${For} $4 0 $3
${IfThen} $1 != 1 ${|} ${Break} ${|}
; get a PID from the array
IntOp $5 $4 * 4 ; calculate offset
IntOp $5 $5 + $2 ; add offset to original buffer address
System::Call '*$5(i .r5)' ; get next PID = $5
${Unless} $5 = 0
System::Call 'kernel32::OpenProcess(i ${PROCESS_QUERY_INFORMATION}|${PROCESS_VM_READ}, i 0, i r5)i .r6'
${Unless} $6 = 0 ; $6 is hProcess
; get full path
System::Call 'psapi::GetModuleFileNameExW(i r6, i 0, w .r7, i ${NSIS_MAX_STRLEN})i .r8' ; $7 = path
${Unless} $8 = 0 ; no path
System::Store "s" ; store registers in System's private stack
Push $5 ; PID to stack
Push $7 ; path to stack
Call $0 ; user func must return 1 on the stack to continue looping
System::Store "l" ; restore registers
Pop $1 ; continue?
${EndUnless}
System::Call 'kernel32::CloseHandle(i r6)'
${EndUnless}
${EndUnless}
${Next}
Push 1 ; return value
${Else}
Push -2 ; function failure return value
${EndUnless}
System::Free $2 ; free buffer
System::Store "l" ; restore registers
!macroend
!macro ProcessWait_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process
Pop $1 ; timeout
StrCpy $6 1 ; initialize loop
StrCpy $7 0 ; initialize timeout counter
System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure
${DoWhile} $6 = 1 ; processwait loop
; take system process snapshot in $3
System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3'
${Unless} $3 = -1
System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4'
${Unless} $4 = 0
${Do}
; get process name in $5
System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)'
${If} $5 == $0
; exists, return pid
System::Call '*$2(i,i,i .s)'; process pid to stack ; process pid
StrCpy $6 0 ; end loop
${Break}
${EndIf}
System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4'
${LoopUntil} $4 = 0
System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot
${EndUnless}
${Else}
Push -2
${Break}
${EndUnless}
; timeout loop
${If} $6 = 1
${If} $1 >= 0
IntOp $7 $7 + 500 ; increment timeout counter
${AndIf} $7 >= $1 ; timed out, break loop
Push -1 ; timeout return value
${Break} ; end loop if timeout
${EndIf}
Sleep 500 ; pause before looping
${EndIf}
${Loop} ; processwaitloop
System::Free $2 ; free buffer
System::Store "l" ; restore registers
!macroend
!macro ProcessWait2_
System::Store "s" ; store registers in System's private stack
System::Store "P0" ; FindProcDLL return value
Pop $0 ; process
Pop $1 ; timeout
StrCpy $2 0 ; initialize timeout counter
${Do}
FindProcDLL::FindProc $0
${IfThen} $R0 = 1 ${|} ${Break} ${|}
${If} $1 >= 0
IntOp $2 $2 + 250
${AndIf} $2 >= $1
Push -1 ; timeout return value
${Break}
${EndIf}
Sleep 250
${Loop}
${If} $R0 = 1 ; success, get pid
${GetProcessPID} $0 $0
Push $0 ; return pid
${EndIf}
System::Store "R0" ; restore registers
System::Store "l"
!macroend
!macro ProcessWaitClose_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process / PID
Pop $1 ; timeout
; passed process name or pid
StrCpy $2 $0 4 -4
${If} $2 == ".exe"
${GetProcessPID} $0 $0
${EndIf}
; else passed pid directly
${Unless} $0 = 0
System::Call 'kernel32::OpenProcess(i ${SYNCHRONIZE}, i 0, i r0)i .r2'
${Unless} $2 = 0 ; $2 is hProcess
System::Call 'kernel32::WaitForSingleObject(i r2, i $1)i .r1'
${If} $1 = ${WAIT_TIMEOUT}
Push -1 ; timed out
${Else}
Push $0 ; return pid of ended process
${EndIf}
System::Call 'kernel32::CloseHandle(i r2)'
${Else}
Push 0 ; failure return value
${EndUnless}
${Else}
Push 0 ; failure return value
${EndUnless}
System::Store "l" ; restore registers
!macroend
!macro CloseProcess_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process / PID
; passed process name or pid
StrCpy $1 $0 4 -4
${If} $1 == ".exe"
${GetProcessPID} $0 $0
${EndIf}
; else passed pid directly
${Unless} $0 = 0 ; $0 = target pid
Push $0 ; return pid of process
; use EnumWindows and a callback
System::Get '(i .r1, i)i sr4' ; $1 = hwnd, $4 = callback#, s (stack) = source for return value
Pop $3 ; $3 = callback address
System::Call 'user32::EnumWindows(k r3, i)i' ; enumerate top-level windows
${DoWhile} $4 == "callback1"
System::Call 'user32::GetWindowThreadProcessId(i r1, *i .r2)i' ; $2 = pid that created the window
${If} $2 = $0 ; match to target pid
SendMessage $1 16 0 0 /TIMEOUT=1 ; send WM_CLOSE to all top-level windows owned by process, timeout immediately
${EndIf}
Push 1 ; callback return value; keep enumerating windows (returning 0 stops)
StrCpy $4 "" ; clear callback#
System::Call '$3' ; return from callback
${Loop}
System::Free $3 ; free callback
${Else}
Push 0 ; failure return value
${EndUnless}
System::Store "l" ; restore registers
!macroend
!macro TerminateProcess_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process / PID
; passed process name or pid
StrCpy $1 $0 4 -4
${If} $1 == ".exe"
${GetProcessPID} $0 $0
${EndIf}
; else passed pid directly
${Unless} $0 = 0
System::Call 'kernel32::OpenProcess(i ${PROCESS_TERMINATE}, i 0, i r0)i .r1'
${Unless} $1 = 0 ; $1 is hProcess
System::Call 'kernel32::TerminateProcess(i r1, i 0)i .r1'
${If} $1 = 0 ; fail
Push -1
${Else}
Push $0 ; return pid of ended process
${EndIf}
System::Call 'kernel32::CloseHandle(i r1)'
${Else}
Push 0 ; failure return value
${EndUnless}
${Else}
Push 0 ; failure return value
${EndUnless}
System::Store "l" ; restore registers
!macroend
!macro Execute_
System::Store "s" ; store registers in System's private stack
Pop $0 ; cmdline
Pop $1 ; wrkdir
System::Alloc 68 ; 4*16 + 2*2 / STARTUPINFO structure = $2
Pop $2
System::Call '*$2(i 68)' ; set cb = sizeof(STARTUPINFO)
System::Call '*(i,i,i,i)i .r3' ; PROCESS_INFORMATION structure = $3
${If} $1 == ""
StrCpy $1 "i"
${Else}
StrCpy $1 'w "$1"'
${EndIf}
System::Call `kernel32::CreateProcessW(i, w '$0', i, i, i 0, i 0, i, $1, i r2, i r3)i .r4` ; return 0 if fail
${Unless} $4 = 0 ; failed to create process
System::Call '*$3(i .r4, i .r5, i .r6)' ; read handles and PID
System::Call 'kernel32::CloseHandle(i $4)' ; close hProcess
System::Call 'kernel32::CloseHandle(i $5)' ; close hThread
Push $6 ; return PID
${Else}
Push 0 ; return val if failed
${EndUnless}
System::Free $2 ; free STARTUPINFO struct
System::Free $3 ; free PROCESS_INFORMATION struct
System::Store "l" ; restore registers
!macroend
!macro LLProcessExists_
System::Store "s" ; store registers in System's private stack
Pop $0 ; process name
StrCpy $_LOGICLIB_TEMP 0
System::Call '*(&l4,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING})i .r2' ; $2 = PROCESSENTRY32W structure
; take system process snapshot in $3
System::Call 'kernel32::CreateToolhelp32Snapshot(i 2, i 0)i .r3'
IntCmp $3 -1 done
System::Call 'kernel32::Process32FirstW(i r3, i r2)i .r4'
IntCmp $4 0 endloop
loop:
System::Call '*$2(i,i,i,i,i,i,i,i,i,${_PROCFUNC_WSTRING} .r5)'
StrCmp $5 $0 0 next_process
StrCpy $_LOGICLIB_TEMP 1
Goto endloop
next_process:
System::Call 'kernel32::Process32NextW(i r3, i r2)i .r4'
IntCmp $4 0 endloop
Goto loop
endloop:
System::Call 'kernel32::CloseHandle(i r3)' ; close snapshot
done:
System::Free $2 ; free buffer
System::Store "l" ; restore registers
!macroend
!endif ; PROCFUNC_INCLUDED
/****************************************************************************
Functions
=========
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO,
*LPSTARTUPINFO;
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION,
*LPPROCESS_INFORMATION;
BOOL WINAPI EnumProcesses(
__out DWORD* pProcessIds,
__in DWORD cb,
__out DWORD* pBytesReturned
);
DWORD WINAPI GetModuleBaseName(
__in HANDLE hProcess,
__in_opt HMODULE hModule,
__out LPTSTR lpBaseName,
__in DWORD nSize
);
DWORD WINAPI GetModuleFileNameEx(
__in HANDLE hProcess,
__in_opt HMODULE hModule,
__out LPTSTR lpFilename,
__in DWORD nSize
);
BOOL WINAPI CloseHandle(
__in HANDLE hObject
);
DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
BOOL WINAPI TerminateProcess(
__in HANDLE hProcess,
__in UINT uExitCode
);
BOOL EnumWindows(
__in WNDENUMPROC lpEnumFunc,
__in LPARAM lParam
);
DWORD GetWindowThreadProcessId(
__in HWND hWnd,
__out LPDWORD lpdwProcessId
);
BOOL PostMessage(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam
);
****************************************************************************/

BIN
Build/Installer/UAC.dll Normal file

Binary file not shown.

200
Build/Installer/UAC.nsh Normal file
View File

@ -0,0 +1,200 @@
!ifndef UAC_HDR__INC
!verbose push
!verbose 3
!ifndef UAC_VERBOSE
!define UAC_VERBOSE 3
!endif
!verbose ${UAC_VERBOSE}
!define UAC_HDR__INC 0x00020204 ;MMmmbbrr
!include LogicLib.nsh
!macro _UAC_definemath def val1 op val2
!define /math _UAC_definemath "${val1}" ${op} ${val2}
!ifdef ${def}
!undef ${def}
!endif
!define ${def} "${_UAC_definemath}"
!undef _UAC_definemath
!macroend
!macro _UAC_ParseDefineFlags_orin parse outflags
!searchparse /noerrors ${${parse}} "" _UAC_ParseDefineFlags_orin_f1 "|" _UAC_ParseDefineFlags_orin_f2
!define _UAC_ParseDefineFlags_orin_this ${_UAC_ParseDefineFlags_orin_f1}
!undef ${parse}
!define ${parse} ${_UAC_ParseDefineFlags_orin_f2}
!define _UAC_ParseDefineFlags_orin_saveout ${${outflags}}
!undef ${outflags}
!define /math ${outflags} "${_UAC_ParseDefineFlags_orin_saveout}" | "${_UAC_ParseDefineFlags_orin_this}"
!undef _UAC_ParseDefineFlags_orin_saveout
!undef _UAC_ParseDefineFlags_orin_this
!ifdef _UAC_ParseDefineFlags_orin_f1
!undef _UAC_ParseDefineFlags_orin_f1
!undef _UAC_ParseDefineFlags_orin_f2
!endif
!macroend
!macro _UAC_ParseDefineFlags_Begin _outdef _in
!define _UAC_PDF${_outdef}_parse "${_in}"
!define _UAC_PDF${_outdef}_flags ""
!define _UAC_PDF${_outdef}_r 0
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x1
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x2
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x4
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x8
!insertmacro _UAC_ParseDefineFlags_orin _UAC_PDF${_outdef}_parse _UAC_PDF${_outdef}_flags ;0x10
!macroend
!macro _UAC_ParseDefineFlags_End _outdef
!define ${_outdef} ${_UAC_PDF${_outdef}_r}
!undef _UAC_PDF${_outdef}_r
!undef _UAC_PDF${_outdef}_flags
!undef _UAC_PDF${_outdef}_parse
!macroend
!macro _UAC_ParseDefineFlags_IncludeFlag _outdef flag
!if ${_UAC_PDF${_outdef}_flags} & ${flag}
!insertmacro _UAC_definemath _UAC_PDF${_outdef}_r ${_UAC_PDF${_outdef}_r} | ${flag}
!endif
!macroend
!macro _UAC_ParseDefineFlagsToInt _outdef _in
!insertmacro _UAC_ParseDefineFlags_Begin _UAC_ParseDefineFlagsToInt_tmp "${_in}"
!define ${_outdef} ${_UAC_PDF_UAC_ParseDefineFlagsToInt_tmp_flags}
!insertmacro _UAC_ParseDefineFlags_End _UAC_ParseDefineFlagsToInt_tmp
!undef _UAC_ParseDefineFlagsToInt_tmp
!macroend
!macro _UAC_IncL
!insertmacro _UAC_definemath __UAC_L "${__UAC_L}" + 1
!macroend
!macro _UAC_MakeLL_Cmp cmpop cmp pluginparams
!insertmacro _LOGICLIB_TEMP
UAC::_ ${pluginparams}
pop $_LOGICLIB_TEMP
!insertmacro ${cmpop} $_LOGICLIB_TEMP ${cmp} `${_t}` `${_f}`
!macroend
!macro UAC_RunElevated
UAC::_ 0
!macroend
!macro UAC_PageElevation_RunElevated
UAC::_ 0
!macroend
/*!macro UAC_OnInitElevation_RunElevated
UAC::_ 0
!macroend
!macro UAC_OnInitElevation_OnGuiInit
!macroend*/
!macro UAC_IsAdmin
UAC::_ 2
!macroend
!define UAC_IsAdmin `"" UAC_IsAdmin ""`
!macro _UAC_IsAdmin _a _b _t _f
!insertmacro _UAC_MakeLL_Cmp _!= 0 2s
!macroend
!macro UAC_IsInnerInstance
UAC::_ 3
!macroend
!define UAC_IsInnerInstance `"" UAC_IsInnerInstance ""`
!macro _UAC_IsInnerInstance _a _b _t _f
!insertmacro _UAC_MakeLL_Cmp _!= 0 3s
!macroend
!macro UAC_Notify_OnGuiInit
UAC::_ 4
!macroend
!macro UAC_PageElevation_OnGuiInit
!insertmacro UAC_Notify_OnGuiInit
!macroend
!macro UAC_PageElevation_OnInit
UAC::_ 5
${IfThen} ${Errors} ${|} Quit ${|}
!macroend
!define UAC_SYNCREGISTERS 0x1
#!define UAC_SYNCSTACK 0x2
!define UAC_SYNCOUTDIR 0x4
!define UAC_SYNCINSTDIR 0x8
#!define UAC_CLEARERRFLAG 0x10
!macro UAC_AsUser_Call type name flags
push $0
Get${type}Address $0 ${name}
!verbose push
!verbose ${UAC_VERBOSE}
!insertmacro _UAC_ParseDefineFlagsToInt _UAC_AsUser_Call__flags ${flags}
!verbose pop
StrCpy $0 "1$0:${_UAC_AsUser_Call__flags}"
!undef _UAC_AsUser_Call__flags
Exch $0
UAC::_
!macroend
!macro _UAC_AsUser_GenOp outvar op opparam1 opparam2
!define _UAC_AUGOGR_ID _UAC_AUGOGR_OP${outvar}${op}${opparam1}${opparam2}
!ifndef ${_UAC_AUGOGR_ID} ;Has this exact action been done before?
!if ${outvar} == $0
!define ${_UAC_AUGOGR_ID} $1
!else
!define ${_UAC_AUGOGR_ID} $0
!endif
!if "${opparam1}" == ""
!define _UAC_AUGOGR_OPP1 ${${_UAC_AUGOGR_ID}}
!define _UAC_AUGOGR_OPP2 ${opparam2}
!else
!define _UAC_AUGOGR_OPP1 ${opparam1}
!define _UAC_AUGOGR_OPP2 ${${_UAC_AUGOGR_ID}}
!endif
goto ${_UAC_AUGOGR_ID}_C
${_UAC_AUGOGR_ID}_F:
${op} ${_UAC_AUGOGR_OPP1} ${_UAC_AUGOGR_OPP2}
return
${_UAC_AUGOGR_ID}_C:
!undef _UAC_AUGOGR_OPP1
!undef _UAC_AUGOGR_OPP2
!endif
push ${${_UAC_AUGOGR_ID}}
!insertmacro UAC_AsUser_Call Label ${_UAC_AUGOGR_ID}_F ${UAC_SYNCREGISTERS}
StrCpy ${outvar} ${${_UAC_AUGOGR_ID}}
pop ${${_UAC_AUGOGR_ID}}
!undef _UAC_AUGOGR_ID
!macroend
!macro UAC_AsUser_GetSection datatype secidx outvar
!insertmacro _UAC_AsUser_GenOp ${outvar} SectionGet${datatype} ${secidx} ""
!macroend
!macro UAC_AsUser_GetGlobalVar var
!insertmacro _UAC_AsUser_GenOp ${var} StrCpy "" ${var}
!macroend
!macro UAC_AsUser_GetGlobal outvar srcvar
!insertmacro _UAC_AsUser_GenOp ${outvar} StrCpy "" ${srcvar}
!macroend
!macro UAC_AsUser_ExecShell verb command params workdir show
!insertmacro _UAC_IncL
goto _UAC_L_E_${__UAC_L}
_UAC_L_F_${__UAC_L}:
ExecShell "${verb}" "${command}" ${params} ${show}
return
_UAC_L_E_${__UAC_L}:
!if "${workdir}" != ""
push $outdir
SetOutPath "${workdir}"
!endif
!insertmacro UAC_AsUser_Call Label _UAC_L_F_${__UAC_L} ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} #|${UAC_CLEARERRFLAG}
!if "${workdir}" != ""
pop $outdir
SetOutPath $outdir
!endif
!macroend
!verbose pop
!endif /* UAC_HDR__INC */

BIN
Build/Installer/Wizard.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB