diff --git a/tools/msvs/msi/custom_actions.c b/tools/msvs/msi/custom_actions.c index 5e7d617f387915..bf36edc734ec1c 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 #include #include +#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 29e0933e379a78..5f6b25fc423492 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 6ff0d4b149b679..2ce00a44b1df03 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"> - + @@ -249,16 +249,27 @@ - + + + + + + +