From 67fc9858046fb4015c1933335b54deedf4a620d3 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 7 Apr 2025 17:57:21 +0200 Subject: [PATCH 1/7] fix(msi): use standard replace mode for MSI installer shoudl enable replacing files during install happen only when needed instead of always will need to take care of migration from older releases Signed-off-by: Matthieu Gallien Signed-off-by: Jyrki Gadinger --- admin/win/msi/Nextcloud.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/win/msi/Nextcloud.wxs b/admin/win/msi/Nextcloud.wxs index 38ea1632a0eb2..a655c74cfe757 100644 --- a/admin/win/msi/Nextcloud.wxs +++ b/admin/win/msi/Nextcloud.wxs @@ -45,7 +45,7 @@ https://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/ --> - + From b9f57fd2546b546d6e17321f6d3a83dbca5c0e42 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Wed, 7 May 2025 16:07:37 +0200 Subject: [PATCH 2/7] fix(msi): do not completely remove the previous installation when updating The MSIs we distribute perform so-called "major upgrades". From the Microsoft docs, we learn that... > A typical major upgrade **removes a previous version** of an > application and installs a new version. Indeed that was the case -- the previous version is uninstalled completely before the new version gets installed. Since we install an extension that's loaded by explorer, the installer will ask the user to restart Windows Explorer during the uninstallation of the previous version (and restarting that might not always work as expected). There is a way to change this behaviour though, using Wix3's `MajorUpgrade` element. Through its `Schedule` property it's possible to define when the removal of the previous version should occur. The previous value `afterInstallInitialize` is one of two values that perform a complete uninstall/install sequence. The new value `afterInstallExecute` will install new files on top of the previous installation (depending on the `REINSTALLMODE` I guess) and remove older files that are not present. In the case of the extensions this means that the .dlls from the previous installation will not be touched, as long as the version embedded in the DLL info didn't change. This results in the installer no longer requesting Windows Explorer to restart, which is a big plus :D I also changed the REINSTALLMODE to `dmus` to allow downgrades as well. With this change, the request to restart Windows Explorer should hopefully happen only once an installation was made using an MSI that contains this change. Further updates will only request a restart if the DLL version of these extensions change... See also: - https://learn.microsoft.com/en-us/windows/win32/msi/major-upgrades - https://docs.firegiant.com/wix/schema/wxs/majorupgrade/#attributes:~:text=Schedule Signed-off-by: Jyrki Gadinger --- admin/win/msi/Nextcloud.wxs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/win/msi/Nextcloud.wxs b/admin/win/msi/Nextcloud.wxs index a655c74cfe757..3a9ddcdbee255 100644 --- a/admin/win/msi/Nextcloud.wxs +++ b/admin/win/msi/Nextcloud.wxs @@ -44,8 +44,8 @@ https://www.firegiant.com/wix/tutorial/upgrades-and-modularization/replacing-ourselves/ https://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/ --> - - + + From b7af3c70833f8104f11fa33fc50b0580853d24d6 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Thu, 8 May 2025 14:23:40 +0200 Subject: [PATCH 3/7] fix(msi): force termination of stuck processes Stopping the Windows Explorer process does not always work. Per default the MSI Restart Manager will display a warning message after a timeout, and not attempt to restart Explorer afterwards -- resulting in a black screen if no other window is open. Setting the property `MSIRMSHUTDOWN` to `1` will force the termination of the process when the timeout is reached, which finally allows the Explorer to be restarted. Signed-off-by: Jyrki Gadinger --- admin/win/msi/Nextcloud.wxs | 1 + 1 file changed, 1 insertion(+) diff --git a/admin/win/msi/Nextcloud.wxs b/admin/win/msi/Nextcloud.wxs index 3a9ddcdbee255..56acc7c6dca1c 100644 --- a/admin/win/msi/Nextcloud.wxs +++ b/admin/win/msi/Nextcloud.wxs @@ -46,6 +46,7 @@ --> + From 4a5e31d89d5dcdd073628e1f994e28d79f227af3 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Fri, 9 May 2025 15:07:25 +0200 Subject: [PATCH 4/7] feat(windows): use cmake to configure windows integration DLL version Signed-off-by: Matthieu Gallien --- shell_integration/windows/NCUtil/CMakeLists.txt | 3 ++- shell_integration/windows/NCUtil/{Version.h => Version.h.in} | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename shell_integration/windows/NCUtil/{Version.h => Version.h.in} (77%) diff --git a/shell_integration/windows/NCUtil/CMakeLists.txt b/shell_integration/windows/NCUtil/CMakeLists.txt index fa75e159380aa..1b5610253799e 100644 --- a/shell_integration/windows/NCUtil/CMakeLists.txt +++ b/shell_integration/windows/NCUtil/CMakeLists.txt @@ -7,5 +7,6 @@ add_library(NCUtil STATIC target_include_directories(NCUtil PUBLIC - "${CMAKE_CURRENT_SOURCE_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/shell_integration/windows/NCUtil/Version.h b/shell_integration/windows/NCUtil/Version.h.in similarity index 77% rename from shell_integration/windows/NCUtil/Version.h rename to shell_integration/windows/NCUtil/Version.h.in index 3651569191884..eb97edb912c53 100644 --- a/shell_integration/windows/NCUtil/Version.h +++ b/shell_integration/windows/NCUtil/Version.h.in @@ -2,10 +2,10 @@ // This is the number that will end up in the version window of the DLLs. // Increment this version before committing a new build if you are today's shell_integration build master. -#define NCEXT_BUILD_NUM 47 +#cmakedefine NCEXT_BUILD_NUM @NCEXT_BUILD_NUM@ #define STRINGIZE2(s) #s #define STRINGIZE(s) STRINGIZE2(s) -#define NCEXT_VERSION 3,0,0,NCEXT_BUILD_NUM +#cmakedefine NCEXT_VERSION @NCEXT_VERSION@ #define NCEXT_VERSION_STRING STRINGIZE(NCEXT_VERSION) From 9aff10a760e18cf37d1eb50d9dad7178c1ab93e7 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Fri, 9 May 2025 17:10:48 +0200 Subject: [PATCH 5/7] fix(windows): add missing version to cfapi shell integration DLL Signed-off-by: Matthieu Gallien --- src/libsync/vfs/cfapi/shellext/CMakeLists.txt | 3 + .../cfapi/shellext/CfApiShellIntegration.rc | 64 +++++++++++++++++++ .../CfApiShellIntegrationVersion.h.in | 14 ++++ 3 files changed, 81 insertions(+) create mode 100644 src/libsync/vfs/cfapi/shellext/CfApiShellIntegration.rc create mode 100644 src/libsync/vfs/cfapi/shellext/CfApiShellIntegrationVersion.h.in diff --git a/src/libsync/vfs/cfapi/shellext/CMakeLists.txt b/src/libsync/vfs/cfapi/shellext/CMakeLists.txt index e822afcc9a9c4..af6c74f3f382c 100644 --- a/src/libsync/vfs/cfapi/shellext/CMakeLists.txt +++ b/src/libsync/vfs/cfapi/shellext/CMakeLists.txt @@ -153,6 +153,8 @@ set(cppWinRtExe "${WindowsSDKBinPathForTools}\\cppwinrt.exe") message("cppWinRtExe: ${cppWinRtExe}") message("midlExe: ${midlExe}") +configure_file(CfApiShellIntegrationVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/CfApiShellIntegrationVersion.h) + # use midl.exe and cppwinrt.exe to generate files for CustomStateProvider (WinRT class) add_custom_command(OUTPUT ${MidlOutputPathHeader} COMMAND ${midlExe} /winrt /h nul /tlb ${MidlOutputPathTlb} /winmd ${MidlOutputPathWinmd} /metadata_dir "${WindowsSDKReferencesPath}\\Windows.Foundation.FoundationContract\\${WindowsFoundationContractVersion}" /nomidl /reference "${WindowsSDKReferencesPath}\\Windows.Foundation.FoundationContract\\${WindowsFoundationContractVersion}\\Windows.Foundation.FoundationContract.winmd" /reference "${WindowsSDKReferencesPath}\\Windows.Storage.Provider.CloudFilesContract\\${WindowsStorageProviderCloudFilesContractVersion}\\Windows.Storage.Provider.CloudFilesContract.winmd" /I ${MidleFileFolder} customstateprovider.idl @@ -170,6 +172,7 @@ add_library(CfApiShellExtensions MODULE ${CMAKE_SOURCE_DIR}/src/common/shellextensionutils.cpp customstateprovider.cpp CfApiShellIntegration.def + CfApiShellIntegration.rc ) message("CUSTOM_STATE_ICON_LOCKED_OUT: ${CUSTOM_STATE_ICON_LOCKED_OUT}") diff --git a/src/libsync/vfs/cfapi/shellext/CfApiShellIntegration.rc b/src/libsync/vfs/cfapi/shellext/CfApiShellIntegration.rc new file mode 100644 index 0000000000000..b6a3777370a08 --- /dev/null +++ b/src/libsync/vfs/cfapi/shellext/CfApiShellIntegration.rc @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-2.0-or-later + */ +// Microsoft Visual C++ generated resource script. +// +#include "CfApiShellIntegrationVersion.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION NCEXT_VERSION + PRODUCTVERSION NCEXT_VERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Nextcloud GmbH" + VALUE "FileDescription", "Nextcloud CfApi shell extension" + VALUE "FileVersion", NCEXT_VERSION_STRING + VALUE "InternalName", "NCOverlays" + VALUE "LegalCopyright", "Copyright (C) 2023 Nextcloud GmbH" + VALUE "ProductName", "Nextcloud shell extension" + VALUE "ProductVersion", NCEXT_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/libsync/vfs/cfapi/shellext/CfApiShellIntegrationVersion.h.in b/src/libsync/vfs/cfapi/shellext/CfApiShellIntegrationVersion.h.in new file mode 100644 index 0000000000000..30ce150ce4e11 --- /dev/null +++ b/src/libsync/vfs/cfapi/shellext/CfApiShellIntegrationVersion.h.in @@ -0,0 +1,14 @@ +#pragma once + +// SPDX-FileCopyrightText: 2016 ownCloud GmbH +// SPDX-License-Identifier: LGPL-2.1-or-later + +// This is the number that will end up in the version window of the DLLs. +// Increment this version before committing a new build if you are today's shell_integration build master. +#cmakedefine NCEXT_BUILD_NUM @NCEXT_BUILD_NUM@ + +#define STRINGIZE2(s) #s +#define STRINGIZE(s) STRINGIZE2(s) + +#cmakedefine NCEXT_VERSION @NCEXT_VERSION@ +#define NCEXT_VERSION_STRING STRINGIZE(NCEXT_VERSION) From be50bb499ad6acab2e6050e9917cc2c3eb7c4202 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Mon, 12 May 2025 12:39:48 +0200 Subject: [PATCH 6/7] feat(msi): do not schedule reboots ourselves let's have the MSI RestartManager take care of that Signed-off-by: Jyrki Gadinger [skip ci] --- admin/win/msi/Nextcloud.wxs | 3 --- 1 file changed, 3 deletions(-) diff --git a/admin/win/msi/Nextcloud.wxs b/admin/win/msi/Nextcloud.wxs index 56acc7c6dca1c..942275ad8b5fd 100644 --- a/admin/win/msi/Nextcloud.wxs +++ b/admin/win/msi/Nextcloud.wxs @@ -89,9 +89,6 @@ (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") - - - (SCHEDULE_REBOOT=1) OR NOT (UILevel=2) From 54653f6a3f232ee912d794824c42e2ab190fef94 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Fri, 30 May 2025 09:21:25 +0200 Subject: [PATCH 7/7] chore: add missing backport for VERSION.cmake Signed-off-by: Jyrki Gadinger --- VERSION.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VERSION.cmake b/VERSION.cmake index 1e56e674fcb44..90c1ad30fb63e 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -7,6 +7,8 @@ set(MIRALL_VERSION_PATCH 4) set(MIRALL_VERSION_YEAR 2025) set(MIRALL_SOVERSION 0) set(MIRALL_PREVERSION_HUMAN "3.16.4") # For preversions where PATCH>=50. Use version + alpha, rc1, rc2, etc. +set(NCEXT_BUILD_NUM 47) +set(NCEXT_VERSION 3,0,0,${NCEXT_BUILD_NUM}) # ------------------------------------ # Minimum supported server versions