NSIS: Problem reading installdir by InstallDirRegKey - nsis

I have a nsi script which starts as following:
Name "myprog"
OutFile "myprog.exe"
InstallDir $PROGRAMFILES32\xx
InstallDirRegKey HKLM "Software\yy\xx" "InstallDir"
RequestExecutionLevel admin
AutoCloseWindow true
BrandingText /TRIMCENTER "me"
LoadLanguageFile "${NSISDIR}\Contrib\Language files\German.nlf"
Caption "Updateprogramm"
It works fine on my dev machine, but not on production (e.g. the user has only readonly permissions for the registry path). It is a Win 2003 server os. Even when the registry key exists, the program tries to install in $PROGRAMFILES32\xx.

InstallDirRegKey only needs read access.
The thing troubling thing for me is that you are talking about read only, but you have "RequestExecutionLevel admin" in your script. This says to me that you require admin rights and when you have "RequestExecutionLevel admin" you also need to use UserInfo::GetAccountType (To handle < NT6 systems and Vista+ when UAC is off)

Related

Assign HKLM/HKCU to a variable for different types of installs

I'm writing a script to associate file associations, and I'm wondering if it's possible to assign a variable to HKLM or HKCU depending on whether it's an admin or user install. The project I'm working on determines this at run time when the user appends -user for a user install as opposed to an admin install. I was thinking of something like:
Var location
${If} $InstallMode == "Admin"
$location = HKLM ;probably not the right way to assign
${Else}
$location = HKCU
${EndIf}
I'm new to NSIS and from what I've read and tried so far, I can !define a variable to be HKLM or HKCU by writing !define location HKCU but define won't work during runtime.
SHCTX exists for this purpose. It is controlled by SetShellVarContext. The default is the user (HKCU), set to All for HKLM.

Inno Setup desktop shortcut (link) which has "Run as administrator" advanced property set

I am struggling to get Inno setup (5.5.9u) to created a desktop shortcut that has an icon and has the advanced property of "Run as administrator" set.
Issue
This question, is a little different than: How to set 'Run as administrator' on a file using Inno Setup
Since what I am trying to do is not run a program at setup time with admin rights, (setup is already running at Admin), but rather leave a link on the desktop that has has the advanced property of "Run as Administrator".
Code Sample
[Icons]
Name: "{group}\EGPL Watson Uninstall"; Filename: "{uninstallexe}"; \
WorkingDir: "{app}"
Name: "{commondesktop}\DashBoard"; \
Filename: "{app}\dashboard\node_modules\electron\dist\electron.exe main.js"; \
WorkingDir: "{app}\dashboard"; \
IconFilename: "{src}\dashboard\build\configure.ico"
First, make sure you have a very good reason to run your application with Administrator privileges. User applications should not need Administrator privileges. If they need it, it's usually a sign of a bad design. One common (bad) reason to want an application to run with Administrator privileges, is that the application needs to write to its installation folder.
See Application does not work when installed with Inno Setup
Inno Setup does not natively support creating a shortcut with "Run as Administrator" flag set.
The "Run as Administrator" flag is a bit the .lnk file. See:
LinkFlags in [MS-SHLLINK]: Shell Link (.LNK) Binary File Format;
How to create a Run As Administrator shortcut using Powershell
How can I use JScript to create a shortcut that uses "Run as Administrator"
You can set the bit using the following code:
[Icons]
Name: "{userdesktop}\My Program"; Filename: "{app}\MyProg.exe"; \
AfterInstall: SetElevationBit('{userdesktop}\My Program.lnk')
[Code]
procedure SetElevationBit(Filename: string);
var
Buffer: string;
Stream: TStream;
begin
Filename := ExpandConstant(Filename);
Log('Setting elevation bit for ' + Filename);
Stream := TFileStream.Create(FileName, fmOpenReadWrite);
try
Stream.Seek(21, soFromBeginning);
SetLength(Buffer, 1);
Stream.ReadBuffer(Buffer, 1);
Buffer[1] := Chr(Ord(Buffer[1]) or $20);
Stream.Seek(-1, soFromCurrent);
Stream.WriteBuffer(Buffer, 1);
finally
Stream.Free;
end;
end;
Tested on Unicode version of Inno Setup (the only version as of Inno Setup 6). But it should, even more naturally, work on Ansi version too.

Windows 10 NSIS uninstaller to also remove notification icon

I'm working on a windows 10 app but I've noticed that when I uninstall it it's icon remains in the notification & actions window. what would I need to do or add to my uninstaller to allow it to remove this icon. This is what what uninstaller look like in my .nsi script
Section "Uninstall"
Call un.XXXXXXXXX
ExecWait '"$INSTDIR\f2p_ping.exe" --f2p' $0
; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp"
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "MyApp"
DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "MyApp"
DeleteRegKey HKLM "SOFTWARE\MyApp"
DeleteRegKey HKCU "Software\MyApp\Overlay\ExcludedProcesses"
DeleteRegKey HKCR "MyApp"
RMDir /r "$INSTDIR"
RMDir /r $PROGRAMFILES\MyApp
RMDir /r "$APPDATA\MyApp\*.*"
; Remove shortcuts, if any
SetShellVarContext current
Delete "$SMPROGRAMS\MyApp\*.*"
Delete "$SMPROGRAMS\Startup\MyApp.lnk"
SetShellVarContext all
Delete "$SMPROGRAMS\MyApp\*.*"
Delete "$SMPROGRAMS\Startup\MyApp.lnk"
Delete "$DESKTOP\MyApp.lnk"
; Remove directories used
SetShellVarContext current
RMDir "$SMPROGRAMS\MyApp"
SetShellVarContext all
RMDir "$SMPROGRAMS\MyApp"
RMDir "$INSTDIR"
SectionEnd
The best solution is probably to have your application hide the notifications since it already contains notification code. Run something like ExecWait '"$InstDir\MyApp.exe" /uninstall' at the start of your uninstaller.
It might be possible to use one of the IToast* interfaces with the System plugin but there is a lot of code needed and I don't know if Windows let's you pretend to be another application by using its Application Model Id. For example, MSDN has this to say about IToastNotificationHistory::Remove:
The app ID of the app that sent the specified toast notification. This app must be part of the same app package as the app making this remove request.
MSDN also has this to say about desktop apps:
Generally, sending a toast notification from a desktop app is the same as sending it from a Windows Store app. However, you should be aware of these differences and requirements:
For a desktop app to display a toast, the app must have a shortcut on the Start screen.
The shortcut must have an AppUserModelID.
Desktop apps cannot schedule a toast.

command AutoCloseWindow not valid in Section

Section userSoftware
MessageBox MB_YESNO|MB_ICONQUESTION "Insert user software DVD in to drive and click Yes to install User Software or click No to Proceed" /SD IDNO IDYES yes IDNO no
yes:
AutoCloseWindow true
SetRebootFlag false
Call installUserSoftware
no:
;do nothing
SectionEnd
Section: "userSoftware"
Error: command AutoCloseWindow not valid in Section
This is the error I am getting with AutoCloseWindow. All I am trying to do is after installing the server software if user selects to install Client software, installation of server software should disappear without asking user to hit finish button.
Code I gave I am just testing how AutoCloseWindow or SetAutoClose works, nut all I have is an error!!
AutoCloseWindow is a property like Name and Installdir and must be placed outside functions and sections. If you want to set the autoclose flag at runtime you must use the SetAutoClose command...

NSIS - retrieving the start menu folder not working as expected

In my NSIS script, the MUI_STARTMENU_GETFOLDER macro is not working as expected - instead of giving me the folder that the user actually entered, it gives me the default that I set earlier. Near the beginning of my script I have:
Var StartMenuFolder ; Define variable to hold start menu folder
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${PRODUCT_PUBLISHER}\${PRODUCT_NAME}" ; Set default start menu folder
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
I can access $StartMenuFolder in installer (but NOT uninstaller) Sections by use of !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder. In uninstaller sections and macros, instead of returning the actual start menu folder, it returns the default folder I specified above.
The MUI_STARTMENU_GETFOLDER macro assumes that you used the MUI_STARTMENUPAGE_REGISTRY_* defines and the MUI_STARTMENU_WRITE_* macros during install (All MUI_STARTMENU_GETFOLDER does is read the registry entry written by the installer (The entry is written in MUI_STARTMENU_WRITE_END if the MUI_STARTMENUPAGE_REGISTRY_* defines are set correctly))

Resources