在 NSIS 中安装后如何为桌面和开始菜单创建快捷方式?

How to create shortcut for desktop and startmenu after installation in NSIS?

我是 NSIS 的新手。我正在尝试在 post-installation 中添加以下页面样式(即在完成页面之前)。谁能建议我们是否可以做一个自定义页面并添加必要的复选框、单选按钮和程序组?或任何其他建议。

下面是我的页面序列:

!insertmacro MUI_PAGE_DIRECTORY
  
  ;Custom page for selecting service name to restart.
  Page custom nsDialogsSelectService ngDialogSelectServicePageLeave 
  
  ; variable and text for the app data dir
  !define MUI_DIRECTORYPAGE_VARIABLE $appDataDir
  !define MUI_PAGE_HEADER_TEXT "Choose Data Directory"
  !define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install application data for ${PRODUCT_FULL} ${PVERSION}."
  !define MUI_DIRECTORYPAGE_TEXT_TOP "Setup will install data directory need todo.  To install in a different folder, click Browse and select another folder.  Click Next to Continue."
  !define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Destination Folder"
  !insertmacro MUI_PAGE_DIRECTORY 
  !insertmacro MUI_PAGE_INSTFILES
  
  !define MUI_FINISHPAGE_TITLE_3LINES
  
  Page custom nsDialogShortcut ngDialogShortcutPageLeave ;Page contain checkbox , based on the selection of checkbox I am showing Startmenu and then finish page.
  
  !insertmacro MUI_PAGE_STARTMENU 0 $SMDir  
  !insertmacro MUI_PAGE_FINISH

让用户选择 user/machine 快捷方式与 UAC 的工作方式相冲突。当非管理员用户使用管理员帐户升级时,安装程​​序将以 运行“错误”配置文件结束。

Windows 指南指出,只有应用程序套件(具有单独的主要应用程序,如 MS Office)应创建“开始”菜单文件夹。常规应用程序应直接在 $SMPrograms 中创建其(单个)快捷方式。您不应创建卸载程序或帮助文件的快捷方式。您还应该避免创建桌面快捷方式。

这意味着您可以简单地使用组件页面来提供快捷方式选项:

!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English

Section "Program files"
SectionIn RO
SetOutPath $InstDir
File "MyApp.exe"
SectionEnd

Section "Start menu shortcut"
CreateShortcut "$SMPrograms$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd

Section /o "Desktop shortcut"
CreateShortcut "$Desktop$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd

或作为“完成”页面上的复选框:

!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_SHOWREADME ""
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Start menu shortcut"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateShortcuts
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English

Function CreateShortcuts
CreateShortcut "$SMPrograms$(^Name).lnk" "$InstDir\MyApp.exe"
FunctionEnd

如果您确实有一套应用程序,那么您可以使用“开始”菜单页面提示输入文件夹名称:

Var SMFolder

!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE STARTMENU Suite $SMFolder
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English

Section
!insertmacro MUI_STARTMENU_WRITE_BEGIN Suite
CreateDirectory "$SMPrograms$SMFolder"
CreateShortcut "$SMPrograms$SMFolder\App1.lnk" "$InstDir\MyApp1.exe"
CreateShortcut "$SMPrograms$SMFolder\App2.lnk" "$InstDir\MyApp2.exe"
; TODO: Write $SMFolder to the registry or a .ini so your uninstaller can delete the folder
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd

万一您有一套应用程序并且还想创建桌面快捷方式,那么是的,您需要使用自定义页面:

Var SMDir
Var SMCheck
Var DeskCheck
Var SMList
Var SMDirEdit

!include LogicLib.nsh
!include nsDialogs.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyShortcutsPageCreate MyShortcutsPageLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English

Function .onInit
StrCpy $SMDir "$(^Name)" ; Default
StrCpy $SMCheck ${BST_CHECKED}
FunctionEnd

Function MyShortcutsPageCreate
!insertmacro MUI_HEADER_TEXT "Shortcuts" "Shortcuts blah blah blah"
nsDialogs::Create 1018
Pop [=13=]
${IfThen} [=13=] == error ${|} Abort ${|}

${NSD_CreateCheckbox} 0 0u 50% 12u "Create Start menu shortcuts"
Pop $R8
SendMessage $R8 ${BM_SETCHECK} $SMCheck ""

${NSD_CreateCheckbox} 0 14u 50% 12u "Create desktop shortcuts"
Pop $R9
SendMessage $R9 ${BM_SETCHECK} $DeskCheck ""

${NSD_CreateSortedListBox} 0 28u 100% -43u ""
Pop $SMList

${NSD_CreateText} 0 -13u 100% 12u "$SMDir"
Pop $SMDirEdit

${NSD_LB_AddString} $SMList "(Default)"
${NSD_LB_SetItemData} $SMList 0 1 ; Mark as special
SetShellVarContext Current
Call FillSMList
SetShellVarContext All
Call FillSMList
SetShellVarContext ? ; TODO: Restore to what you actually are installing as
${NSD_OnChange} $SMList OnSMListChanged

${NSD_OnClick} $R8 OnSMCheckChanged
Push $R8
Call OnSMCheckChanged
nsDialogs::Show
FunctionEnd

Function FillSMList
FindFirst [=13=]  "$SMPrograms\*"
loop:
    StrCmp  "" done
    ${If} ${FileExists} "$SMPrograms$1\*.*"
    ${AndIf}  != "."
    ${AndIf}  != ".."
        ${NSD_LB_FindStringExact} $SMList "" 
        ${If}  < 0
            ${NSD_LB_AddString} $SMList 
        ${EndIf}
    ${EndIf}
    FindNext [=13=] 
    Goto loop
done:
FindClose [=13=]
FunctionEnd

Function OnSMCheckChanged
Pop [=13=]
${NSD_GetChecked} [=13=] [=13=]
EnableWindow $SMList [=13=]
EnableWindow $SMDirEdit [=13=]
FunctionEnd

Function OnSMListChanged
Pop [=13=]
${NSD_LB_GetSelection} $SMList [=13=]
${NSD_SetText} $SMDirEdit "[=13=]$(^Name)"
${NSD_LB_GetSelectionIndex} $SMList [=13=]
${NSD_LB_GetItemData} $SMList [=13=] [=13=]
${If} [=13=] <> 0
    ${NSD_SetText} $SMDirEdit "$(^Name)"
${EndIf}
FunctionEnd

Function MyShortcutsPageLeave
${NSD_GetChecked} $R8 $SMCheck
${NSD_GetChecked} $R9 $DeskCheck
${NSD_GetText} $SMDirEdit $SMDir
FunctionEnd


Section
${If} $SMCheck <> 0
    CreateDirectory "$SMPrograms$SMDir"
    CreateShortcut "$SMPrograms$SMDir\App1.lnk" "$InstDir\App1.exe"
    CreateShortcut "$SMPrograms$SMDir\App2.lnk" "$InstDir\App2.exe"
${EndIf}

${If} $DeskCheck <> 0
    CreateShortcut "$Desktop\App1.lnk" "$InstDir\App1.exe"
    CreateShortcut "$Desktop\App2.lnk" "$InstDir\App2.exe"
${EndIf}
SectionEnd