summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Reis <reis@janeasystems.com>2015-07-02 16:34:27 +0100
committerAlexis Campailla <alexis@janeasystems.com>2015-07-22 09:30:11 -0400
commit8e80528453aca0354422162e09c7c9f4700ddb1e (patch)
tree3c108cf9fc4118f9fba4c45caf895dca8dab8a92
parentb8d47a7b6f0ba70883ce5566f5c381a16eedb2a2 (diff)
downloadnode-8e80528453aca0354422162e09c7c9f4700ddb1e.tar.gz
win,msi: change InstallScope to perMachine
The MSI install scope was set to the WiX default, which is per-user. However, with UAC, it could not be installed by a standard user because InstallPrivileges is elevated by default, hence the install scope should be set to per-machine. Furthermore, the default install path is a per-machine location and setting the system path requires administrator privileges. By changing the InstallScope to perMachine, Start Menu shortcuts are placed in ProgramData and not the installing user's AppData folder, making the shortcuts available to other users. This also fixes the installation when AppData is a network folder. The custom action is necessary to allow upgrades. Since a per-machine MSI cannot upgrade an application installed per-user, the custom action checks if there is going to be an upgrade to a previous version installed per-user and sets the installation as per-user to allow upgrading. Hence, the advantages of installing per-machine will only apply in fresh installations. Fixes #5849 Fixes #7629 PR-URL: https://github.com/joyent/node/pull/25640 Reviewed-By: Alexis Campailla <alexis@janeasystems.com> Reviewed-By: Bert Belder <bertbelder@gmail.com>
-rw-r--r--tools/msvs/msi/custom_actions.c52
-rw-r--r--tools/msvs/msi/custom_actions.def3
-rwxr-xr-xtools/msvs/msi/product.wxs17
3 files changed, 67 insertions, 5 deletions
diff --git a/tools/msvs/msi/custom_actions.c b/tools/msvs/msi/custom_actions.c
index 5e7d617f3..bf36edc73 100644
--- a/tools/msvs/msi/custom_actions.c
+++ b/tools/msvs/msi/custom_actions.c
@@ -1,10 +1,60 @@
-
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#include <wcautil.h>
+#define GUID_BUFFER_SIZE 39 // {8-4-4-4-12}\0
+
+
+UINT WINAPI SetInstallScope(MSIHANDLE hInstall) {
+ HRESULT hr = S_OK;
+ UINT er = ERROR_SUCCESS;
+ TCHAR upgrade_code[GUID_BUFFER_SIZE];
+ DWORD upgrade_code_len = GUID_BUFFER_SIZE;
+ DWORD iProductIndex;
+ TCHAR product_code[GUID_BUFFER_SIZE];
+ TCHAR assignment_type[2];
+ DWORD assignment_type_len = 2;
+
+ hr = WcaInitialize(hInstall, "SetInstallScope");
+ ExitOnFailure(hr, "Failed to initialize");
+
+ er = MsiGetProperty(hInstall, TEXT("UpgradeCode"), upgrade_code,
+ &upgrade_code_len);
+ ExitOnWin32Error(er, hr, "Failed to get UpgradeCode property");
+
+ for (iProductIndex = 0;; iProductIndex++) {
+ er = MsiEnumRelatedProducts(upgrade_code, 0, iProductIndex, product_code);
+ if (er == ERROR_NO_MORE_ITEMS) break;
+ ExitOnWin32Error(er, hr, "Failed to get related product code");
+
+ er = MsiGetProductInfo(product_code, INSTALLPROPERTY_ASSIGNMENTTYPE,
+ assignment_type, &assignment_type_len);
+ ExitOnWin32Error(er, hr, "Failed to get the assignment type property "
+ "from related product");
+
+ // '0' = per-user; '1' = per-machine
+ if (assignment_type[0] == '0') {
+ /* When old versions which were installed as per-user are detected, the
+ * installation scope has to be set to per-user to be able to do an
+ * upgrade. If not, two versions will be installed side-by-side: one as
+ * per-user and the other as per-machine.
+ *
+ * If we wanted to disable backward compatibility, the installer should
+ * abort here, and request the previous version to be manually
+ * uninstalled before installing this one.
+ */
+ er = MsiSetProperty(hInstall, TEXT("ALLUSERS"), TEXT(""));
+ ExitOnWin32Error(er, hr, "Failed to set the install scope to per-user");
+ break;
+ }
+ }
+
+LExit:
+ return WcaFinalize(ERROR_SUCCESS);
+}
+
UINT WINAPI BroadcastEnvironmentUpdate(MSIHANDLE hInstall) {
HRESULT hr = S_OK;
diff --git a/tools/msvs/msi/custom_actions.def b/tools/msvs/msi/custom_actions.def
index 29e0933e3..5f6b25fc4 100644
--- a/tools/msvs/msi/custom_actions.def
+++ b/tools/msvs/msi/custom_actions.def
@@ -1,4 +1,5 @@
LIBRARY "custom_actions"
EXPORTS
-BroadcastEnvironmentUpdate \ No newline at end of file
+SetInstallScope
+BroadcastEnvironmentUpdate
diff --git a/tools/msvs/msi/product.wxs b/tools/msvs/msi/product.wxs
index 6ff0d4b14..2ce00a44b 100755
--- a/tools/msvs/msi/product.wxs
+++ b/tools/msvs/msi/product.wxs
@@ -18,7 +18,7 @@
Manufacturer="$(var.ProductAuthor)"
UpgradeCode="1d60944c-b9ce-4a71-a7c0-0384eb884baa">
- <Package InstallerVersion="200" Compressed="yes"/>
+ <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"/>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
@@ -249,16 +249,27 @@
</Component>
</DirectoryRef>
- <Binary Id='BroadcastEnvironmentUpdate'
+ <Binary Id='CustomActionsDLL'
SourceFile='$(var.custom_actions.TargetDir)$(var.custom_actions.TargetName).dll' />
+ <CustomAction Id="SetInstallScope"
+ BinaryKey="CustomActionsDLL"
+ DllEntry="SetInstallScope"
+ Execute="immediate"
+ Return="check" />
+
<CustomAction Id="BroadcastEnvironmentUpdate"
- BinaryKey="BroadcastEnvironmentUpdate"
+ BinaryKey="CustomActionsDLL"
DllEntry="BroadcastEnvironmentUpdate"
Execute="immediate"
Return="check" />
+ <InstallUISequence>
+ <Custom Action='SetInstallScope' Before='FindRelatedProducts'/>
+ </InstallUISequence>
+
<InstallExecuteSequence>
+ <Custom Action='SetInstallScope' Before='FindRelatedProducts'/>
<Custom Action='BroadcastEnvironmentUpdate' After='InstallFinalize'/>
</InstallExecuteSequence>