- NSIS Discussion
- Set installation dir according to a value from an ini
Archive: Set installation dir according to a value from an ini
hasmetlee
25th March 2006 19:10 UTC
Set installation dir according to a value from an ini
Hi to all.
I was an innosetup user but decided to use nsis for some reasons. Some things are different... Anyway my problem is:
Installer should read from "XXX.ini" file to detect if TargetProgram installed for multi user profile or not. Then it should copy files to right directory. XXX.ini has these lines:
[System]
Multi User=1 or 0
if "Multi User"=1 ==> installer should understand that TargetProgram is installed for multi profile so target directory is $appdata
if "Multi User"=0 ==> installer should understand that TargetProgram is installed for single profile so target directory is $INSTDIR
Section part:
SectionGroup "Sectin1" SecMenu
Section "-"
SetOutPath "$SPECIAL_DIR"
SetOverwrite on
File Dosyalar\lang1.lng
File Dosyalar\lang2.lng
SetOutPath "$SPECIAL_DIR\skin\"
File Dosyalar\MySkin.zip
SetOutPath "$SPECIAL_DIR\toolbar\"
File Dosyalar\toolbar.ini
SectionEnd
$SPECIAL_DIR can changable acording to he XXX.ini. It may $appdata or $instdir.
How can i do nsis make this?
One more thing that, my installer doesn't overwrite files. It doesn't even warn me. I've added "SetOverwrite on" but nothing was changed...
After spending all day on help file and forums couldn't find special for this situation.
Afrow UK
25th March 2006 19:44 UTC
ReadINIStr and StrCpy
ReadINIStr $R0 "path\to\file.ini" "System" "Multi User"
StrCmp $R0 1 0 +3
StrCpy $SPECIAL_DIR $APPDATA
Goto +2
StrCpy $SPECIAL_DIR $INSTDIR
-Stu
hasmetlee
25th March 2006 22:19 UTC
Thank you very much but i got this error:
StrCmp "$R0" "1" equal=0, nonequal=+3
Usage: StrCpy $(user_var: output) str [maxlen] [startoffset]
There may be something i missed...
Afrow UK
25th March 2006 22:36 UTC
Did you declare SPECIAL_DIR with the Var instruction?
Var SPECIAL_DIR
-Stu
hasmetlee
26th March 2006 12:58 UTC
Of course did not. I forgot, sorry...
Now, i have another problem. I've done a test script and i've put a test.ini in C:\ with [System] and Multi User=1 values.
var SPECIAL_DIR
Function TestFunction
ReadINIStr $R0 "C:\Test.ini" "System" "Multi User"
StrCmp $R0 1 0 +3
StrCpy $SPECIAL_DIR $APPDATA
Goto +2
StrCpy $SPECIAL_DIR $INSTDIR
FunctionEnd
SectionGroup "!Test Section" SecMainMenu
Section "-Hidden"
SectionIn RO
SetOutPath "$INSTDIR"
SetOverwrite on
File Dosyalar\Lang1.lng
File Dosyalar\Lang2.lng
SetOutPath "$INSTDIR\skin\"
File Dosyalar\MySkin.zip
CreateDirectory "$SPECIAL_DIR\Test\toolbar"
SetOutPath "$SPECIAL_DIR\Test\toolbar\"
File Dosyalar\toolbar.ini
SectionEnd
.
.
.
SectionGroupEnd
I got this error while installing:
http://img93.imageshack.us/img93/3856/hata4ed.png
I couldn't make SPECIAL_DIR work. It returns with no string...
Afrow UK
26th March 2006 14:44 UTC
Are you even calling TestFunction? Just rename it to .onInit
-Stu
hasmetlee
26th March 2006 17:32 UTC
Ok, thanks. It works now on my test script but i can't run on my installer's script. There are several lines under .onInit section. Do you think that they may prevent to run this one?
Another question: I've noticed that, target .ini file's related line has a comment. I mean that line we want to get is like this:
[System]
Multi User=1 ; If enabled program will use Windows profiles to store individual user settings
How can i get just integer from this line?
And last question is, if there is no target.ini or no value in it, can i set an alternate installation path?
Afrow UK
26th March 2006 20:17 UTC
I'm not sure why but NSIS doesn't seem to handle comments very well when they're placed on the same lines as property values, even though NSIS uses Windows API's (I think).
Use this function:
http://nsis.sourceforge.net/Get_first_part_of_a_string
ReadINIStr $R0 "path\to\file.ini" "System" "Multi User"
StrCmp $R0 "" 0 +3
StrCpy $SPECIAL_DIR "my path"
Goto End
Push $R0
Call GetFirstStrPart
Pop $R0
StrCmp $R0 1 0 End
StrCpy $SPECIAL_DIR $APPDATA
Goto End
StrCpy $SPECIAL_DIR $INSTDIR
End:
-Stu
hasmetlee
26th March 2006 21:38 UTC
Thank you very much.
Btw, is there any editor like program which has highlighting feature? It could make easier to write script...
JasonFriday13
26th March 2006 23:24 UTC
Almost everyone uses HM NIS Edit. It is freeware and open source, and has syntax highlighting and an installoptions editor. The link above takes you to the mirrors page to download it.
Afrow UK
27th March 2006 07:52 UTC
If you want to stick with Notepad like me, you can try Notepad2:
http://www.flos-freeware.ch/notepad2.html
It has built in highlighting for many programming languages including NSIS.
-Stu
Helmut_Q
27th March 2006 14:40 UTC
These codes are interesting. I've set some part of hasmetlee's and Afrow UK's codes for me and tried to run but some part of my script didn't work.
It can copy MyApp.ini file, so "section" part did work but ---InstallDir "$My_Path_01\MyApp"--- part didn't work. Tell me please what's wrong?
!include "MUI.nsh"
!include "Sections.nsh"
Name "MyApp"
OutFile "MyApp.exe"
Function GetFirstStrPart
Exch $R0
Push $R1
Push $R2
StrLen $R1 $R0
IntOp $R1 $R1 + 1
loop:
IntOp $R1 $R1 - 1
StrCpy $R2 $R0 1 -$R1
StrCmp $R2 "" exit2
StrCmp $R2 " " exit1 ; Change " " to "\" if ur inputting dir path str
Goto loop
exit1:
StrCpy $R0 $R0 -$R1
exit2:
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Var My_Path_01
Function .onInit
ReadINIStr $R0 "C:\Test.ini" "AppDir" "MultiOrNot"
StrCmp $R0 "" 0 +3
StrCpy $My_Path_01 "$APPDATA\My_Path_02"
Goto End
Push $R0
Call GetFirstStrPart
Pop $R0
StrCmp $R0 1 0 End
StrCpy $My_Path_01 $APPDATA
Goto End
StrCpy $My_Path_01 $INSTDIR
End:
StrCpy $1 ${FGVar}
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${FGVar}
!insertmacro RadioButton ${FGYok}
!insertmacro EndRadioButtons
FunctionEnd
SectionGroup "!Test Section" SecMainMenu
Section "Hidden"
SectionIn RO
SetOutPath "$My_Path_01\MyApp"
File MyApp.ini
SectionEnd
SectionGroupEnd
InstallDir "$My_Path_01\MyApp"
!insertmacro MUI_PAGE_DIRECTORY
ShowInstDetails show
AutoCloseWindow false
Afrow UK
27th March 2006 14:48 UTC
I'm assuming then that InstallDir sets a fixed path for the installation directory. This is a constant value specified at compile time which cannot contain variables (or can, but they are ignored, correct?)
It appears that you're not even using the $INSTDIR variable which is pre-defined to store the path for where to install files too. Therefore, rather than using $My_Path_01, just use $INSTDIR! You won't even need to use the InstallDir instruction then, because the value of $INSTDIR is what is displayed on the directory page.
-Stu
hasmetlee
27th March 2006 15:02 UTC
Thanks for the program links and the informations...
Afrow UK
27th March 2006 15:10 UTC
Well I may be wrong, but if InstallDir does accept variables then it wouldn't matter anyway because you are setting the value of $My_Path_01 in .onInit. InstallDir sets the default value of $INSTDIR before .onInit. Therefore, I would have though that any variables specified in InstallDir will just be an empty string.
That's why you should be using $INSTDIR as it sets the InstallDir directly.
What installation directory do you get on the directory page? Is it "\MyApp" or "$My_Path_01\MyApp"?
-Stu
hasmetlee
31st March 2006 17:19 UTC
I've just noticed about this...
If target .ini file has zero value script doesn't work:
[System]
Multi User=0 ;comment section....
But if "Multi User=1" ==> it works... Why? What's wrong?
One more thing that, if there is no target.ini file or there is no "Multi User" line in it, my installer has %100 CPU usage. This one is a rarely situation but i have to take care all of these... How can i prevent this and make my script work?
I've cleaned up my script, here is a light version of it:
!include "MUI.nsh"
!include "Sections.nsh"
Var Yol ;Yol
;--------------------------------
Name "My Prog"
OutFile "Deneme.exe"
InstallDir "$PROGRAMFILES\Opera"
InstallDirRegKey HKCU "Software\Opera Software" "Last Directory3"
ShowInstDetails show
AutoCloseWindow false
SilentInstall normal
CRCCheck on
SetCompressor /solid "lzma"
SetDatablockOptimize on
SetOverwrite on
;--------------------------------
;Görünüm
;!define MUI_HEADERIMAGE
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico"
!define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\orange.bmp"
!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\Orange.bmp"
!define MUI_COMPONENTSPAGE_CHECKBITMAP "${NSISDIR}\Contrib\Graphics\Checks\colorful.bmp"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_FINISHPAGE_RUN $INSTDIR\Opera.exe
!define MUI_ABORTWARNING
;--------------------------------
;Pages
!insertmacro MUI_PAGE_INSTFILES
;--------------------------------
;Installer Sections
SectionGroup "Section Main" SecMenu
Section "!Needed files"
SectionIn RO
SetOutPath "$Yol\toolbar\"
File Dosyalar\toolbar.ini
SectionEnd
SectionGroupEnd
;--------------------------------
;Functions
Function GetFirstStrPart
Exch $R0
Push $R1
Push $R2
StrLen $R1 $R0
IntOp $R1 $R1 + 1
loop:
IntOp $R1 $R1 - 1
StrCpy $R2 $R0 1 -$R1
StrCmp $R2 "" exit2
StrCmp $R2 " " exit1 ; Change " " to "\" if ur inputting dir path str
Goto loop
exit1:
StrCpy $R0 $R0 -$R1
exit2:
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Function .onInit
ReadINIStr $R0 "$INSTDIR\operadef6.ini" "System" "Multi User"
StrCmp $R0 "" 0 +3
StrCpy $Yol "$APPDATA\Opera\Opera\Profile"
Goto End
Push $R0
Call GetFirstStrPart
Pop $R0
StrCmp $R0 1 0 End
StrCpy $Yol $APPDATA\Opera\Opera\Profile
Goto End
StrCpy $Yol $INSTDIR\Profile
End:
FunctionEnd
Afrow UK
31st March 2006 17:26 UTC
Sounds like GetFirstStrPart is doing an infinate loop (not sure why).
Anyway this code is cleaner:
Function .onInit
ClearErrors
ReadINIStr $R0 "$INSTDIR\operadef6.ini" "System" "Multi User"
IfErrors +2
StrCmp $R0 "" 0 +3
StrCpy $Yol "$APPDATA\Opera\Opera\Profile"
Goto End
Push $R0
Call GetFirstStrPart
Pop $R0
StrCmp $R0 1 0 +3
StrCpy $Yol $APPDATA\Opera\Opera\Profile
Goto End
StrCpy $Yol $INSTDIR\Profile
End:
FunctionEnd
-Stu
hasmetlee
31st March 2006 18:40 UTC
Thank you very much. All the codes work perfect now :)
HaMsTeYr
2nd August 2006 17:08 UTC
Something similar
Hmm... i thought that i might add on here as well, what i'm trying to achieve...
Let me just put it straight, i make counter-strike source models, and have them compiled in zip format. What i've gotten tired of is always opening up directories and specifying locations, and also directing people all the time, so i came up with the idea to create a simple installer that can achieve these tasks.
First off, if i could, i'd use the classic interface, but i'm not sure if the classic interface supports these custom pages (never quite checked). I'm working on the Modern Interface at the moment.
e.g. my steam username is hamsteyr, and the files to be put in the game to replace existing models are kept in this directory, C:\Program Files\Valve\Steam\SteamApps\hamsteyr\counter-strike source\cstrike.
My problem now is that there are no registry keys which directly link to this, but there is one which links to C:\Program Files\Valve\Steam\.
What i've done is made it look for the registry, to get the C:\Program Files\Valve\Steam\, then add the \Steamapps\...\...
So what i've got now is "$INSTDIR\SteamApps\$STEAM_USER\counter-strike source\cstrike. The variable $STEAM_USER is what i'm trying to solve here. I've tried adding a custom page that asks for the input for the username, and then put it into the installer as the variable $STEAM_USER, but that doesn't work somehow. This is my example code so far.
InstallDir "CS:Source Not found, please specifiy location"
InstallDirRegKey HKLM "SOFTWARE\Valve\Steam" "InstallPath"
!insertmacro MUI_PAGE_LICENSE "${NSISDIR}\Docs\Modern UI\License.txt"
Page custom CustomPageA
;!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
ReserveFile "Userpage.ini"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
Var STEAM_USER
Function .onInit
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "Userpage.ini"
FunctionEnd
Function CustomPageA
!insertmacro MUI_HEADER_TEXT "Steam username page" "Insert your Steam username in this page."
!insertmacro MUI_INSTALLOPTIONS_DISPLAY "Userpage.ini"
FunctionEnd
Section "" SecDummy
;Push $STEAM_USER
;!insertmacro MUI_INSTALLOPTIONS_READ $STEAM_USER "Userpage.ini" "Field 2" "State"
ReadINIStr $STEAM_USER "Userpage.ini" "Field 2" "State"
SetOutPath "$INSTDIR\SteamApps\$STEAM_USER\counter-strike source\cstrike"
File "c:\model.mdl"
SectionEnd
This is my Userpage.ini file
[Settings]
NumFields=2
[Field 1]
Type=label
Text=Your Steam username
Left=0
Right=-1
Top=0
Bottom=10
[Field 2]
Type=Text
Left=0
Right=-1
Top=20
Bottom=100
State=
Can anyone tell me why it wont work? Also, if the Directory page could show the full installdir, that would be awesome. O_o
Afrow UK
2nd August 2006 17:11 UTC
http://nsis.sourceforge.net/Get_Stea...d_install_path
Searching the forum and Wiki usually helps :p
-Stu
HaMsTeYr
4th August 2006 07:31 UTC
I tried searching forums before i posted here, and since i've been cut back to dail up i kinda got fed up of looking O_o
Btw, is it me or is the page u gave me... umm... empty O_o
kichik
4th August 2006 11:14 UTC
Originally posted by HaMsTeYr
Btw, is it me or is the page u gave me... umm... empty O_o
Someone vandalized the page a couple of hours ago. I've restored it.
HaMsTeYr
4th August 2006 16:18 UTC
Vandalised...? SWT... some people out there have no life at all =_= anyway, thanks for restoring it ;)
EDIT: I've read through the coding, and by the looks of it, the installer detects the steam user. What i'm trying to get at is for the user to specify the account name as one computer might not have just one steam user if u know what i mean. Any insight on how i could do this?