Search code examples
pythonpyqtpyqt5pyinstallernsis

NSIS setup desktop icon, start menu icon and Abort/Retry/Ignore Error


I made a PyQt5 application recently and built it using pyinstaller. I have made the zip file. Now I wanted to to use NSIS to get an installer. I went to the sample's page and copied the following code "Simple installer and uninstaller with start menu item" https://nsis.sourceforge.io/Simple_tutorials#Simple_installer_and_uninstaller_with_start_menu_item.

I have tried to read the docs but I 'm confused between what is the installation dir, is it where the installer files would be or where like after you install some software on windows in Program Files. All installation files are visible in C:/Program Files/[Some Software].Is it that folder? Also there is SetOutPath. I want the similar behaviour too i.e, the installer should have checkboxes for shortcut icon on desktop and start menu. It should point in C:\Program Files[Name of app] when user runs installer. Currently it is giving me Retry/Ignore/ Abort error when run with "a.nsi", the script with the copied code. Otherwise when I try to use the make installer with zip file option I get the nice installer but that doesnt place desktop icon or start menu icon and the default installation dir it shows is desktop.

Name "Mailer"
# define name of installer
OutFile "Mailer-install.exe"
# For removing Start Menu shortcut in Windows 7
RequestExecutionLevel user

# define installation directory
InstallDir $PROGRAMFILES


# start default section
Section

    # set the installation directory as the destination for the following actions
    SetOutPath $INSTDIR
    File "Mailer.zip"
    # create the uninstaller
    WriteUninstaller "$INSTDIR\uninstall.exe"

    # create a shortcut named "new shortcut" in the start menu programs directory
    # point the new shortcut at the program uninstaller
    CreateShortCut "$SMPROGRAMS\new shortcut.lnk" "$INSTDIR\uninstall.exe"
SectionEnd

# uninstaller section start
Section "uninstall"

    # first, delete the uninstaller
    Delete "$INSTDIR\uninstall.exe"

    # second, remove the link from the start menu
    Delete "$SMPROGRAMS\new shortcut.lnk"

# uninstaller section end
SectionEnd

<h3> The logs if required</h3> 

MakeNSIS v3.05 - Copyright 1999-2019 Contributors
See the file COPYING for license details.
Credits can be found in the Users Manual.

Processing config: C:\Program Files (x86)\NSIS\nsisconf.nsh
Processing default plugins: "C:\Program Files (x86)\NSIS\Plugins\x86-ansi\*.dll"
 + Banner::destroy
 + Banner::getWindow
 + Banner::show
 + BgImage::AddImage
 + BgImage::AddText
 + BgImage::Clear
 + BgImage::Destroy
 + BgImage::Redraw
 + BgImage::SetBg
 + BgImage::SetReturn
 + BgImage::Sound
 + Dialer::AttemptConnect
 + Dialer::AutodialHangup
 + Dialer::AutodialOnline
 + Dialer::AutodialUnattended
 + Dialer::GetConnectedState
 + InstallOptions::dialog
 + InstallOptions::initDialog
 + InstallOptions::show
 + LangDLL::LangDialog
 + Math::Script
 + StartMenu::Init
 + StartMenu::Select
 + StartMenu::Show
 + System::Alloc
 + System::Call
 + System::Copy
 + System::Free
 + System::Get
 + System::Int64Op
 + System::Store
 + System::StrAlloc
 + TypeLib::GetLibVersion
 + TypeLib::Register
 + TypeLib::UnRegister
 + UserInfo::GetAccountType
 + UserInfo::GetName
 + UserInfo::GetOriginalAccountType
 + VPatch::GetFileCRC32
 + VPatch::GetFileMD5
 + VPatch::vpatchfile
 + advsplash::show
 + nsDialogs::Create
 + nsDialogs::CreateControl
 + nsDialogs::CreateItem
 + nsDialogs::CreateTimer
 + nsDialogs::GetUserData
 + nsDialogs::KillTimer
 + nsDialogs::OnBack
 + nsDialogs::OnChange
 + nsDialogs::OnClick
 + nsDialogs::OnNotify
 + nsDialogs::SelectFileDialog
 + nsDialogs::SelectFolderDialog
 + nsDialogs::SetRTL
 + nsDialogs::SetUserData
 + nsDialogs::Show
 + nsExec::Exec
 + nsExec::ExecToLog
 + nsExec::ExecToStack
 + nsisdl::download
 + nsisdl::download_quiet
 + splash::show

!define: "MUI_INSERT_NSISCONF"=""

Changing directory to: "C:\Users\Dell\Desktop\New folder (3)\f"

Processing script file: "C:\Users\Dell\Desktop\New folder (3)\f\a.nsi" (ACP)
Name: "Mailer"
OutFile: "Mailer-install.exe"
InstallDir: "$PROGRAMFILES"
Section: ""
SetOutPath: "$INSTDIR"
File: "Mailer.zip" [compress] 57197161/57534535 bytes
WriteUninstaller: "$INSTDIR\uninstall.exe"
CreateShortcut: "$SMPROGRAMS\new shortcut.lnk"->"$INSTDIR\uninstall.exe"  icon:,0, nwd=0, showmode=0x0, hotkey=0x0, comment=
SectionEnd
Section: "uninstall"
Delete: "$INSTDIR\uninstall.exe"
Delete: "$SMPROGRAMS\new shortcut.lnk"
SectionEnd

Processed 1 file, writing output (x86-ansi):
warning 7998: ANSI targets are deprecated
Processing pages... Done!
Removing unused resources... Done!
Generating language tables... Done!
Generating uninstaller... Done!

Output: "C:\Users\Dell\Desktop\New folder (3)\f\Mailer-install.exe"
Install: 1 page (64 bytes), 1 section (2072 bytes), 5 instructions (140 bytes), 40 strings (726 bytes), 1 language table (198 bytes).
Uninstall: 1 page (128 bytes), 1 section (2072 bytes), 3 instructions (84 bytes), 39 strings (617 bytes), 1 language table (194 bytes).

Using zlib compression.

EXE header size:               36352 / 37888 bytes
Install code:                    728 / 2568 bytes
Install data:               57197165 / 57534547 bytes
Uninstall code+data:             909 / 1409 bytes
CRC (0x02F0CF53):                  4 / 4 bytes

Total size:                 57235158 / 57576416 bytes (99.4%)

1 warning:
  7998: ANSI targets are deprecated


Solution

  • You made a fatal change in the example script, you changed InstallDir to $PROGRAMFILES and you cannot write to $PROGRAMFILES if you are not a elevated administrator!

    To give the user the option to create the shortcut or not, put it in a separate Section and add a components page:

    Name "MyApp"
    OutFile "MyAppSetup.exe"
    Unicode True
    RequestExecutionLevel Admin ; Request UAC elevation
    InstallDir "$ProgramFiles\$(^Name)"
    
    Page Components
    Page Directory
    Page InstFiles
    
    Uninstpage UninstConfirm
    Uninstpage InstFiles
    
    !include LogicLib.nsh
    
    !macro EnsureAdminRights
      UserInfo::GetAccountType
      Pop $0
      ${If} $0 != "admin" ; Require admin rights on WinNT4+
        MessageBox MB_IconStop "Administrator rights required!"
        SetErrorLevel 740 ; ERROR_ELEVATION_REQUIRED
        Quit
      ${EndIf}
    !macroend
    
    Function .onInit
      SetShellVarContext All
      !insertmacro EnsureAdminRights
    FunctionEnd
    
    Function un.onInit
      SetShellVarContext All
      !insertmacro EnsureAdminRights
    FunctionEnd
    
    
    Section "Program files (Required)"
      SectionIn Ro
      SetOutPath $InstDir ; Sets the output directory for File instructions
      WriteUninstaller "$InstDir\Uninst.exe"
      File "/oname=$InstDir\MyApp.exe" "${NSISDIR}\Bin\MakeLangId.exe" ; Pretend that we have a real application to install
    SectionEnd
    
    Section "Start Menu shortcut"
      CreateShortcut /NoWorkingDir "$SMPrograms\$(^Name).lnk" "$InstDir\MyApp.exe"
    SectionEnd
    
    
    Section -Uninstall
      Delete "$InstDir\MyApp.exe"
      Delete "$InstDir\Uninst.exe"
      RMDir "$InstDir"
    
      Delete "$SMPrograms\$(^Name).lnk"
    SectionEnd
    

    Note: This is a slightly modified version of the install-shared.nsi example script. That script also registers the uninstaller with the Control Panel/Settings App which you should also do in a real installer.