Old 19th June 2009, 14:03   #1
headlock
Junior Member
 
Join Date: Jun 2009
Posts: 3
Installer doesn't delete icons in Start Menu Group

Hello everyone and huge thanks to NSIS community for doing a great job.

The project I'm working in is using NSIS and recently it was found that uninstaller doesn't do it's job correctly. Our installer supports multi user installation mode. The problem is that the uninstaller doesn't delete icons on the desktop and in the start menu group when installing application for the current user. I've found that the reason of it is that $SMPROGRAMS == AllUsers.

Here is the code:

...
!define PRODUCT_UNINST_ROOT_KEY "SHCTX"

!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY
!insertmacro MULTIUSER_PAGE_INSTALLMODE
...
Section Uninstall
...
#$SMPROGRAMS points to AllUsers
RMDir /r "$SMPROGRAMS\${MANUFACTURER}\${PRODUCT_NAME}$suffix"
RMDir "$SMPROGRAMS\${MANUFACTURER}"
..
SectionEnd

Do I need to set the context of $SMPROGRAMS manually. If yes than how do I get the installation mode used in installer?
Can someone help me please? I would appreciate it very much.

p.s: sorry for my English, i know it's not perfect
headlock is offline   Reply With Quote
Old 19th June 2009, 17:26   #2
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
I'm confused, are you trying to remove the shortcuts during install? The Uninstall section is used for creating the uninstaller (use WriteUninstaller to make the uninstaller .exe, placed in the installer code), uninstall sections aren't executed in the installer. Otherwise you use SetShellVarContext before using $SMPROGRAMS or other shell folders to specify current or all users.
redxii is offline   Reply With Quote
Old 22nd June 2009, 08:18   #3
headlock
Junior Member
 
Join Date: Jun 2009
Posts: 3
Thanks for your reply, redxii.
No, I don't try to remove shortcuts during the install process. Section 'Uninstall' is used for the uninstaller. I suppose that when user installs the application, installer writes to registry depending on what install mode has been chosen. It will write to HKLM if install mode is 'all users' or to HKCU is it's only for current user. Then, when
uninstaller is executed I suppose it should define how to initialize $SMPROGRAMS by itself. Otherwise, if it doesn't I need to implement some dummy logic like:

!if ${ROOT} == 'HKLM'
SetShellVarContext all
!else if ${ROOT} == 'HKCU'
SetShellVarContext current

In this case, how do I know the registry root of the installed application?

Last edited by headlock; 22nd June 2009 at 08:35.
headlock is offline   Reply With Quote
Old 22nd June 2009, 11:42   #4
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
The value of $MultiUser.InstallMode will be AllUsers or CurrentUser. I guess we need a SetShellVarContext push and SetShellVarContext pop.

Stu
Afrow UK is offline   Reply With Quote
Old 22nd June 2009, 13:28   #5
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,442
I have been thinking about the need for something like this also, it might be a good idea to be able to push/pop all the settings (SetShellVarContext,SetDetailsPrint,SetRegView etc)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 22nd June 2009, 16:16   #6
headlock
Junior Member
 
Join Date: Jun 2009
Posts: 3
Thanks, Afrow UK! Unfortunetely that didn't help me ...
Here is my code:

!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_INSTALLMODE_COMMANDLINE

#if uncomment this line $MultiUser.InstallMode will always be == 'CurrentUser'
#!define MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER

!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\${MANUFACTURER}\${PRODUCT_NAME}$suffix"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "Install_Dir"
!define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCT_NAME}$suffix"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\${MANUFACTURER}\${PRODUCT_NAME}$suffix"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "Install_Mode"
!define MULTIUSER_MUI
...
Section Uninstall
...
${If} $MultiUser.InstallMode == 'AllUsers'
SetShellVarContext all
${ElseIf} $MultiUser.InstallMode == 'CurrentUser'
SetShellVarContext current
${EndIf}

RMDir /r "$SMPROGRAMS\${MANUFACTURER}\${PRODUCT_NAME}$suffix"
RMDir "$SMPROGRAMS\${MANUFACTURER}"
..
SectionEnd.

Perhaps I forgot something to do...
headlock is offline   Reply With Quote
Old 22nd June 2009, 19:26   #7
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
I think you misunderstand. You just need to SetShellVarContext current before deleting the shortcuts. I posted what I did because you may want to know what to set back with SetShellVarContext afterwards.

Stu
Afrow UK is offline   Reply With Quote
Old 2nd July 2009, 09:36   #8
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Hello, I have a similar problem. I'm not quite following what the solution is though from this thread. Any chance you could go in greater detail.

For me, it's slightly different. Everything in my installer works, except for the uninstalling for the start menu shortcut. The other shortcuts (quciklaunch and desktop) are removed no problem, along with the core of the mod.

For reference here is the code I am using (well the bits that are pertinant):

code:
...
Var INSTDIR1 ; Mods
Var StartMenuFolder



code:
...
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder



code:
Section "Start Menu Shortcut" Section4
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
!insertmacro MUI_STARTMENU_WRITE_END
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\${NAME}.lnk" "$INSTDIR1\Civ4BeyondSword.exe" ...
SectionEnd



code:
Section "Uninstall"

...
;Delete Start Menu Shortcut
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
Delete "$SMPROGRAMS\$StartMenuFolder\${NAME}.lnk"
RMDir "$SMPROGRAMS\$StartMenuFolder"
...
SectionEnd




Now I can't at all figure out what's wrong with that. It installs fine, everything in this script works (even the optional add on stuff I have in other parts of the code), just the danged uninstaller refuses to remove the Start Menu shortcut. (also I replaced the icon stuff and beginning of the uninstall section with a ... because it was running off the screen, and works fine)

Anyone have any idea how to fix this?
phungus420 is offline   Reply With Quote
Old 3rd July 2009, 03:58   #9
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Well I've split the uninstaller into seperate sections, and added:

SetShellVarContext "current"

To both the onInit and un.onInit (also tried SetShellVarContext "all"), and still no dice.

Anyone have any clue what is wrong with my Uninstaller? Everything works except the blasted Start Menu refuses to be deleted.

Here is my unistaller code if that helps:

code:
;Uninstaller Section

Section "un.Core" SecUnCore

;Delete Files
RMDir /r "$0\${MOD_LOC}\*.*"
;Remove the installation directory
RMDir "$0\${MOD_LOC}"
;Delete Desktop Shortcut
Delete "$DESKTOP\${NAME}.lnk"
;Delete Quicklaunch Shortcut
Delete "$QUICKLAUNCH\${SHORT_NAME}.lnk"
SectionEnd

Section "-un.StartMenu" SecUnStartMenu

;Delete Start Menu Shortcut
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
Delete "$SMPROGRAMS\$StartMenuFolder\${NAME}.lnk"
RMDir "$SMPROGRAMS\$StartMenuFolder"
SectionEnd

Section "-un.Registry" SecUnRegistry

DeleteRegValue "${MOD_REG_ROOT}" "Software\${MOD_LOC}" "Start Menu"
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${MOD_LOC}"
SectionEnd

Section "-un.Uninstaller" SecUnUninstaller

# delete uninstaller
Delete "$INSTDIR\Uninstall.exe"
SectionEnd

Function un.onInit

;get mod install path of from the registy
SetShellVarContext "current"
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${MOD_LOC}" "ModInstDir"
FunctionEnd



I've searched and searched, and been getting help from a programmer who is pretty versed in the NSIS installer on the CivFanatics forums, and no clues come up. It just doesn't work...



Also one thing that might help would be to have a print statement to tell me what exactly the uninstaller is trying to do, that causes it to fail. Is there anyway to set up print statements in NSIS?
phungus420 is offline   Reply With Quote
Old 3rd July 2009, 07:59   #10
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Well I was able to get logging to work (with some help). The issue is that when you select the folder to install the start menu to, it doesn't relate this information.

$StartMenuFolder should be returning SELECTEDFOLDER/${MOD_LOC}, but instead only returns ${MOD_LOC}

I thought this was the whole purpose of
MUI_STARTMENU_GETFOLDER Application $StartMenuFolder

Anyone know how to get it to pull the selected folder the user chooses when installing?
phungus420 is offline   Reply With Quote
Old 3rd July 2009, 11:19   #11
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Man this is driving me nuts, I've been hammering away at it all day. My head is about to explode. I can set up another variable, like so:

code:
Section "Start Menu Shortcut" Section4
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
CreateShortCut "$SMPROGRAMS\$StartMenuFolder ...
!insertmacro MUI_STARTMENU_WRITE_END
StrCpy $StartMenuFolder1 "$SMPROGRAMS\$StartMenuFolder"
!define START_MENU_FOLDER "$StartMenuFolder1"
SectionEnd



But there seems to be no way to reference it in the uninstaller. Everytime I do, it just comes up blank if I check it. Everything I try I'm just stuck with this in the Install section, with no way to reference it in the uninstall section....
phungus420 is offline   Reply With Quote
Old 3rd July 2009, 12:40   #12
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Well I tried a really hacky work around, that I'm not sure how or why it failed. Basically I had it write the Variable to a text file it would create on install. This worked, and the document contained the correct path. Then I set it to read that file in the uninstaller. For some reason if I used a user variable, the script failed to compile. If I used one of the default variables like $R1, it compiled, but there was nothing inside it after it was told to read the file. So strange, I was sure that would work. And it's not like Read and Write code is hard, I can't see what's wrong with it (or why using a user variable would fail to compile, but using a default variable would not). For reference this is what I mean:

code:
!define START_MENU_HACK "StartMenuHack.txt" ;Do not change this block
...


Var HackStartMenu

...

StrCpy $StartMenuFolder1 "$SMPROGRAMS\$StartMenuFolder"
FileOpen $4 "$INSTDIR\Mods\${MOD_LOC}\${START_MENU_HACK}" w
FileWrite $4 "$StartMenuFolder1"
FileClose $4



Above all works, was checked, it wrote the file with the correct path.

code:
FileOpen $R4 "$INSTDIR\Mods\${MOD_LOC}\${START_MENU_HACK}" r
FileRead $R4 $HackStartMenu
FileClose $R4
Delete "$HackStartMenu\${NAME}.lnk"
RMDir "$HackStartMenu"


Now the above failed to compile. Complaiend about the FileRead $R4 $HackStartMenu, and said something about the user variable. But the strange thing was using $R2 compiled. But when I checked what was inside of it, it just came out blank. And I did move this to the top of the uninstall functions to make sure the folder wasn't deleted before it had a chance to read it.

I think I'm out of ideas now. Help.
phungus420 is offline   Reply With Quote
Old 4th July 2009, 05:34   #13
phungus420
Junior Member
 
Join Date: Apr 2009
Posts: 15
Got it to work finally. I had to write the StartMenu path to the registry. Now just one minor detail left, but guess I'll start a new thread on it.
phungus420 is offline   Reply With Quote
Old 4th July 2009, 11:02   #14
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
I was about to go onto what I meant earlier but then I've realised what your problem is. If you'd read the Multi User readme properly you would have saved yourself a lot of hassle.

code:

!define MULTIUSER_EXECUTIONLEVEL Highest
!include MultiUser.nsh

...

Function .onInit
!insertmacro MULTIUSER_INIT
FunctionEnd

Function un.onInit
!insertmacro MULTIUSER_UNINIT
FunctionEnd



Stu
Afrow UK is offline   Reply With Quote
Old 18th October 2010, 14:52   #15
hürnen
Junior Member
 
Join Date: Jun 2010
Posts: 9
Hi Afrow UK

I'd like to resume this thread, as I've got some problems too. I worked through the Multi User readme, but still don't get it.

I'll describe two scenarios, in both of which I am an admin user on XP.
1:
Install the application "for anyone using this computer". Shortcuts are created in C:\Documents and Settings\All Users\Startmenu\Programs\MyApp
Now I execute the uninstaller and everything (including shortcuts) is removed as expected.

2:
Install the application "just for me". Shortcuts are created in C:\Documents and Settings\myUser\Startmenu\Programs\MyApp
Now I execute the uninstaller but the shortcuts won't get deleted. The uninstaller tries to remove shortcuts in C:\Documents and Settings\All Users\Startmenu\Programs\MyApp, but there are none.

I assume the default "installation mode" in the uninstaller is "AllUsers", if the uninstaller is executed by an admin.

I see two solutions:
  • a check box in the uninstaller for allUsers/currentUser or
  • I have to manually save the "installation mode" during installation in the registry and read it back during uninstallation and then call SetShellVarContext with that value.

Is there a simpler solution? Or I am completely of the track?

Thanks,
Remo
hürnen is offline   Reply With Quote
Old 18th October 2010, 15:36   #16
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,442
The 2nd solution is the correct one (I believe MultiUser will do it for you if you set the correct defines) Or for my take on this: http://www.nsis.pastebin.com/PmiY8DuZ

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 25th October 2010, 18:17   #17
JackN
Junior Member
 
Join Date: Oct 2010
Posts: 10
I am trying to tailor http://www.nsis.pastebin.com/PmiY8DuZ to install a java app with several .jar libs and a dll. After making the changes I got the nsis compile warning:

Quote:
uninstall function "un.StrStr" not referenced - zeroing code (0-33) out
So I tried http://www.nsis.pastebin.com/PmiY8DuZ no changes but got the same warning. Anyone able to point me in the right direction?

Quote:
Originally Posted by Anders View Post
The 2nd solution is the correct one (I believe MultiUser will do it for you if you set the correct defines) Or for my take on this: http://www.nsis.pastebin.com/PmiY8DuZ
JackN is offline   Reply With Quote
Old 25th October 2010, 18:55   #18
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
Quote:
Originally Posted by JackN View Post
After making the changes I got the nsis compile warning:
Quote:
Originally Posted by NSIS
uninstall function "un.StrStr" not referenced - zeroing code (0-33) out
That warning is fairly benign (thus being a warning, rather than an error).

The String Functions header uses Functions for some of its musclework. Functions can't be shared between Installer and Uninstaller, so both are defined when you use ${StrStr} to initialize the functions.

If you then subsequently not actually call the uninstaller version of that Function anywhere from the uninstaller, NSIS will throw that warning out there.

Unless you really, really need to save a few bytes (those zeroes compress nicely, of course), I wouldn't worry about it.
Animaether is offline   Reply With Quote
Old 25th October 2010, 19:32   #19
JackN
Junior Member
 
Join Date: Oct 2010
Posts: 10
Uninstaller still does not delete icons in Start Menu Group or from the desktop. Do I need to delete these items explicitly? Do I need to define MUI_FINISHPAGE_RUN? This is the output from the installer followed by a script modified from http://www.nsis.pastebin.com/PmiY8DuZ:

Quote:
Delete file: C:\Program Files (x86)\MyApp\MyApp.ico
Delete file: C:\Program Files (x86)\MyApp\MyApp.jar
Delete file: C:\Program Files (x86)\MyApp\lib\jcommon-1.0.16.jar
Delete file: C:\Program Files (x86)\MyApp\lib\jfreechart-1.0.13.jar
Delete file: C:\Program Files (x86)\MyApp\lib\Serialio.jar
Remove folder: C:\Program Files (x86)\MyApp\lib\
Delete file: C:\Program Files (x86)\MyApp\uninstall.exe
Remove folder: C:\Program Files (x86)\MyApp\
Completed
PHP Code:
!define APPNAME "MyApp"
!define REGUINSTKEY "{82e9dffd-fcec-4ba6-b912-a595644cf080}" guidgen.com

!include x64.nsh

OutFile 
"Setup_${APPNAME}.exe"
Name "${APPNAME}"

!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_InstDir "${APPNAME}"

Var SMDir ;Start menu folder

!define MULTIUSER_MUI
!include MUI2.nsh
!include MultiUser.nsh

!macro WriteUninstData name data
push 
"${data}"
push "${name}"
call WriteUninstData
!macroend

!macro ReadUninstData outvar name
push 
"${name}"
call un.ReadUninstData
!if "${outvar}!= ""
pop ${outvar}
!endif
!
macroend

Function .onInit
!insertmacro MULTIUSER_INIT
FunctionEnd

Function un.onInit
;MULTIUSER_UNINIT does NOT do The Right Thing(TM), so we roll our own
!insertmacro MULTIUSER_INIT_TEXTS
UserInfo
::GetAccountType
Pop $MultiUser
.Privileges
!insertmacro ReadUninstData $1 IMode
${If} $0
    call un
.MultiUser.InstallMode.CurrentUser
${Else}
    ${If} 
$MultiUser.Privileges != Admin
        MessageBox MB_ICONSTOP 
"$(^Name)${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
        
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
        Quit
    
${EndIf}
    
call un.MultiUser.InstallMode.AllUsers
${EndIf}
FunctionEnd

!insertmacro MUI_PAGE_WELCOME
!insertmacro MULTIUSER_PAGE_INSTALLMODE
#!insertmacro MUI_PAGE_COMPONENTS ;This example does not have separate components
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU 0 $SMDir
!insertmacro MUI_PAGE_INSTFILES
###TODO:!define MUI_FINISHPAGE_RUN "$InstDir\MyApp.exe"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW PageFinShow
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

!insertmacro MUI_LANGUAGE English

Function PageFinShow
!ifdef MUI_FINISHPAGE_RUN
;When installmode != CurrentUserwe could end up running something as the wrong user...
${If} 
$MultiUser.InstallMode != CurrentUser
    SendMessage $mui
.FinishPage.Run ${BM_SETCHECK0 0
!if 1
    EnableWindow $mui
.FinishPage.Run 0
!else
    
ShowWindow $mui.FinishPage.Run 0
!endif
${EndIf}
!endif
FunctionEnd


Section 
"Required Files"
SectionIn RO
SetOutPath $InstDir
WriteUninstaller 
"$InstDir\uninstall.exe"
;Save install mode
StrCpy 
$"0" 
${IfThen$MultiUser.InstallMode == AllUsers ${|} StrCpy $"1"  ${|}
!
insertmacro WriteUninstData IMode $1

File 
${APPNAME}.ico
File dist
\${APPNAME}.jar
CreateDirectory 
"$InstDir\lib"
File /oname=lib\jcommon-1.0.16.jar dist\lib\jcommon-1.0.16.jar
File 
/oname=lib\jfreechart-1.0.13.jar dist\lib\jfreechart-1.0.13.jar
File 
/oname=lib\Serialio.jar dist\lib\Serialio.jar
WriteUninstaller $InstDir
\Uninstall.exe
Check OS for proper jspWin.dll
${If} ${RunningX64}
    
File /oname=$SYSDIR\jspWin.dll dll\64b\jspWin.dll
${Else}
    
File /oname=$SYSDIR\jspWin.dll dll\32b\jspWin.dll
${EndIf}

Check for Java Runtime Environment (JRE)
${If} ${
RunningX64
    ${
DisableX64FSRedirection
    ${
Unless} ${FileExists"$SYSDIR\javaw.exe" 
        
ExecWait '"jre-6u22-windows-x64.exe"'
    
${EndUnless
    ${
EnableX64FSRedirection
${Else}  
    ${
Unless} ${FileExists"$SYSDIR\javaw.exe" 
        
ExecWait '"jre-6u22-windows-i586-s.exe"'
    
${EndUnless
${EndIf}  
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}" UninstallString '"$InstDir\uninstall.exe"'
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}" DisplayName "${APPNAME}"
SectionEnd

Section 
-StartMenu
!insertmacro MUI_STARTMENU_WRITE_BEGIN 0
CreateDirectory 
"$SMPrograms\$SMDir"
###TODO: CreateShortcut "$SMPrograms\$SMDir\${APPNAME}.lnk" '"$InstDir\MyApp.exe"'
CreateDirectory "$SMPrograms\$SMDir"
CreateShortCut "$SMPrograms\$SMDir\${APPNAME}.lnk" "$SYSDIR\javaw.exe" "-jar ${APPNAME}.jar" "$INSTDIR\${APPNAME}.ico"
CreateShortCut "$SMPrograms\$SMDir\Uninstall ${APPNAME}.lnk" "$INSTDIR\Uninstall.exe" "$INSTDIR\${APPNAME}.ico"
CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$SYSDIR\javaw.exe" "-jar ${APPNAME}.jar" "$INSTDIR\${APPNAME}.ico"
;We need to save the startmenu folder so we can remove the shortcut in the uninstaller
!insertmacro WriteUninstData SMDir $SMDir
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd

Section Uninstall
!insertmacro ReadUninstData $SMDir SMDir
${If} $InstDir != ""
    
Delete "$InstDir\${APPNAME}.ico"
    
Delete "$InstDir\${APPNAME}.jar"
    
RMDir /"$InstDir\lib"
${EndIf}
${If} 
$SMDir != ""
    
Delete "$SMPrograms\$SMDir\${APPNAME}.lnk"
    
RMDir "$SMPrograms\$SMDir"
${EndIf}
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}"
Delete "$InstDir\uninstall.exe"
RMDir "$InstDir"
Delete "$DESKTOP\MyApp.lnk"
SectionEnd

Function WriteUninstData
Exch 
$1
push 
$0
Exch 2
FileOpen 
$"$InstDir\uninstall.exe" a
FileSeek 
$0 0 END
FileWrite 
$"$\n$1>"
pop $1
FileWrite 
$$1
FileClose 
$0
pop 
$1
pop 
$0
FunctionEnd

Function Un.ReadUninstData
Exch 
$9
Push 
$0
Push 
$1
Push 
$2
Push 
$3
FileOpen 
$"$EXEPATHr
StrCpy 
$3 2
${Do}
    
IntOp $$1
    FileSeek 
$-$3 END $1
    
${If} $9999 ;${If} $33000
        StrCpy 
$"" ;failed
        
${Break}
    ${EndIf}
    
FileRead $$1
    StrLen 
$$9
    IntOp 
$$1
    StrCpy 
$$$2
    
${If} $== "$9>"
        
StrLen $$9
        IntOp 
$$1
        StrCpy 
$$"" $2
        
${Do}
            
StrCpy $$9 1 -1
            
${If} $!= "$\n"
            
${AndIf} $!= "$\r"
                
${Break}
            ${EndIf}
            
StrCpy $$-1
        
${Loop}
        ${Break}
    ${EndIf}
${
Loop}
pop $3
pop 
$2
pop 
$1
pop 
$0
Exch 
$9
FunctionEnd 
JackN is offline   Reply With Quote
Old 25th October 2010, 20:45   #20
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
Just off the bat.. since you are using MultiUser for a mixed admin/non-admin install are you checking for the correct context? $SMPrograms will either be the currently logged in user's start menu if SetShellVarContext is set to 'current' (default) and it looks as if you are intending to remove all users' start menu. The same goes for $DESKTOP, its location too will depend on SetShellVarContext.

One way is to check a string in HKCU or HKLM to see which exists, then set un.MultiUser.InstallMode.AllUsers or un.MultiUser.InstallMode.CurrentUser accordingly. You have to check HKLM and HKCU explicitly you can't use SHCTX.

Last edited by redxii; 25th October 2010 at 21:44.
redxii is offline   Reply With Quote
Old 25th October 2010, 21:49   #21
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,442
The warning is there because multiuser.nsh wants it, but since its uninstaller handling is broken (IMHO) I use some custom stuff and the function that uses un.StrStr never gets called. I'm guessing you could !define UnStrStr_INCLUDED before including multiuser.nsh and then undef it again.

The normal way to deal with a problem like this is to messagebox the path in the uninstaller and make sure it is correct like redxii suggests.

But there is a bigger problem here, why are you using a dual mode script (single and all users) when you are installing files in $sysdir, only admins can do that so normal users will not be able to install without errors!

As a final note, adding a desktop shortcut in the startmenu section is well, not kind to your users, just add a desktop shortcut section and a components page

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 26th October 2010, 13:07   #22
JackN
Junior Member
 
Join Date: Oct 2010
Posts: 10
Ok: back to basics since I need to complete this. I don't need MultiUser or Admin, I was just following the example in http://www.nsis.pastebin.com/PmiY8DuZ hoping to get to a quick solution. I've gone back to something simpler that installs properly but uninstall is only partial. SMPrograms icons are still not being deleted. I have been programming in embedded environments for some time but I am very new to application programming and desktop environments. I am developing on Vista 64 but need to target XP and Vista 32 and 64 installs. I don't need all the bells and whistles in this 1.0 distribution but it would be nice if I could get it to uninstall properly. What is the simplest method to repair the uninstall to include SMPrograms?

Install details:

Quote:
Output folder: C:\Program Files (x86)\MyApp
Extract: MyApp.ico... 100%
Extract: MyApp.jar... 100%
Create folder: C:\Program Files (x86)\MyApp\lib
Extract: lib\jcommon-1.0.16.jar... 100%
Extract: lib\jfreechart-1.0.13.jar... 100%
Extract: lib\Serialio.jar... 100%
Created uninstaller: C:\Program Files (x86)\MyApp\Uninstall.exe
Extract: C:\Windows\system32\jspWin.dll... 100%
Create folder: C:\Users\jackn\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp
Create shortcut: C:\Users\jackn\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp\MyApp.lnk
Create shortcut: C:\Users\jackn\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp\Uninstall MyApp.lnk
Completed
Uninstall details:

Quote:
Delete file: C:\Program Files (x86)\MyApp\MyApp.ico
Delete file: C:\Program Files (x86)\MyApp\MyApp.jar
Delete file: C:\Program Files (x86)\MyApp\Uninstall.exe
Delete file: C:\Program Files (x86)\MyApp\lib\jcommon-1.0.16.jar
Delete file: C:\Program Files (x86)\MyApp\lib\jfreechart-1.0.13.jar
Delete file: C:\Program Files (x86)\MyApp\lib\Serialio.jar
Remove folder: C:\Program Files (x86)\MyApp\lib\
Remove folder: C:\Program Files (x86)\MyApp\
Remove folder: C:\Users\jackn\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\MyApp\
Completed
PHP Code:
!define APPNAME "MyApp"
!define REGUINSTKEY "{ce9c1ec4-7410-4376-bf7e-4abf0bd9f0ac}" guidgen.com
!include x64.nsh
OutFile 
"Setup_${APPNAME}.exe"
Name "${APPNAME}"
InstallDir "$PROGRAMFILES\${APPNAME}"
DirText "Please choose install directory"

Section "Install"
SetOutPath $InstDir
File 
${APPNAME}.ico
File dist
\${APPNAME}.jar
CreateDirectory 
"$InstDir\lib"
File /oname=lib\jcommon-1.0.16.jar dist\lib\jcommon-1.0.16.jar
File 
/oname=lib\jfreechart-1.0.13.jar dist\lib\jfreechart-1.0.13.jar
File 
/oname=lib\Serialio.jar dist\lib\Serialio.jar
WriteUninstaller $InstDir
\Uninstall.exe
Check OS for proper jspWin.dll
${If} ${RunningX64}
    
File /oname=$SYSDIR\jspWin.dll dll\64b\jspWin.dll
${Else}
    
File /oname=$SYSDIR\jspWin.dll dll\32b\jspWin.dll
${EndIf}
Check for Java Runtime Environment (JRE)
${If} ${
RunningX64
    ${
DisableX64FSRedirection
    ${
Unless} ${FileExists"$SYSDIR\javaw.exe" 
        
ExecWait '"jre-6u22-windows-x64.exe"'
    
${EndUnless
    ${
EnableX64FSRedirection
${Else}  
    ${
Unless} ${FileExists"$SYSDIR\javaw.exe" 
        
ExecWait '"jre-6u22-windows-i586-s.exe"'
    
${EndUnless
${EndIf}  
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}" "UninstallString" '"$InstDir\Uninstall.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}" "DisplayName" "${APPNAME} (remove only)"
CreateDirectory "$SMPrograms\${APPNAME}"
CreateShortCut "$SMPrograms\${APPNAME}\${APPNAME}.lnk" "$SYSDIR\javaw.exe" "-jar ${APPNAME}.jar" "$InstDir\${APPNAME}.ico"
CreateShortCut "$SMPrograms\${APPNAME}\Uninstall ${APPNAME}.lnk" "$InstDir\Uninstall.exe" "$InstDir\${APPNAME}.ico"
MessageBox MB_OK "Installation was successful."
SectionEnd

Section Uninstall
${If} $InstDir != ""
    
Delete "$InstDir\${APPNAME}.ico"
    
Delete "$InstDir\${APPNAME}.jar"
    
Delete "$InstDir\Uninstall.exe"
    
RMDir /"$InstDir\lib"
    
RMDir "$InstDir"
${EndIf}
Delete "$SMPrograms\${APPNAME}\${APPNAME}.lnk"
Delete "$SMPrograms\${APPNAME}\Uninstall ${APPNAME}.lnk"
RMDir "$SMPrograms\${APPNAME}"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${REGUINSTKEY}"
SectionEnd 
JackN is offline   Reply With Quote
Old 26th October 2010, 15:32   #23
JackN
Junior Member
 
Join Date: Oct 2010
Posts: 10
Solved: also needed
PHP Code:
RequestExecutionLevel highest 
JackN is offline   Reply With Quote
Old 26th October 2010, 16:04   #24
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,442
Quote:
Originally Posted by JackN View Post
Solved: also needed
PHP Code:
RequestExecutionLevel highest 
This issue is a known NT6 problem, see http://nsis.sourceforge.net/Shortcut..._Windows_Vista (Basically, MS broke all old nsis installers)

Using "RequestExecutionLevel highest" is not the correct solution for you since you are installing stuff in $sysdir. Like I said, only admins can do that. Take a look at http://www.nsis.pastebin.com/63tS3AS2 for info on how to make sure your installer runs as admin. Also, it is probably a good idea for you to set "SetShellVarContext all" in BOTH the installer and uninstaller before touching the $smprograms variable.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump