speedo,w32: Allow installation as normal user
authorAndre Heinecke <aheinecke@intevation.de>
Wed, 3 May 2017 12:40:16 +0000 (14:40 +0200)
committerAndre Heinecke <aheinecke@intevation.de>
Wed, 3 May 2017 12:49:26 +0000 (14:49 +0200)
* build-aux/speedo/w32/g4wihelp.c (ENV_HK_USER, ENV_REG_USER):
New defines.
(path_add): Handle is_user_install variable. Don't abort
if Path reg key does not exist. Fix crash if Path reg key
does not contain a semicolon.
(path_remove): Handle is_user_install variable. Fix crash
if Path reg key does not exist.
* build-aux/speedo/w32/inst.nsi: Remove obsolete HAVE_STARTMENU
this was double guarded with WITH_GUI. Add Multiuser plugin and
defines for this. Use SHCTX instead of HKLM / HKCU.
(PrintNonAdminWarning): Only Warn and don't abort.

--
The default is still to install as Adminstrator system wide
but the user now has the option to explicitly install GnuPG without
Administrator rights. A warning will be shown in that case but
a user may continue.

A per user install is by default under %LOCALAPPDATA%\GnuPG

Related Task: T2971

Signed-off-by: Andre Heinecke <aheinecke@intevation.de>
build-aux/speedo/w32/g4wihelp.c
build-aux/speedo/w32/inst.nsi

index 012e4af..d62d036 100644 (file)
@@ -964,10 +964,8 @@ read_w32_registry_string (HKEY root, const char *dir, const char *name)
 #define ENV_REG "SYSTEM\\CurrentControlSet\\Control\\" \
     "Session Manager\\Environment"
   /* The following setting can be used for a per-user setting.  */
 #define ENV_REG "SYSTEM\\CurrentControlSet\\Control\\" \
     "Session Manager\\Environment"
   /* The following setting can be used for a per-user setting.  */
-#if 0
-#define ENV_HK HKEY_CURRENT_USER
-#define ENV_REG "Environment"
-#endif
+#define ENV_HK_USER HKEY_CURRENT_USER
+#define ENV_REG_USER "Environment"
 /* Due to a bug in Windows7 (kb 2685893) we better put a lower limit
    than 8191 on the maximum length of the PATH variable.  Note, that
    depending on the used toolchain we used to had a 259 byte limit in
 /* Due to a bug in Windows7 (kb 2685893) we better put a lower limit
    than 8191 on the maximum length of the PATH variable.  Note, that
    depending on the used toolchain we used to had a 259 byte limit in
@@ -979,12 +977,16 @@ path_add (HWND hwndParent, int string_size, char *variables,
          stack_t **stacktop, extra_parameters_t *extra)
 {
   char dir[PATH_LENGTH_LIMIT];
          stack_t **stacktop, extra_parameters_t *extra)
 {
   char dir[PATH_LENGTH_LIMIT];
+  char is_user_install[2];
   char *path;
   char *path_new;
   int path_new_size;
   char *comp;
   const char delims[] = ";";
   char *path;
   char *path_new;
   int path_new_size;
   char *comp;
   const char delims[] = ";";
+  int is_user;
   HKEY key_handle = 0;
   HKEY key_handle = 0;
+  HKEY root_key;
+  const char *env_reg;
 
   g_hwndParent = hwndParent;
   EXDLL_INIT();
 
   g_hwndParent = hwndParent;
   EXDLL_INIT();
@@ -997,13 +999,26 @@ path_add (HWND hwndParent, int string_size, char *variables,
   if (popstring (dir, sizeof (dir)))
     return;
 
   if (popstring (dir, sizeof (dir)))
     return;
 
-/*   MessageBox (g_hwndParent, "XXX 2", 0, MB_OK); */
+  /* The expected stack layout: HKEY component.  */
+  if (popstring (is_user_install, sizeof (is_user_install)))
+    return;
+
+  if (!strcmp(is_user_install, "1"))
+    {
+      root_key = ENV_HK_USER;
+      env_reg = ENV_REG_USER;
+    }
+  else
+    {
+      root_key = ENV_HK;
+      env_reg = ENV_REG;
+    }
+
+  path = read_w32_registry_string (root_key, env_reg, "Path");
 
 
-  path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
   if (! path)
     {
   if (! path)
     {
-      MessageBox (g_hwndParent, "No PATH variable found", 0, MB_OK);
-      return;
+      path = strdup ("");
     }
 
 /*   MessageBox (g_hwndParent, "XXX 3", 0, MB_OK); */
     }
 
 /*   MessageBox (g_hwndParent, "XXX 3", 0, MB_OK); */
@@ -1041,6 +1056,8 @@ path_add (HWND hwndParent, int string_size, char *variables,
   do
     {
 /*       MessageBox (g_hwndParent, comp, 0, MB_OK); */
   do
     {
 /*       MessageBox (g_hwndParent, comp, 0, MB_OK); */
+      if (!comp)
+        break;
 
       if (!strcmp (comp, dir))
        {
 
       if (!strcmp (comp, dir))
        {
@@ -1053,10 +1070,8 @@ path_add (HWND hwndParent, int string_size, char *variables,
   while (comp);
   free (path);
 
   while (comp);
   free (path);
 
-/*   MessageBox (g_hwndParent, "XXX 8", 0, MB_OK); */
-
-  /* Set a key for our CLSID.  */
-  RegCreateKey (ENV_HK, ENV_REG, &key_handle);
+  /* Update the path key.  */
+  RegCreateKey (root_key, env_reg, &key_handle);
   RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
                 path_new, path_new_size);
   RegCloseKey (key_handle);
   RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
                 path_new, path_new_size);
   RegCloseKey (key_handle);
@@ -1074,6 +1089,7 @@ path_remove (HWND hwndParent, int string_size, char *variables,
             stack_t **stacktop, extra_parameters_t *extra)
 {
   char dir[PATH_LENGTH_LIMIT];
             stack_t **stacktop, extra_parameters_t *extra)
 {
   char dir[PATH_LENGTH_LIMIT];
+  char is_user_install[2];
   char *path;
   char *path_new;
   int path_new_size;
   char *path;
   char *path_new;
   int path_new_size;
@@ -1082,6 +1098,8 @@ path_remove (HWND hwndParent, int string_size, char *variables,
   HKEY key_handle = 0;
   int changed = 0;
   int count = 0;
   HKEY key_handle = 0;
   int changed = 0;
   int count = 0;
+  HKEY root_key;
+  const char *env_reg;
 
   g_hwndParent = hwndParent;
   EXDLL_INIT();
 
   g_hwndParent = hwndParent;
   EXDLL_INIT();
@@ -1092,7 +1110,25 @@ path_remove (HWND hwndParent, int string_size, char *variables,
   if (popstring (dir, sizeof (dir)))
     return;
 
   if (popstring (dir, sizeof (dir)))
     return;
 
-  path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
+  /* The expected stack layout: HKEY component.  */
+  if (popstring (is_user_install, sizeof (is_user_install)))
+    return;
+
+  if (!strcmp(is_user_install, "1"))
+    {
+      root_key = ENV_HK_USER;
+      env_reg = ENV_REG_USER;
+    }
+  else
+    {
+      root_key = ENV_HK;
+      env_reg = ENV_REG;
+    }
+
+  path = read_w32_registry_string (root_key, env_reg, "Path");
+
+  if (!path)
+    return;
   /* Old path plus semicolon plus dir plus terminating nul.  */
   path_new_size = strlen (path) + 1;
   path_new = malloc (path_new_size);
   /* Old path plus semicolon plus dir plus terminating nul.  */
   path_new_size = strlen (path) + 1;
   path_new = malloc (path_new_size);
@@ -1126,7 +1162,7 @@ path_remove (HWND hwndParent, int string_size, char *variables,
     return;
 
   /* Set a key for our CLSID.  */
     return;
 
   /* Set a key for our CLSID.  */
-  RegCreateKey (ENV_HK, ENV_REG, &key_handle);
+  RegCreateKey (root_key, env_reg, &key_handle);
   RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
                 path_new, path_new_size);
   RegCloseKey (key_handle);
   RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
                 path_new, path_new_size);
   RegCloseKey (key_handle);
index 7716f7f..297ef06 100644 (file)
@@ -1,5 +1,6 @@
 # inst.nsi - Installer for GnuPG on Windows.      -*- coding: latin-1; -*-
 # Copyright (C) 2005, 2014 g10 Code GmbH
 # inst.nsi - Installer for GnuPG on Windows.      -*- coding: latin-1; -*-
 # Copyright (C) 2005, 2014 g10 Code GmbH
+#               2017 Intevation GmbH
 #
 # This file is part of GnuPG.
 #
 #
 # This file is part of GnuPG.
 #
@@ -42,7 +43,7 @@
 !define PRETTY_PACKAGE "GNU Privacy Guard"
 !define PRETTY_PACKAGE_SHORT "GnuPG"
 !define COMPANY "The GnuPG Project"
 !define PRETTY_PACKAGE "GNU Privacy Guard"
 !define PRETTY_PACKAGE_SHORT "GnuPG"
 !define COMPANY "The GnuPG Project"
-!define COPYRIGHT "Copyright (C) 2015 The GnuPG Project"
+!define COPYRIGHT "Copyright (C) 2017 The GnuPG Project"
 !define DESCRIPTION "GnuPG: The GNU Privacy Guard for Windows"
 
 !define INSTALL_DIR "GnuPG"
 !define DESCRIPTION "GnuPG: The GNU Privacy Guard for Windows"
 
 !define INSTALL_DIR "GnuPG"
@@ -80,9 +81,6 @@ SetCompressor lzma
 # SetCompressorDictSize 8
 !endif
 
 # SetCompressorDictSize 8
 !endif
 
-# Include the generic parts.
-!define HAVE_STARTMENU
-
 # We use the modern UI.
 !include "MUI.nsh"
 
 # We use the modern UI.
 !include "MUI.nsh"
 
@@ -90,6 +88,17 @@ SetCompressor lzma
 !include "LogicLib.nsh"
 !include "x64.nsh"
 
 !include "LogicLib.nsh"
 !include "x64.nsh"
 
+# We support user mode installation but prefer system wide
+!define MULTIUSER_EXECUTIONLEVEL Highest
+!define MULTIUSER_MUI
+!define MULTIUSER_INSTALLMODE_COMMANDLINE
+!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\${PACKAGE_SHORT}"
+!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
+!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\${PACKAGE_SHORT}"
+!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "Install Directory"
+!define MULTIUSER_INSTALLMODE_INSTDIR "${PACKAGE_SHORT}"
+!include "MultiUser.nsh"
+
 # Set the package name.  Note that this name should not be suffixed
 # with the version because this would get displayed in the start menu.
 # Given that a slash in the name troubles Windows startmenu creation
 # Set the package name.  Note that this name should not be suffixed
 # with the version because this would get displayed in the start menu.
 # Given that a slash in the name troubles Windows startmenu creation
@@ -109,9 +118,6 @@ OutFile "${NAME}-${VERSION}_${BUILD_DATESTR}.exe"
 !endif
 InstallDir "$PROGRAMFILES\${INSTALL_DIR}"
 
 !endif
 InstallDir "$PROGRAMFILES\${INSTALL_DIR}"
 
-InstallDirRegKey HKLM "Software\${PACKAGE_SHORT}" "Install Directory"
-
-
 # Add version information to the file properties.
 VIProductVersion "${PROD_VERSION}"
 VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
 # Add version information to the file properties.
 VIProductVersion "${PROD_VERSION}"
 VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
@@ -161,7 +167,7 @@ VIAddVersionKey "FileVersion" "${PROD_VERSION}"
 
 # We don't have MUI_PAGE_DIRECTORY
 
 
 # We don't have MUI_PAGE_DIRECTORY
 
-!ifdef HAVE_STARTMENU
+!ifdef WITH_GUI
 
 Page custom CustomPageOptions
 
 
 Page custom CustomPageOptions
 
@@ -169,7 +175,7 @@ Var STARTMENU_FOLDER
 
 !define MUI_PAGE_CUSTOMFUNCTION_PRE CheckIfStartMenuWanted
 !define MUI_STARTMENUPAGE_NODISABLE
 
 !define MUI_PAGE_CUSTOMFUNCTION_PRE CheckIfStartMenuWanted
 !define MUI_STARTMENUPAGE_NODISABLE
-!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
+!define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
 !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\GnuPG"
 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
 # We need to set the Startmenu name explicitly because a slash in the
 !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\GnuPG"
 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
 # We need to set the Startmenu name explicitly because a slash in the
@@ -354,6 +360,8 @@ FunctionEnd
 # OS version without the need for an Administrator is in use.  Print a
 # diagnostic if this is not the case and abort installation.
 Function PrintNonAdminWarning
 # OS version without the need for an Administrator is in use.  Print a
 # diagnostic if this is not the case and abort installation.
 Function PrintNonAdminWarning
+  Var /GLOBAL is_user_install
+  StrCpy $is_user_install "0"
   ClearErrors
   UserInfo::GetName
   IfErrors leave
   ClearErrors
   UserInfo::GetName
   IfErrors leave
@@ -361,9 +369,11 @@ Function PrintNonAdminWarning
   UserInfo::GetAccountType
   Pop $1
   StrCmp $1 "Admin" leave +1
   UserInfo::GetAccountType
   Pop $1
   StrCmp $1 "Admin" leave +1
-  MessageBox MB_OK "$(T_AdminNeeded)"
-  Quit
-
+  MessageBox MB_YESNO "$(T_AdminWanted)" IDNO exit
+  StrCpy $is_user_install "1"
+  goto leave
+ exit:
+    Quit
  leave:
 FunctionEnd
 
  leave:
 FunctionEnd
 
@@ -446,24 +456,30 @@ LangString T_FoundExistingVersion ${LANG_GERMAN} \
        eine neuere oder dieselbe Version handelt.)"
 LangString T_FoundExistingVersionB ${LANG_ENGLISH} \
      "A version of GnuPG has already been installed on the system. \
        eine neuere oder dieselbe Version handelt.)"
 LangString T_FoundExistingVersionB ${LANG_ENGLISH} \
      "A version of GnuPG has already been installed on the system. \
-      There will be no problem installing and thus overwriting this \
-      Version. $\r$\n\
+       $\r$\n\
        $\r$\n\
       Do you want to continue installing GnuPG?"
 LangString T_FoundExistingVersionB ${LANG_GERMAN} \
      "Eine Version von GnuPG ist hier bereits installiert. \
        $\r$\n\
       Do you want to continue installing GnuPG?"
 LangString T_FoundExistingVersionB ${LANG_GERMAN} \
      "Eine Version von GnuPG ist hier bereits installiert. \
-      Es ist problemlos möglich, die Installation fortzuführen.  $\r$\n\
+        $\r$\n\
         $\r$\n\
       Möchten die die Installation von GnuPG fortführen?"
 
 
 
 # From Function PrintNonAdminWarning
         $\r$\n\
       Möchten die die Installation von GnuPG fortführen?"
 
 
 
 # From Function PrintNonAdminWarning
-LangString T_AdminNeeded ${LANG_ENGLISH} \
-   "Warning: Administrator permissions required for a successful installation"
-LangString T_AdminNeeded ${LANG_GERMAN} \
-   "Achtung: Für eine erfolgreiche Installation werden \
-    Administratorrechte benötigt."
+LangString T_AdminWanted ${LANG_ENGLISH} \
+   "Warning: It is recommended to install GnuPG system-wide with \
+    administrator rights. \
+      $\r$\n\
+      $\r$\n\
+    Do you want to continue installing GnuPG without administrator rights?"
+LangString T_AdminWanted ${LANG_GERMAN} \
+   "Achtung: Es wird empfohlen GnuPG systemweit mit \
+    Administratorrechten zu installieren. \
+      $\r$\n\
+      $\r$\n\
+    Möchten die die Installation von GnuPG ohne Administratorrechte fortführen?"
 
 # From Function PrintCloseOtherApps
 LangString T_CloseOtherApps ${LANG_ENGLISH} \
 
 # From Function PrintCloseOtherApps
 LangString T_CloseOtherApps ${LANG_ENGLISH} \
@@ -505,7 +521,7 @@ FunctionEnd
 #        Input - head of the stack
 Function AddToPath
   Exch $0
 #        Input - head of the stack
 Function AddToPath
   Exch $0
-  g4wihelp::path_add "$0"
+  g4wihelp::path_add "$0" $is_user_install
   StrCmp $R5 "0" add_to_path_done
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
   add_to_path_done:
   StrCmp $R5 "0" add_to_path_done
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
   add_to_path_done:
@@ -516,8 +532,24 @@ FunctionEnd
 # RemoveFromPath - Remove a given dir from the path
 #     Input: head of the stack
 Function un.RemoveFromPath
 # RemoveFromPath - Remove a given dir from the path
 #     Input: head of the stack
 Function un.RemoveFromPath
+  ClearErrors
+  UserInfo::GetName
+  IfErrors remove_admin
+  Pop $0
+  UserInfo::GetAccountType
+  Pop $1
+  StrCmp $1 "Admin" remove_admin remove_user
+
+remove_admin:
+  Exch $0
+  g4wihelp::path_remove "$0" "0"
+  goto remove_done
+remove_user:
   Exch $0
   Exch $0
-  g4wihelp::path_remove "$0"
+  g4wihelp::path_remove "$0" "1"
+  goto remove_done
+
+remove_done:
   StrCmp $R5 "0" remove_from_path_done
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
   remove_from_path_done:
   StrCmp $R5 "0" remove_from_path_done
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
   remove_from_path_done:
@@ -540,7 +572,7 @@ Section "-gnupginst"
   FileWrite $0 "${VERSION}$\r$\n"
   FileClose $0
 
   FileWrite $0 "${VERSION}$\r$\n"
   FileClose $0
 
-  WriteRegStr HKLM "Software\GnuPG" "Install Directory" $INSTDIR
+  WriteRegStr SHCTX "Software\GnuPG" "Install Directory" $INSTDIR
 
   # If we are reinstalling, try to kill a possible running gpa using
   # an already installed gpa.
 
   # If we are reinstalling, try to kill a possible running gpa using
   # an already installed gpa.
@@ -1381,7 +1413,7 @@ Section "-un.gnupginst"
   RMDir "$INSTDIR"
 
   # Clean the registry.
   RMDir "$INSTDIR"
 
   # Clean the registry.
-  DeleteRegValue HKLM "Software\GNU\GnuPG" "Install Directory"
+  DeleteRegValue SHCTX "Software\GNU\GnuPG" "Install Directory"
 SectionEnd
 
 
 SectionEnd
 
 
@@ -1409,8 +1441,25 @@ Function .onInit
   !insertmacro MUI_INSTALLOPTIONS_EXTRACT "${W32_SRCDIR}/inst-options.ini"
 
   #Call CalcDepends
   !insertmacro MUI_INSTALLOPTIONS_EXTRACT "${W32_SRCDIR}/inst-options.ini"
 
   #Call CalcDepends
+
+  Var /GLOBAL changed_dir
+  # Check if the install directory was modified on the command line
+  StrCmp "$INSTDIR" "$PROGRAMFILES\${INSTALL_DIR}" unmodified 0
+  # It is modified. Save that value.
+  StrCpy $changed_dir "$INSTDIR"
+
+  # MULITUSER_INIT overwrites directory setting from command line
+  !insertmacro MULTIUSER_INIT
+  StrCpy $INSTDIR "$changed_dir"
+  goto initDone
+unmodified:
+  !insertmacro MULTIUSER_INIT
+initDone:
 FunctionEnd
 
 FunctionEnd
 
+Function "un.onInit"
+  !insertmacro MULTIUSER_UNINIT
+FunctionEnd
 
 #Function .onInstFailed
 #  Delete $TEMP\gpgspltmp.wav
 
 #Function .onInstFailed
 #  Delete $TEMP\gpgspltmp.wav
@@ -1439,13 +1488,6 @@ FunctionEnd
 !ifdef WITH_GUI
 Section "-startmenu"
 
 !ifdef WITH_GUI
 Section "-startmenu"
 
-!ifdef HAVE_STARTMENU
-  # Make sure that the context of the automatic variables has been set to
-  # the "all users" shell folder.  This guarantees that the menu gets written
-  # for all users.  We have already checked that we are running as Admin; or
-  # we printed a warning that installation will not succeed.
-  SetShellVarContext all
-
   # Check if the start menu entries where requested.
   !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
        "Field 2" "State"
   # Check if the start menu entries where requested.
   !insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
        "Field 2" "State"
@@ -1517,7 +1559,6 @@ no_gpa_quicklaunch:
 no_quick_launch:
 
 
 no_quick_launch:
 
 
-!endif
 SectionEnd
 !endif
 
 SectionEnd
 !endif
 
@@ -1533,30 +1574,23 @@ Section
 
   # Windows Add/Remove Programs support
   StrCpy $MYTMP "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
 
   # Windows Add/Remove Programs support
   StrCpy $MYTMP "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
-  WriteRegExpandStr HKLM $MYTMP "UninstallString" '"$INSTDIR\gnupg-uninstall.exe"'
-  WriteRegExpandStr HKLM $MYTMP "InstallLocation" "$INSTDIR"
-  WriteRegStr       HKLM $MYTMP "DisplayName"     "${PRETTY_PACKAGE}"
+  WriteRegExpandStr SHCTX $MYTMP "UninstallString" '"$INSTDIR\gnupg-uninstall.exe"'
+  WriteRegExpandStr SHCTX $MYTMP "InstallLocation" "$INSTDIR"
+  WriteRegStr       SHCTX $MYTMP "DisplayName"     "${PRETTY_PACKAGE}"
 !ifdef WITH_GUI
 !ifdef WITH_GUI
-  WriteRegStr       HKLM $MYTMP "DisplayIcon"     "$INSTDIR\bin\gpa.exe,0"
+  WriteRegStr       SHCTX $MYTMP "DisplayIcon"     "$INSTDIR\bin\gpa.exe,0"
+!else
+  WriteRegStr       SHCTX $MYTMP "DisplayIcon"     "$INSTDIR\bin\gpg.exe,0"
 !endif
 !endif
-  WriteRegStr       HKLM $MYTMP "DisplayVersion"  "${VERSION}"
-  WriteRegStr       HKLM $MYTMP "Publisher"       "The GnuPG Project"
-  WriteRegStr       HKLM $MYTMP "URLInfoAbout"    "https://gnupg.org"
-  WriteRegDWORD     HKLM $MYTMP "NoModify"        "1"
-  WriteRegDWORD     HKLM $MYTMP "NoRepair"        "1"
+  WriteRegStr       SHCTX $MYTMP "DisplayVersion"  "${VERSION}"
+  WriteRegStr       SHCTX $MYTMP "Publisher"       "The GnuPG Project"
+  WriteRegStr       SHCTX $MYTMP "URLInfoAbout"    "https://gnupg.org"
+  WriteRegDWORD     SHCTX $MYTMP "NoModify"        "1"
+  WriteRegDWORD     SHCTX $MYTMP "NoRepair"        "1"
 SectionEnd
 
 SectionEnd
 
-
 Section Uninstall
 Section Uninstall
-
 !ifdef WITH_GUI
 !ifdef WITH_GUI
-!ifdef HAVE_STARTMENU
-  # Make sure that the context of the automatic variables has been set to
-  # the "all users" shell folder.  This guarantees that the menu gets written
-  # for all users.  We have already checked that we are running as Admin; or
-  # we printed a warning that installation will not succeed.
-  SetShellVarContext all
-
   #---------------------------------------------------
   # Delete the menu entries and any empty parent menus
   #---------------------------------------------------
   #---------------------------------------------------
   # Delete the menu entries and any empty parent menus
   #---------------------------------------------------
@@ -1574,7 +1608,7 @@ Section Uninstall
     StrCmp $MYTMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
   startMenuDeleteLoopDone:
 
     StrCmp $MYTMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
   startMenuDeleteLoopDone:
 
-  DeleteRegValue HKLM "Software\GNU\GnuPG" "Start Menu Folder"
+  DeleteRegValue SHCTX "Software\GNU\GnuPG" "Start Menu Folder"
 
   # Delete Desktop links.
   Delete "$DESKTOP\GPA.lnk"
 
   # Delete Desktop links.
   Delete "$DESKTOP\GPA.lnk"
@@ -1587,14 +1621,13 @@ Section Uninstall
 no_quick_launch_uninstall:
 
 !endif
 no_quick_launch_uninstall:
 
 !endif
-!endif
 
   Delete "$INSTDIR\gnupg-uninstall.exe"
   RMDir "$INSTDIR"
 
   # Clean the registry.
 
   Delete "$INSTDIR\gnupg-uninstall.exe"
   RMDir "$INSTDIR"
 
   # Clean the registry.
-  DeleteRegValue HKLM "Software\GnuPG" "Install Directory"
-  DeleteRegKey /ifempty HKLM "Software\GnuPG"
+  DeleteRegValue SHCTX "Software\GnuPG" "Install Directory"
+  DeleteRegKey /ifempty SHCTX "Software\GnuPG"
   # Remove Windows Add/Remove Programs support.
   # Remove Windows Add/Remove Programs support.
-  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
+  DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
 SectionEnd
 SectionEnd