|
|
|
|
#1 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Newbie question
I'm new to NSIS (couple of days). It seems to be a great tool thus far. I seem to have everything working except for one issue. I'm installing a 32 bit legacy app on Windows 7x64. I cannot get the InstallLib macro to write files to $SYSDIR or "$COMMONFILES\Microsoft Shared\VFP".
I think I have set RequestExecutionLevel and used UAC_RunElevated correctly?? from what I found in the examples and forums. The File statement does succeed in creating a file in the SysWOW64 folder, so $SYSDIR is working for it. It also creates the $INSTDIR folder under Program Files x64 and populates the files. There are no error messages; the $SYSDIR files simply do not get created. I seem to be close but I must be missing something simple - either a setting, system variable, or I may not fully understand the coding order required. I am listing the code (less uninstall) in hopes that someone can look at it and point me in the right direction. ; Script generated by the HM NIS Edit Script Wizard. ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "KOF Data System" !define PRODUCT_VERSION "1.0" !define PRODUCT_PUBLISHER "KOF Company" !define PRODUCT_WEB_SITE "http://www.zakula.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\kfMain.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir" ; MUI 1.67 compatible ------ !include "MUI.nsh" !include LogicLib.nsh ; Administrative priveleges !include UAC.nsh ; 64 bit compatibility ------ !include x64.nsh ; jz ; DLL/TLB installation routine ------ !include Library.nsh ; jz ; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !define MUI_LICENSEPAGE_CHECKBOX !insertmacro MUI_PAGE_LICENSE "g:\kof_setup_9\License.txt" ; Start menu page var ICONS_GROUP !define MUI_STARTMENUPAGE_NODISABLE !define MUI_STARTMENUPAGE_DEFAULTFOLDER "KOF Data System" !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}" !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_RUN "$INSTDIR\kfMain.exe" !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\ReadMe.txt" !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "kfSetup.exe" InstallDir "$PROGRAMFILES\KOF" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" BrandingText 'KOF System' ShowInstDetails show ShowUnInstDetails show RequestExecutionLevel none BGGradient FF0000 0000FF 00FF00 Icon 'g:\kof_Setup_9\kof.ico' InstProgressFlags 'smooth' LicenseBkColor '/windows' WindowIcon on SetFont Tahoma 10 ;;;;;;;;; FUNCTION .ONINIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function .onInit ; jz ; Try to setup admin priveleges for install process (COPIED EXAMPLE) uac_tryagain: !insertmacro UAC_RunElevated #MessageBox mb_TopMost "0=$0 1=$1 2=$2 3=$3" ${Switch} $0 ${Case} 0 ${IfThen} $1 = 1 ${|} Quit ${|} ;we are the outer process, the inner process has done its work, we are done ${IfThen} $3 <> 0 ${|} ${Break} ${|} ;we are admin, let the show go on ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user MessageBox mb_IconExclamation|mb_TopMost|mb_SetForeground "This installer requires admin access, try again" /SD IDNO IDOK uac_tryagain IDNO 0 ${EndIf} ;fall-through and die ${Case} 1223 MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This installer requires admin privileges, aborting!" Quit ${Case} 1062 MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!" Quit ${Default} MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate , error $0" Quit ${EndSwitch} ; Set up and display splash screen w/fade-in SetOutPath $TEMP File /oname=$PLUGINSDIR\SplashTmp.bmp "g:\kof_setup_9\KOF_SetupSplash1.bmp" advsplash::show 1000 850 500 -1 $PLUGINSDIR\SplashTmp ; To determine the system folders (32 bit or 64 bit) at runtime ${EnableX64FSRedirection} StrCpy $INSTDIR "$PROGRAMFILES\KOF" FunctionEnd ;;;;;;;;; FUNCTION .ONINIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; FUNCTION .ONGUIEND ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function .onGuiEnd ; jz ; Run PostgreSql ODBC 8.3 install application, and then delete it ExecWait '"msiexec" /i "$INSTDIR\psql_odbc_8_3.msi"' ; PostgreSQL ODBC installer ;Delete "$INSTDIR\psql_odbc_8_3.msi" ; If Chosen by user, display the readme file MessageBox MB_YESNO|MB_ICONQUESTION "Do you wish to view the ReadMe file now?" IDNO false !system '"$WINDIR\notepad.exe" "$INSTDIR\ReadMe.txt"' false: MessageBox MB_YESNO|MB_ICONQUESTION "The computer must be rebooted for settings to take effect. Do you wish to reboot your computer now?" IDNO false2 Reboot false2: FunctionEnd ;;;;;;;;; FUNCTION .ONGUIEND ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;; SECTION SEC01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Section "MainSection" SEC01 SetOverwrite ifnewer ; Copy into $INSTDIR SetOutPath "$INSTDIR" ; Copy app-specific files File "g:\kof_setup_9\kfMain.exe" File "g:\kof_setup_9\Config.fpw" File "g:\kof_setup_9\AppStart.app" ; Dummy app to trigger "get updated build" process File "g:\kof_setup_9\kf0000.app" File "g:\kof_setup_9\AppInfo.ini" File "g:\kof_setup_9\ReportOutput.app" File "g:\kof_setup_9\ReportPreview.app" File "g:\kof_setup_9\ReportBuilder.app" File "g:\kof_setup_9\FoxTools.fll" File "g:\kof_setup_9\MD5.fll" File "g:\kof_setup_9\FoxUser.dbf" File "g:\kof_setup_9\FoxUser.fpt" File "g:\kof_setup_9\vfpAlert.exe" ; Copy necessary ODBC driver installation package File "g:\kof_setup_9\PostgresOdbcDriver\psql_odbc_8_3.msi" ; Copy files needed for Dazzle interface is to be shipping computer CreateDirectory "$INSTDIR\Dazzle" SetOutPath "$INSTDIR\Dazzle" File "g:\kof_setup_9\Dazzle\Dazzle_BoundPrint.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_FirstClass.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_MediaMail.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_ParcelPost.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_PriorityMail.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_APO_FPO_ShipLabel.lyt" File "g:\kof_setup_9\Dazzle\Dazzle_Lg_Pri_Intl_ShipLbl.lyt" File "g:\kof_setup_9\Dazzle\KofPackage1.lyt" File "g:\kof_setup_9\Dazzle\DazzleAddressCodes.txt" File "g:\kof_setup_9\Dazzle\DazzlePostalServices.txt" File "g:\kof_setup_9\Dazzle\KofDazzle_ReadMe.txt" ; Copy into $INSTDIR\BarCode_Scanner CreateDirectory "$INSTDIR\BarCode_Scanner" SetOutPath "$INSTDIR\BarCode_Scanner" File "g:\kof_setup_9\BarCode_Scanner\Free3of9.txt" File "g:\kof_setup_9\BarCode_Scanner\kf_ScannerSetup.txt" File "g:\kof_setup_9\BarCode_Scanner\Xi2000_Manual.pdf" File "g:\kof_setup_9\BarCode_Scanner\Xi2000_Spec.pdf" ; Copy into $FONTS SetOutPath "$FONTS" File "g:\kof_setup_9\BarCode_Scanner\Free3of9.ttf" File "g:\kof_setup_9\BarCode_Scanner\Fre3of9x.ttf" SetOutPath "$SYSDIR" ; Try to use a straight file write to sysdir File "g:\kof_setup_9\TestSysDirFile.txt" ; Install in $COMMONFILES or $SYSDIR !insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsVcr71.dll" $SYSDIR $COMMONFILES CreateDirectory "$COMMONFILES\Microsoft Shared\VFP" !insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\GdiPlus.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib REGDLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\vfp9R.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib REGDLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\vfp9T.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\vfp9Renu.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib REGEXE SHARED REBOOT_PROTECTED "g:\kof_setup_9\FoxHHelp9.exe" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\FoxHHelpPs9.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES ; Already available in windows ;!insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsXml3.dll" $SYSDIR $COMMONFILES ;!insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsXml3r.dll" $SYSDIR $COMMONFILES !insertmacro InstallLib DLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsXml3a.dll" $SYSDIR $COMMONFILES !insertmacro InstallLib REGDLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsXml4.dll" $SYSDIR $COMMONFILES !insertmacro InstallLib REGDLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\MsXml4r.dll" $SYSDIR $COMMONFILES !insertmacro InstallLib REGDLL SHARED REBOOT_PROTECTED "g:\kof_setup_9\Filer.dll" "$COMMONFILES\Microsoft Shared\VFP" $COMMONFILES !insertmacro InstallLib DLL NOTSHARED REBOOT_PROTECTED "g:\kof_setup_9\DibApi32.dll" $INSTDIR $COMMONFILES ; Create the Shortcuts !insertmacro MUI_STARTMENU_WRITE_BEGIN Application SetShellVarContext all CreateDirectory "$SMPROGRAMS\KOF Data System" CreateShortCut "$SMPROGRAMS\KOF Data System\KOF.lnk" "$INSTDIR\kfMain.exe" CreateShortCut "$DESKTOP\KOF.lnk" "$INSTDIR\kfMain.exe" CreateShortCut "$QUICKLAUNCH\KOF.lnk" "$INSTDIR\kfMain.exe" SetShellVarContext current !insertmacro MUI_STARTMENU_WRITE_END SectionEnd ;;;;;;; SECTION SEC01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
|
|
#2 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
In your post, I assume you meant Program Files (x86)? You need to use ${DisableX64FSRedirection} to write to system32/Program Files. Also I would recommend using MUI2.nsh over MUI.nsh (uses nsDialogs and is therefore faster).
Your script isn't too big but in future please attach the script or use pastebin. Stu |
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Hi Stu,
Thanks, I did mean x86. I changed ${EnableX64FSRedirection} to ${DisableX64FSRedirection} but the 32 bit files still do not show up in the system directory (SysWoW64?) with InstallLib. Is .onInit the right place for this? Thanks for the prompt response. Jeff |
|
|
|
|
|
#4 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
OK sorry if you want to install to SysWOW64 then you do not need to enable or disable file system redirection. Windows will redirect to SysWOW64 anyway. If it is not working then you don't have access to the folder. You need to use RequestExecutionLevel admin.
Edit: Also .onInit would not be the correct place as the Wow64EnableWow64FsRedirection API only works for the current thread. Sections run under a new thread and therefore you'd need to use Wow64EnableWow64FsRedirection again. Stu |
|
|
|
|
|
#5 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Hi Stu,
I'm back again. I cannot seem to get get this thing to work. I've tried what you suggested and a host of other things. The InstallLib macro simply refuses to install any files in any system folders or any "common files" subfolders. The File command has no problem writing these dlls to the folders where InstallLib fails. What is the special secret to making InstallLib work? Do I need to use SetOutPath to point to the target directory even though the target directory is one of the parameters? Is my syntax somehow incorrect? Do I need to use the File command to copy the file first? How do I know it got registered, etc? I have attached my code so you can see the InstallLib syntax. I must be doing something really stupid, but I can't seem to see what. This is the only problem I've had, but without this functionality there is no install. Jeff |
|
|
|
|
|
#6 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Sorry, I forgot to attach on the last post.
Jeff |
|
|
|
|
|
#7 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Do you need to use the UAC plugin? I've been doing fine with RequestionExecutionLevel admin on Windows 7 32/64.
I recommend just writing a basic script which does the bare minimum until you can find out the problem. Stu |
|
|
|
|
|
#8 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
No problem. I'll comment it out and try it.
Also, I'm just about coded up to use the File command to create the files and RegDLL to register them. Is that a feasible way to do the same thing? Jeff |
|
|
|
|
|
#9 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
It depends on the library. RegDll is the same as using regsvr32 /s (but does not depend on it).
Stu |
|
|
|
|
|
#10 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Hi Stu,
I've been out of the office for a while. The presence of the UAC plugin didn't affect my problem either way. I did, when I got back, get things working in a round-about way. I found a prewritten installer for all the VFP support libraries that I needed. I called that installer from an ExecWait statement. I preceded that with instructions on a notepad window called from ExecWait. I followed that with a .msi to install odbc drivers via ExecWait. It's not thrilling, but it works. I would still like to know why InstallLib fails for the next time that I need to do something similar. Thanks for the effort, Jeff |
|
|
|
|
|
#11 |
|
Moderator
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
|
Notepad window? If you mean a console window you can hide those using nsExec.
Stu |
|
|
|
|
|
#12 |
|
Junior Member
Join Date: Dec 2010
Posts: 7
|
Well, actually it is a Notepad window. I don't need to really hide. I'm using an external installer (exe) for some of the support libraries during the middle of the NSIS install. But it requires to make a few selections on its start screen. So I use ExecWait to display the Notepad window with instructions on what to select, and it informs the user that the install process will continue when he closes the instruction window.
But I have another question. In my script I would like to abstract the path where the compiler finds the source files. This way I could put everything on the local server where there is easy access to the installation executable. Also, edits and recompiles of the script that might be needed will always be where they are going to be used, eliminating the need to remember to copy any files when any change occurs. Can I just copy my current ${NSISDIR} tree to the server? Will everything work there from any computer, or is an install required because of support files or reg keys? Then I can add my source folders to that tree and and use ${NSISDIR} to find everything. Also, $EXEPATH and $EXEDIR do not presently work. Is this because I move the exe file after it gets compiled to the server where it gets run from desktop computers as a program on a mapped network drive? In fact, maybe this is why InstallLib does not work at runtime? |
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|