Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changes/6.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Release date: `2026-xx-xx`
- [NXDRIVE-3108](https://hyland.atlassian.net/browse/NXDRIVE-3108): Fix MacOS release version checking on Github
- [NXDRIVE-3110](https://hyland.atlassian.net/browse/NXDRIVE-3110): Update timeout on macOS
- [NXDRIVE-3122](https://hyland.atlassian.net/browse/NXDRIVE-3122): Fix upgrade issue from 5.4.0 to latest
- [NXDRIVE-3133](https://hyland.atlassian.net/browse/NXDRIVE-3133): End the running Drive task before attempting to install

## Security

Expand Down
52 changes: 35 additions & 17 deletions tools/windows/setup-common.iss
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,19 @@ WizardStyle=modern
Compression=lzma
SolidCompression=yes

; Controls which files Setup will check for being in use before upgrading
CloseApplicationsFilter=*.*
; Disable the "close applications" prompt. The PrepareToInstall function
; already handles killing ndrive.exe before installation proceeds.
CloseApplications=no

; Minimum Windows version required (Windows 8)
MinVersion=6.2.9200


[InstallDelete]
; This is required to handle upgrades from 5.4.0 (PyInstaller 5.0) which had different
; Qt DLL structure. Without this, orphaned 32-bit DLLs from 5.4.0 can cause
; "DLL load failed while importing QtCore: %1 is not a valid Win32 application" errors.
Type: filesandordirs; Name: "{app}\PyQt5"
Type: files; Name: "{app}\Qt*.dll"
Type: files; Name: "{app}\qt*.dll"
Type: files; Name: "{app}\python*.dll"
Type: files; Name: "{app}\vcruntime*.dll"
Type: files; Name: "{app}\msvcp*.dll"
Type: files; Name: "{app}\api-ms-*.dll"
Type: files; Name: "{app}\ucrtbase.dll"
Type: files; Name: "{app}\libcrypto*.dll"
Type: files; Name: "{app}\libssl*.dll"
Type: files; Name: "{app}\libffi*.dll"
Type: files; Name: "{app}\sqlite3.dll"
; Delete everything inside the installation directory before installing new files.
; This ensures no orphaned files from previous versions cause conflicts (e.g.,
; "DLL load failed while importing QtCore" errors due to stale DLLs).
Type: filesandordirs; Name: "{app}\*"


[UninstallDelete]
Expand Down Expand Up @@ -131,3 +121,31 @@ begin
if (Length(url) > 0) and (Length(username) > 0) then
Result := True;
end;

function IsProcessRunning(const ProcessName: String): Boolean;
// Check if a process is currently running using tasklist.
var
ResultCode: Integer;
begin
Exec('cmd', '/C tasklist /FI "IMAGENAME eq ' + ProcessName + '" | find /I "' + ProcessName + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
Result := (ResultCode = 0);
end;

function PrepareToInstall(var NeedsRestart: Boolean): String;
// Kill ndrive.exe if it is running before proceeding with the installation.
// If automatic kill fails, ask user to manually kill Nuxeo Drive
var
ResultCode: Integer;
begin
Result := '';

if not IsProcessRunning('{#MyAppExeName}') then
Exit; // Force-kill the process

Exec('taskkill', '/F /IM {#MyAppExeName}', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
Comment on lines +143 to +145
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic in this function is inverted. The comment says "Force-kill the process" but it actually exits early when the process is NOT running. This means when the process IS running (line 142 evaluates to false), the code continues to lines 145-150 to kill it. However, the comment placement makes it confusing and suggests incorrect logic. The early exit should occur when the process is already stopped (not running), which is the correct behavior but the comment is misleading.

Suggested change
Exit; // Force-kill the process
Exec('taskkill', '/F /IM {#MyAppExeName}', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
Exit; // Process is not running; nothing to do
Exec('taskkill', '/F /IM {#MyAppExeName}', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); // Force-kill the process

Copilot uses AI. Check for mistakes.
Sleep(2000);

// If the process is still running, ask the user to close it manually
if IsProcessRunning('{#MyAppExeName}') then
Result := '{#MyAppName} is still running and could not be stopped automatically.' + #13#10 + 'Please close {#MyAppName} manually and try again.';
end;