Reg Key and Install Directory for Complete

What was $SMPROGRAMS set to then? I thought you said it was pointing to the wrong start menu. I don't see how you would optimize that code any. Is there anything in particular you find slow?

You might be able to set a pre-function that is called before the page is shown. If that section is unselected, call Abort to skip the page.
 
What was $SMPROGRAMS set to then? I thought you said it was pointing to the wrong start menu.

I checked it using the FileWrite method Balderstrom linked to. Had it write down what was being stored in the variable(s) in a logging text file. The problem was when the variable $SMPROGRAMS was called outside the section, it didn't include the Folder the user selected. So if I asked $SMPROGRAMS what it was inside the Start Menu section it would return:
C:\Documents and Settings\P\Start Menu\Programs\Firaxis Games (because I picked Firaxis Games as the menu folder to be in)
When I asked it what it was outside the section it would tell me it was:
C:\Documents and Settings\P\Start Menu\Programs

So I had to end up writing the Start Menu to the registry inside that section, because NSIS wol't let me set a variable inside the install sections, and then call for it in the uninstall sections. First I tried creating a new variable StartMenuFolder1, set it in the StartMenu section, and from then on in the installer section if I asked it what it was it would return the correct path, but if I put it in the uninstall section it just returned blank (the logger wrote nothing).

I don't see how you would optimize that code any. Is there anything in particular you find slow?
I was more worried about the Registry stuff. I'm no programmer and tinkering with other users registries worries me :mischief:, but if you say it looks clean, sounds good to me.

You might be able to set a pre-function that is called before the page is shown. If that section is unselected, call Abort to skip the page.

That would work yes. Any idea how to do this?

What I was just trying to do was set it so that the Start Menu Shortcut box was locked in (always checked), like the Main install is. I know it's here where it's controlled:

Code:
  Function myOnGUIInit
    SectionGetFlags ${Section1} $0
    IntOp $R0 $0 | ${SF_SELECTED}
    SectionSetFlags ${Section1} $R0
  FunctionEnd

And possibly here:

Code:
  Function onInitDirectoryPage1
    StrCpy $CurrentPage "DirectoryPage1"
    ;Section 1 selected?
    SectionGetFlags ${Section1} $0
    IntOp $R0 $0 & ${SF_SELECTED}
    IntCmp $R0 ${SF_SELECTED} checkRegEntry

But I can't figure out how to make Section4 also locked into being selected. I've been reading the tutorials, and searching around the NSIS stuff, but I can't find an example of multiple options being locked in. Only single sections, which I already have.

Either system, setting it up so that the page doesn't load to select the Start Menu folder, or Locking the Start Menu option at the beggining would both work (you can unselect the start menu shortcut in that screen anyway). Any advice/code examples would be much apreciated.
 
Well this is the example I can find on skipping a page:

Code:
  Function customPage
    MessageBox MB_YESNO "Skip custom page?" IDNO noskip
	  Abort
    noskip:
  # StartMenu is used here just for the sake of the example.
  # In real installers, use the MUI_PAGE_STARTMENU macro instead.
  StartMenu::Select "This is a custom page"
  Pop $0
  FunctionEnd
 
  Function dirPre
    MessageBox MB_YESNO "Skip directory page?" IDNO noskip
    	Abort
    noskip:
  FunctionEnd

I'd like to turn it into something like so:
Code:
  Function customPage
    ${If} Section4 notSelected
	  Abort
    ${endIf}
    noskip:  
  StartMenu::Select "!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder"
  Pop $0
  FunctionEnd

But I'm more then a bit confused about how to turn that into real code :crazyeye:

Edit:

Also looks like I need to add that into this funciton:
Code:
  Function onInitDirectoryPage1
    StrCpy $CurrentPage "DirectoryPage1"
    ;Section 1 selected?
    SectionGetFlags ${Section1} $0
    IntOp $R0 $0 & ${SF_SELECTED}
    IntCmp $R0 ${SF_SELECTED} checkRegEntry
      Abort ;skip page
    checkRegEntry:
      StrCmp $INSTDIR "" 0 checkDefaultLocation
        StrCpy $INSTDIR1 "" ;we know nothing
        Return
      checkDefaultLocation:
          StrCpy $INSTDIR1 "$INSTDIR" ;found it!
  FunctionEnd

As this is already where the Custom Page stuff is defined.
 
Well I tried this:

Code:
  Function onInitDirectoryPage1
    StrCpy $CurrentPage "DirectoryPage1"
    ;Section 1 selected?
    SectionGetFlags ${Section1} $0
    IntOp $R0 $0 & ${SF_SELECTED}
    IntCmp $R0 ${SF_SELECTED} checkRegEntry
      Abort ;skip page
    checkRegEntry:
      StrCmp $INSTDIR "" 0 checkDefaultLocation
        StrCpy $INSTDIR1 "" ;we know nothing
        Return
      checkDefaultLocation:
          StrCpy $INSTDIR1 "$INSTDIR" ;found it!

      [B]SectionGetFlags ${Section4} $R0 
      IntOp $R0 $R0 & ${SF_SELECTED} 
      IntCmp $R0 ${SF_SELECTED} show 
 
      Abort 
 
      show: 
        !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder[/B]
    FunctionEnd

And it fails to compile either because:

1)I leave it in the beggining list of components. It complains that it's already defined
2)I remove it from the original list, and it complains because when it gets to the start menu stuff, it can't run the !insertmacro MUI_STARTMENU_WRITE_BEGIN Application part of the code.
 
Looking at bug.nsi, it seems all this is what I'm doing already. Have you tried playing around with that script to see what you can get to work? Here's the page definition:

Code:
!define MUI_STARTMENUPAGE_NODISABLE
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${MOD_REG_ROOT}"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${MOD_REG_KEY}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu"
[B]!define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu[/B]
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder

The bold part tells it to use this custom pre function:

Code:
Function preStartMenu
	${Unless} ${SectionIsSelected} ${SecStartMenu}
		Abort
	${EndUnless}
FunctionEnd

BTW, the three MUI_STARTMENUPAGE_REGUSTRY_ROOT/KEY/VALUENAME settings look to me like I'm providing the registry information for storing the path to the folder the user ends up creating in the start menu. I don't think you needed to do any of your own registry stuff. That's why my script is able to read the directory from the registry during uninstallation.

BTW, the uninstaller gets created by the installer, but no variables get copied to it. I suspect that it gets created by the compiler and packaged into the installer as just another file to be copied. Thus, any variable you set in the installer doesn't exist in the uninstaller.
 
Cool. Took me a while to figure out how to do it.

Had to create a new custom page to set up a new MUI_PAGE_CUSTOMFUNCTION_PRE, otherwise said it was undefined. But then I had this new custom page that wouldn't compile. So searched looking for examples of setting up custom pages. No help, finally in frustration I tried this:

Code:
  Page custom StartMenuShortcut
  !define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu
  !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
  ;Source code scripting removed

along with the required function (otherwise it wol't compile, because it can't set up the custom page. Check my rocking code:

Spoiler :
Code:
  Function StartMenuShortcut
  
    Abort
  FunctionEnd

Works flawlessly :thanx:
 
What this line for?

Code:
Page custom StartMenuShortcut

Since you're using the start menu page macro, I see no use for it, especially since you never show it.
 
Had to create a new custom page to set up a new MUI_PAGE_CUSTOMFUNCTION_PRE, otherwise said it was undefined. But then I had this new custom page that wouldn't compile. So searched looking for examples of setting up custom pages.

Sorry, typo. Didn't mean to say undefined, meant to say already defined. The script already uses a MUI_PAGE_CUSTOMFUNCTION_PRE, so to use a second one, I had to give it it's own custom page. Otherwise, it failed to compile "MUI_PAGE_CUSTOMFUNCTION_PRE is already defined!"

Hence my rocking function abort endfunction code. Didn't see a way around it, and that hack worked so :)
 
Five of my pages have pre functions, so I don't think that second !define was actually the problem. Or I totally misunderstood what you said. Actually, probably the latter.
 
So long as yer just dropping a key into the registry and pulling it back out if they happen to uninstall - then don't worry about it. It's what _should_ be done.

Recently I've updated some software I've had kicking around - Nir Sofer mini-utilities. Apparently as he's been updating of late he's been changing functionality to make them more "USB Drive" friendly. Personally I believe it to be a huge step backwards:
Most of the utils now write .cfg files into their .exe directory, as opposed to storing into the registry (as they used to) - or an option for the end-user to decide whether to drop the .cfg's into the Registry|Application Data or where the binary (.exe) is.

This pollutes the programFiles directory with frequently changing data, or System32 if you've dropped them there. Something I haven't seen since the Win98 days. If others started doing this as well it would make backups of your data a nightmare. As opposed to pulling a single key from the registry for backup, or grabbing the "Application Data" folder, you wind up with .ini's and .cfg's scattered all over the place.

Anyways blah blah blah :) Registry is a good thing when used correctly. It's just unfortunate that some companies like Symantec or Adobe stick everything under the sun there .

Glad you were able to get things ironed out. For future reference, if you are doing any coding, as EF has said - it really is extremely important to track what your variables are actually doing... Otherwise you're just shooting in the dark.
 
Yeah, I wasn't able to focus on the problem until I got it to print exactly what was in the variables.
 
I'm going to start working on getting the installer to install the UserSettings folder in the My Documents path, instead of Program Files, so that Vista Users will no longer need to launch as an admin. I know the BUG intaller installs there by default, into custom assets. I was looking over the BUG installer in the SVN to find out how the BUG installer gets the correct path for the user's computer, as the My Documents path can be different for different users. I can't find it unfortunately.

I have found this however:
Code:
Function findCivRootDir

	Push $0
	
	# locate the Civ4:BTS INI folder
	StrCpy $0 "$DOCUMENTS\My Games\Beyond the Sword"
	${If} ${FileExists} "$0\${CIV_INI_FILE}"
		StrCpy $CivRootDir $0
		StrCpy $CivIniFile "$0\${CIV_INI_FILE}"
		Goto done
	${EndIf}
	
	# can't find it
	StrCpy $CivRootDir ""
	StrCpy $CivIniFile ""

done:
	Pop $0

FunctionEnd
Searching for DOCUMENTS uncovered nothing. Where are you guys defining the variable $DOCUMENTS so that the installer finds the correct path to the CivilizationIV.ini file?
 
Top Bottom