[GH-ISSUE #5606] Allow installation without creation of a lnk on Public Desktop on Windows #11795

Open
opened 2026-08-05 01:31:02 -04:00 by saavagebueno · 2 comments
Owner

Originally created by @smertins-mlsys on GitHub (Mar 16, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5606

Is your feature request related to a problem? Please describe.
Currently, the installer automatically creates a shortcut on the Windows Public Desktop. In some environments, like multi-user systems or managed enterprise setups, this behavior is not desired. I want to install the application without placing a shortcut on the desktop for all users.

Describe the solution you'd like
Allow setting a property, e.g., DESKTOPSHORTCUT=0, during installation to prevent the creation of a public desktop shortcut:

msiexec /i "netbird_installer_0.66.4_windows_amd64.msi" /qn DESKTOPSHORTCUT=0

This could be a command-line property or a checkbox in the installer GUI.

Describe alternatives you've considered

  • Manually deleting the shortcut after installation
  • Using a custom script to remove the shortcut post-installation
    These are workarounds, but having a built-in option would be cleaner and more reliable.
    (Both are problematic because i notice in other programs the lnk can be recreated on update)

Additional context
This feature is particularly useful in enterprise environments where system administrators want to control which shortcuts appear on users’ desktops.

Originally created by @smertins-mlsys on GitHub (Mar 16, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5606 **Is your feature request related to a problem? Please describe.** Currently, the installer automatically creates a shortcut on the Windows Public Desktop. In some environments, like multi-user systems or managed enterprise setups, this behavior is not desired. I want to install the application without placing a shortcut on the desktop for all users. **Describe the solution you'd like** Allow setting a property, e.g., DESKTOPSHORTCUT=0, during installation to prevent the creation of a public desktop shortcut: `msiexec /i "netbird_installer_0.66.4_windows_amd64.msi" /qn DESKTOPSHORTCUT=0` This could be a command-line property or a checkbox in the installer GUI. **Describe alternatives you've considered** - Manually deleting the shortcut after installation - Using a custom script to remove the shortcut post-installation These are workarounds, but having a built-in option would be cleaner and more reliable. (Both are problematic because i notice in other programs the lnk can be recreated on update) **Additional context** This feature is particularly useful in enterprise environments where system administrators want to control which shortcuts appear on users’ desktops.
saavagebueno added the feature-request label 2026-08-05 01:31:02 -04:00
Author
Owner

@jogoossens commented on GitHub (Jun 2, 2026):

Indeed, very nice we can already lock down config, but showing this icon is only recommending the end users to fiddle with the settings :)

<!-- gh-comment-id:4601213705 --> @jogoossens commented on GitHub (Jun 2, 2026): Indeed, very nice we can already lock down config, but showing this icon is only recommending the end users to fiddle with the settings :)
Author
Owner

@ptcmariano commented on GitHub (Jul 24, 2026):

NSIS — only creates the shortcut during the first installation. I record a marker in HKLM\Software\Netbird\DesktopShortcutCreated; if it already exists, the shortcut creation is skipped regardless of what the user did with the file afterwards. On uninstall, I clear this key so that a clean reinstallation reverts to the default behavior.

MSI/WiX — I separated the shortcut into its own Component, with KeyPath pointing to a registry entry (not the .lnk), and a Property DESKTOPSHORTCUT (default "1") read via RegistrySearch from the persisted value. This solves two problems at once:

allows msiexec /i netbird_installer.msi DESKTOPSHORTCUT=0 — which is exactly what is requested in the related issue #5606;

since the choice is stored in the registry, future upgrades read the previous value and do not recreate the shortcut.

patch:
diff --git a/client/installer.nsis b/client/installer.nsis
index 7169907..70b3690 100644
--- a/client/installer.nsis
+++ b/client/installer.nsis
@@ -24,6 +24,10 @@

!define AUTOSTART_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Run"

+; Dedicated key used to remember install-time choices across upgrades,
+; independent of anything the user does to the files/shortcuts afterwards.
+!define NETBIRD_SETTINGS_REG_KEY "Software\Netbird"
+
!define NETBIRD_DATA_DIR "$COMMONPROGRAMDATA\Netbird"

Unicode True
@@ -240,7 +244,16 @@ EnVar::AddValueEx "path" "$INSTDIR"

SetShellVarContext all
CreateShortCut "$SMPROGRAMS${APP_NAME}.lnk" "$INSTDIR${UI_APP_EXE}"
-CreateShortCut "$DESKTOP${APP_NAME}.lnk" "$INSTDIR${UI_APP_EXE}"
+
+; Only create the desktop shortcut the first time NetBird is installed.
+; Once created, the user is free to remove it -- track that we already
+; created it once via a registry marker so later updates/reinstalls don't
+; put it back, regardless of whether the .lnk currently exists on disk.
+ReadRegStr $0 HKLM "${NETBIRD_SETTINGS_REG_KEY}" "DesktopShortcutCreated"
+${If} $0 != "1"

  • CreateShortCut "$DESKTOP${APP_NAME}.lnk" "$INSTDIR${UI_APP_EXE}"
  • WriteRegStr HKLM "${NETBIRD_SETTINGS_REG_KEY}" "DesktopShortcutCreated" "1"
    +${EndIf}
    SectionEnd

Install the Microsoft Edge WebView2 runtime if it isn't already present.

@@ -308,6 +321,10 @@ DeleteRegValue HKLM "${AUTOSTART_REG_KEY}" "${APP_NAME}"
DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "${APP_NAME}"
DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "netbird"

+; Clear the desktop-shortcut marker so a clean reinstall (after a full
+; uninstall) creates the shortcut again, same as a first-time install.
+DeleteRegKey HKLM "${NETBIRD_SETTINGS_REG_KEY}"
+
; Handle data deletion based on checkbox
DetailPrint "Checking if user requested data deletion..."
${If} $DeleteDataEnabled == "1"
diff --git a/client/netbird.wxs b/client/netbird.wxs
index f30a7aa..9a13a0a 100644
--- a/client/netbird.wxs
+++ b/client/netbird.wxs
@@ -17,11 +17,7 @@


  •   			<File ProcessorArchitecture="$(var.ProcessorArchitecture)" Source=".\dist\netbird_windows_$(var.ArchSuffix)\netbird-ui.exe">
    
  •   				<Shortcut Id="NetbirdDesktopShortcut" Directory="DesktopFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon">
    
  •   					<ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" />
    
  •   					<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" />
    
  •   				</Shortcut>
    
  •   			<File Id="NetbirdUiExe" ProcessorArchitecture="$(var.ProcessorArchitecture)" Source=".\dist\netbird_windows_$(var.ArchSuffix)\netbird-ui.exe">
      				<Shortcut Id="NetbirdStartMenuShortcut" Directory="StartMenuFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon">
      					<ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" />
      					<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" />
    

@@ -50,6 +46,25 @@

  •   <!-- Desktop shortcut, DESKTOPSHORTCUT=0 to skip: msiexec /i netbird_installer.msi DESKTOPSHORTCUT=0
    
  •        Kept in its own component with a registry KeyPath (not the .lnk file
    
  •        itself), so:
    
  •          - the choice can be set from the command line for silent/enterprise
    
  •            installs (addresses #5606), and
    
  •          - once installed, MSI does not recreate the shortcut on every
    
  •            upgrade just because the user deleted it -- the persisted
    
  •            registry value is what MSI checks, not the file on disk. -->
    
  •   <StandardDirectory Id="DesktopFolder">
    
  •   	<Component Id="NetbirdDesktopShortcutComponent" Guid="a2f6e6a1-6f0e-4d1a-9d3f-9b6b6a4c9f21" Bitness="always64">
    
  •   		<Condition>DESKTOPSHORTCUT = "1"</Condition>
    
  •   		<RegistryValue Root="HKLM" Key="SOFTWARE\Netbird" Name="DesktopShortcut" Type="string" Value="[DESKTOPSHORTCUT]" KeyPath="yes" />
    
  •   		<Shortcut Id="NetbirdDesktopShortcut" Directory="DesktopFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon" Target="[#NetbirdUiExe]">
    
  •   			<ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" />
    
  •   			<ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" />
    
  •   		</Shortcut>
    
  •   	</Component>
    
  •   </StandardDirectory>
    
  •   <!-- Per-user component: HKCU keypath (auto GUID via "*"), separate from
           the per-machine NetbirdFiles component to satisfy ICE57. -->
      <StandardDirectory Id="ProgramMenuFolder">
    

@@ -71,8 +86,18 @@


  •   	<ComponentRef Id="NetbirdDesktopShortcutComponent" />
      </ComponentGroup>
    
  •   <!-- Defaults to creating the shortcut (matches current behavior).
    
  •        Seeded from SOFTWARE\Netbird\DesktopShortcut if this machine was
    
  •        installed before, so an upgrade preserves whatever the user chose
    
  •        the first time even if DESKTOPSHORTCUT isn't passed again. -->
    
  •   <Property Id="DESKTOPSHORTCUT" Value="1" Secure="yes">
    
  •   	<RegistrySearch Id="DesktopShortcutPrevChoice" Root="HKLM"
    
  •   		Key="SOFTWARE\Netbird" Name="DesktopShortcut" Type="raw" />
    
  •   </Property>
    
  •   <util:CloseApplication Id="CloseNetBird" CloseMessage="no" Target="netbird.exe" RebootPrompt="no" />
      <util:CloseApplication Id="CloseNetBirdUI" CloseMessage="no" Target="netbird-ui.exe" RebootPrompt="no" TerminateProcess="0" />
    
<!-- gh-comment-id:5069765055 --> @ptcmariano commented on GitHub (Jul 24, 2026): NSIS — only creates the shortcut during the first installation. I record a marker in HKLM\Software\Netbird\DesktopShortcutCreated; if it already exists, the shortcut creation is skipped regardless of what the user did with the file afterwards. On uninstall, I clear this key so that a clean reinstallation reverts to the default behavior. MSI/WiX — I separated the shortcut into its own Component, with KeyPath pointing to a registry entry (not the .lnk), and a Property DESKTOPSHORTCUT (default "1") read via RegistrySearch from the persisted value. This solves two problems at once: allows msiexec /i netbird_installer.msi DESKTOPSHORTCUT=0 — which is exactly what is requested in the related issue [#5606](https://github.com/netbirdio/netbird/issues/5606); since the choice is stored in the registry, future upgrades read the previous value and do not recreate the shortcut. patch: diff --git a/client/installer.nsis b/client/installer.nsis index 7169907..70b3690 100644 --- a/client/installer.nsis +++ b/client/installer.nsis @@ -24,6 +24,10 @@ !define AUTOSTART_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Run" +; Dedicated key used to remember install-time choices across upgrades, +; independent of anything the user does to the files/shortcuts afterwards. +!define NETBIRD_SETTINGS_REG_KEY "Software\Netbird" + !define NETBIRD_DATA_DIR "$COMMONPROGRAMDATA\Netbird" Unicode True @@ -240,7 +244,16 @@ EnVar::AddValueEx "path" "$INSTDIR" SetShellVarContext all CreateShortCut "$SMPROGRAMS\${APP_NAME}.lnk" "$INSTDIR\${UI_APP_EXE}" -CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${UI_APP_EXE}" + +; Only create the desktop shortcut the first time NetBird is installed. +; Once created, the user is free to remove it -- track that we already +; created it once via a registry marker so later updates/reinstalls don't +; put it back, regardless of whether the .lnk currently exists on disk. +ReadRegStr $0 HKLM "${NETBIRD_SETTINGS_REG_KEY}" "DesktopShortcutCreated" +${If} $0 != "1" + CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${UI_APP_EXE}" + WriteRegStr HKLM "${NETBIRD_SETTINGS_REG_KEY}" "DesktopShortcutCreated" "1" +${EndIf} SectionEnd # Install the Microsoft Edge WebView2 runtime if it isn't already present. @@ -308,6 +321,10 @@ DeleteRegValue HKLM "${AUTOSTART_REG_KEY}" "${APP_NAME}" DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "${APP_NAME}" DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "netbird" +; Clear the desktop-shortcut marker so a clean reinstall (after a full +; uninstall) creates the shortcut again, same as a first-time install. +DeleteRegKey HKLM "${NETBIRD_SETTINGS_REG_KEY}" + ; Handle data deletion based on checkbox DetailPrint "Checking if user requested data deletion..." ${If} $DeleteDataEnabled == "1" diff --git a/client/netbird.wxs b/client/netbird.wxs index f30a7aa..9a13a0a 100644 --- a/client/netbird.wxs +++ b/client/netbird.wxs @@ -17,11 +17,7 @@ <Directory Id="NetbirdInstallDir" Name="Netbird"> <Component Id="NetbirdFiles" Guid="db3165de-cc6e-4922-8396-9d892950e23e" Bitness="always64"> <File ProcessorArchitecture="$(var.ProcessorArchitecture)" Source=".\dist\netbird_windows_$(var.ArchSuffix)\netbird.exe" KeyPath="yes" /> - <File ProcessorArchitecture="$(var.ProcessorArchitecture)" Source=".\dist\netbird_windows_$(var.ArchSuffix)\netbird-ui.exe"> - <Shortcut Id="NetbirdDesktopShortcut" Directory="DesktopFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon"> - <ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" /> - <ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" /> - </Shortcut> + <File Id="NetbirdUiExe" ProcessorArchitecture="$(var.ProcessorArchitecture)" Source=".\dist\netbird_windows_$(var.ArchSuffix)\netbird-ui.exe"> <Shortcut Id="NetbirdStartMenuShortcut" Directory="StartMenuFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon"> <ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" /> <ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" /> @@ -50,6 +46,25 @@ </Directory> </StandardDirectory> + <!-- Desktop shortcut, DESKTOPSHORTCUT=0 to skip: msiexec /i netbird_installer.msi DESKTOPSHORTCUT=0 + Kept in its own component with a registry KeyPath (not the .lnk file + itself), so: + - the choice can be set from the command line for silent/enterprise + installs (addresses #5606), and + - once installed, MSI does not recreate the shortcut on every + upgrade just because the user deleted it -- the persisted + registry value is what MSI checks, not the file on disk. --> + <StandardDirectory Id="DesktopFolder"> + <Component Id="NetbirdDesktopShortcutComponent" Guid="a2f6e6a1-6f0e-4d1a-9d3f-9b6b6a4c9f21" Bitness="always64"> + <Condition>DESKTOPSHORTCUT = "1"</Condition> + <RegistryValue Root="HKLM" Key="SOFTWARE\Netbird" Name="DesktopShortcut" Type="string" Value="[DESKTOPSHORTCUT]" KeyPath="yes" /> + <Shortcut Id="NetbirdDesktopShortcut" Directory="DesktopFolder" Name="NetBird" WorkingDirectory="NetbirdInstallDir" Icon="NetbirdIcon" Target="[#NetbirdUiExe]"> + <ShortcutProperty Key="System.AppUserModel.ID" Value="NetBird" /> + <ShortcutProperty Key="System.AppUserModel.ToastActivatorCLSID" Value="{0E1B4DE7-E148-432B-9814-544F941826EC}" /> + </Shortcut> + </Component> + </StandardDirectory> + <!-- Per-user component: HKCU keypath (auto GUID via "*"), separate from the per-machine NetbirdFiles component to satisfy ICE57. --> <StandardDirectory Id="ProgramMenuFolder"> @@ -71,8 +86,18 @@ <ComponentGroup Id="NetbirdFilesComponent"> <ComponentRef Id="NetbirdFiles" /> <ComponentRef Id="NetbirdAumidRegistry" /> + <ComponentRef Id="NetbirdDesktopShortcutComponent" /> </ComponentGroup> + <!-- Defaults to creating the shortcut (matches current behavior). + Seeded from SOFTWARE\Netbird\DesktopShortcut if this machine was + installed before, so an upgrade preserves whatever the user chose + the first time even if DESKTOPSHORTCUT isn't passed again. --> + <Property Id="DESKTOPSHORTCUT" Value="1" Secure="yes"> + <RegistrySearch Id="DesktopShortcutPrevChoice" Root="HKLM" + Key="SOFTWARE\Netbird" Name="DesktopShortcut" Type="raw" /> + </Property> + <util:CloseApplication Id="CloseNetBird" CloseMessage="no" Target="netbird.exe" RebootPrompt="no" /> <util:CloseApplication Id="CloseNetBirdUI" CloseMessage="no" Target="netbird-ui.exe" RebootPrompt="no" TerminateProcess="0" />
Sign in to join this conversation.
No Label feature-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11795