[Libreoffice-commits] core.git: setup_native/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Mon Feb 3 10:32:30 UTC 2020
setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx | 70 ++++++----
1 file changed, 46 insertions(+), 24 deletions(-)
New commits:
commit 916cbda310a43d46a0789fd8b2c8f15fb86b27b4
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Mon Feb 3 09:40:12 2020 +0300
Commit: Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Mon Feb 3 11:31:54 2020 +0100
tdf#130329: detect previous version's install location
Since component ids change across major versions, install location
isn't kept automatically for major upgrades. Use OLDPRODUCTS property
set during FindRelatedProducts action (see Upgrade table created by
solenv/bin/modules/installer/windows/upgrade.pm). Read InstallLocation
in existing MigrateInstallPath custom action under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\GUID, where
GUID is the value of OLDPRODUCTS.
This only reads registry hive for the current installer architecture
(32/64 bit), so that the other architecture installation path is not
taken into account when old version is of different architecture, to
avoid installing into wrong directory when e.g. upgrading from 32-bit
to 64-bit, so 64-bit program is not installed to Program Files (x86).
Change-Id: Ib9fa004818908a5706c5af040f1a5a36c03d2f36
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87844
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
diff --git a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
index 66bb99ae18e8..ad34bad8c744 100644
--- a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -19,46 +19,68 @@
#include "shlxtmsi.hxx"
#include <algorithm>
+#include <sstream>
#include <systools/win32/uwinapi.h>
-extern "C" __declspec(dllexport) UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
+extern "C" __declspec(dllexport) UINT __stdcall MigrateInstallPath(MSIHANDLE handle)
{
- WCHAR szValue[8192];
- DWORD nValueSize = sizeof(szValue); // yes, it is the number of bytes
- HKEY hKey;
- std::wstring sInstDir;
+ auto RegValue = [](HKEY hRoot, const WCHAR* sKey, const WCHAR* sVal) {
+ std::wstring sResult;
+
+ if (HKEY hKey; RegOpenKeyW(hRoot, sKey, &hKey) == ERROR_SUCCESS)
+ {
+ WCHAR buf[32767]; // max longpath
+ DWORD bufsize = sizeof(buf); // yes, it is the number of bytes
+ if (RegQueryValueExW(hKey, sVal, nullptr, nullptr, reinterpret_cast<LPBYTE>(buf),
+ &bufsize)
+ == ERROR_SUCCESS)
+ {
+ buf[std::min<size_t>(SAL_N_ELEMENTS(buf) - 1, bufsize / sizeof(*buf))] = 0;
+ sResult = buf;
+ }
+ RegCloseKey(hKey);
+ }
+
+ return sResult;
+ };
std::wstring sManufacturer = GetMsiPropertyW( handle, L"Manufacturer" );
std::wstring sDefinedName = GetMsiPropertyW( handle, L"DEFINEDPRODUCT" );
std::wstring sUpdateVersion = GetMsiPropertyW( handle, L"DEFINEDVERSION" );
std::wstring sUpgradeCode = GetMsiPropertyW( handle, L"UpgradeCode" );
- std::wstring sProductKey = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ std::wstring sKey = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
L"\\" + sUpdateVersion + L"\\" + sUpgradeCode;
- if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ if (auto sInstDir = RegValue(HKEY_CURRENT_USER, sKey.c_str(), L"INSTALLLOCATION");
+ !sInstDir.empty())
{
- if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
- {
- szValue[std::min(static_cast<unsigned int>(SAL_N_ELEMENTS(szValue) - 1), static_cast<unsigned int>(nValueSize / sizeof(*szValue)))] = 0;
- sInstDir = szValue;
- MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
- // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_CURRENT_USER", MB_OK );
- }
-
- RegCloseKey( hKey );
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_CURRENT_USER", MB_OK );
}
- else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ else if (auto sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"INSTALLLOCATION");
+ !sInstDir.empty())
{
- if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_LOCAL_MACHINE", MB_OK );
+ }
+ else if (std::wistringstream sOlds{ GetMsiPropertyW(handle, L"OLDPRODUCTS") }; !sOlds.eof())
+ {
+ std::wstring sOld;
+ bool bFound = false;
+ while (!bFound && std::getline(sOlds, sOld, L';'))
{
- szValue[std::min(static_cast<unsigned int>(SAL_N_ELEMENTS(szValue) - 1), static_cast<unsigned int>(nValueSize / sizeof(*szValue)))] = 0;
- sInstDir = szValue;
- MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
- // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_LOCAL_MACHINE", MB_OK );
+ if (sOld.empty())
+ continue;
+ sKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + sOld;
+ if (auto sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"InstallLocation");
+ !sInstDir.empty())
+ {
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in Uninstall", MB_OK );
+ bFound = true;
+ }
}
-
- RegCloseKey( hKey );
}
return ERROR_SUCCESS;
More information about the Libreoffice-commits
mailing list