Skip to content

Commit 6cb5465

Browse files
committed
feat: enhance application notifications and add about/help dialogs
1 parent 4103f35 commit 6cb5465

4 files changed

Lines changed: 571 additions & 56 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ keywords = ["simkl", "scrobbler"]
99
homepage = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl"
1010
repository = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl"
1111
classifiers = [
12-
"Development Status :: 4 - Beta",
12+
"Development Status :: 5 - Stable",
1313
"Intended Audience :: End Users/Desktop",
1414
"Operating System :: OS Independent",
1515
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",

setup.iss

Lines changed: 176 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#define MyAppName "Media Player Scrobbler for SIMKL"
2+
#define MyAppShortName "MPS for SIMKL"
23
#define MyAppPublisher "kavinthangavel"
34
#define MyAppURL "https://github.com/kavinthangavel/simkl-movie-tracker"
45
#define MyAppExeName "MPSS"
@@ -9,6 +10,7 @@
910
#define MyAppUpdateURL "https://github.com/kavinthangavel/simkl-movie-tracker/releases"
1011
#define MyAppReadmeURL "https://github.com/kavinthangavel/simkl-movie-tracker#readme"
1112
#define MyAppIssuesURL "https://github.com/kavinthangavel/simkl-movie-tracker/issues"
13+
#define MyLicense "GNU GPL v3"
1214

1315
[Setup]
1416
; NOTE: The value of AppId uniquely identifies this application.
@@ -22,11 +24,11 @@ AppPublisherURL={#MyAppURL}
2224
AppSupportURL={#MyAppIssuesURL}
2325
AppUpdatesURL={#MyAppUpdateURL}
2426
DefaultDirName={autopf}\{#MyAppName}
25-
DefaultGroupName={#MyAppName}
27+
DefaultGroupName={#MyAppShortName}
2628
AllowNoIcons=yes
27-
; Privilege level settings - allow user to choose
28-
PrivilegesRequired=admin
29-
PrivilegesRequiredOverridesAllowed=dialog
29+
; Privilege level settings - set to lowest for per-user installation
30+
; and allow the user to choose to run as admin if needed
31+
PrivilegesRequired=lowest
3032
; 64-bit only application
3133
ArchitecturesAllowed=x64compatible
3234
ArchitecturesInstallIn64BitMode=x64compatible
@@ -38,10 +40,12 @@ SetupIconFile=simkl_mps\assets\simkl-mps.ico
3840
Compression=lzma2/ultra64
3941
SolidCompression=yes
4042
; Uninstall settings
41-
UninstallDisplayIcon={app}\{#MyAppExeName}
42-
UninstallDisplayName={#MyAppName}
43-
; Modern UI
43+
UninstallDisplayIcon={app}\{#MyAppExeName}.exe
44+
UninstallDisplayName={#MyAppShortName}
45+
; Modern UI settings
4446
WizardStyle=modern
47+
WizardResizable=yes
48+
WizardSizePercent=120
4549
; This adds Windows 10/11 compatibility settings
4650
MinVersion=10.0.17763
4751
; App metadata
@@ -59,14 +63,35 @@ LicenseFile=LICENSE
5963
SetupMutex={#MyAppName}Setup
6064
AlwaysRestart=no
6165
RestartIfNeededByRun=yes
66+
DisableDirPage=auto
67+
DisableProgramGroupPage=auto
68+
UsedUserAreasWarning=no
6269

6370
[Languages]
6471
Name: "english"; MessagesFile: "compiler:Default.isl"
6572

73+
[Messages]
74+
WelcomeLabel1=Welcome to the [name] Setup Wizard
75+
WelcomeLabel2=This will install [name/ver] on your computer.%n%nMedia Player Scrobbler for SIMKL automatically tracks what you watch in your media players and updates your SIMKL.com account.%n%nIt is recommended that you close all other applications before continuing.
76+
FinishedHeadingLabel=Completing the [name] Setup Wizard
77+
FinishedLabel=Setup has finished installing [name] on your computer. The application may be launched by selecting the installed shortcuts.
78+
AboutSetupMenuItem=About [name]...
79+
AboutSetupTitle=About [name]
80+
AboutSetupMessage=[name] version [ver]%n[name] Media Player Scrobbler for SIMKL%n%nLicense: {#MyLicense}%n%nCopyright © kavinthangavel%n{#MyAppURL}
81+
82+
[CustomMessages]
83+
LaunchAppDesc=Start MPS for SIMKL after installation
84+
DesktopIconDesc=Create a desktop shortcut
85+
StartupIconDesc=Start automatically when Windows starts
86+
UpdateDesc=Schedule weekly update checks (recommended)
87+
AboutApp=About Media Player Scrobbler for SIMKL
88+
VersionInfo=Version: {#MyAppVersion}
89+
LicenseInfo=License: {#MyLicense}
90+
6691
[Tasks]
67-
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}";
68-
Name: "startupicon"; Description: "Start {#MyAppName} when Windows starts"; GroupDescription: "Windows Startup"
69-
Name: "scheduledupdate"; Description: "Schedule weekly update checks (recommended)"; GroupDescription: "Update Settings";
92+
Name: "desktopicon"; Description: "{cm:DesktopIconDesc}"; GroupDescription: "Shortcuts:"
93+
Name: "startupicon"; Description: "{cm:StartupIconDesc}"; GroupDescription: "Startup options:"
94+
Name: "scheduledupdate"; Description: "{cm:UpdateDesc}"; GroupDescription: "Update options:"
7095

7196
[Files]
7297
; Main executable
@@ -77,49 +102,73 @@ Source: "dist\MPS for Simkl.exe"; DestDir: "{app}"; Flags: ignoreversion signonc
77102
Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
78103
; Include updater script directly
79104
Source: "simkl_mps\utils\updater.ps1"; DestDir: "{app}"; Flags: ignoreversion
105+
; Create version file to help with About dialog
106+
Source: "LICENSE"; DestDir: "{app}"; Flags: ignoreversion
80107

81108
[Icons]
82-
; Start Menu entries
83-
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
84-
Name: "{group}\Start Media Scrobbler"; Filename: "{app}\{#MyAppExeName}"; Parameters: "start"
85-
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
86-
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
109+
; Start Menu entries - simplified to just have "Start Scrobbler"
110+
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "start"; Comment: "Start SIMKL scrobbler in the background"
111+
Name: "{group}\{cm:UninstallProgram,{#MyAppShortName}}"; Filename: "{uninstallexe}"
87112

88-
; Desktop icons (optional based on tasks)
89-
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon; Check: IsAdminInstallMode
90-
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon; Check: not IsAdminInstallMode
113+
; Desktop icon - simplified to just one "Start Scrobbler" icon
114+
Name: "{commondesktop}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "start"; Tasks: desktopicon; Check: IsAdminInstallMode; Comment: "Start SIMKL scrobbler in the background"
115+
Name: "{userdesktop}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "start"; Tasks: desktopicon; Check: not IsAdminInstallMode; Comment: "Start SIMKL scrobbler in the background"
91116

92-
; Startup entry (optional based on tasks)
93-
Name: "{userstartup}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "start"; Tasks: startupicon; Check: not IsAdminInstallMode
117+
; Startup entry - renamed to "MPS for Simkl.exe" with specific icon
118+
Name: "{userstartup}\{#MyAppShortName}"; Filename: "{app}\{#MyAppTrayName}"; Parameters: "start"; IconFilename: "{app}\{#MyAppTrayName}"; Tasks: startupicon; Check: not IsAdminInstallMode; Comment: "Start SIMKL scrobbler in the background"
119+
Name: "{commonstartup}\{#MyAppShortName}"; Filename: "{app}\{#MyAppTrayName}"; Parameters: "start"; IconFilename: "{app}\{#MyAppTrayName}"; Tasks: startupicon; Check: IsAdminInstallMode; Comment: "Start SIMKL scrobbler in the background"
94120

95121
[Run]
96122
; Options to run after installation
97-
Filename: "{app}\{#MyAppExeName}"; Description: "Start Media Scrobbler"; Parameters: "start"; Flags: nowait postinstall skipifsilent runascurrentuser
98-
Filename: "{#MyAppURL}"; Description: "Visit the project website"; Flags: postinstall shellexec skipifsilent
123+
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchAppDesc}"; Parameters: "start"; Flags: nowait postinstall skipifsilent runascurrentuser
124+
Filename: "{#MyAppURL}"; Description: "Visit website"; Flags: postinstall shellexec skipifsilent unchecked
99125

100126
[UninstallRun]
101-
; Stop any running processes before uninstall
102-
Filename: "taskkill.exe"; Parameters: "/F /IM ""{#MyAppExeName}"" /T"; Flags: runhidden skipifdoesntexist; RunOnceId: "KillMain"
103-
Filename: "taskkill.exe"; Parameters: "/F /IM ""{#MyAppTrayName}"" /T"; Flags: runhidden skipifdoesntexist; RunOnceId: "KillTray"
127+
; Improved process termination for uninstallation
128+
; First try to gracefully close the app
129+
Filename: "{app}\{#MyAppExeName}.exe"; Parameters: "exit"; Flags: runhidden skipifdoesntexist; RunOnceId: "GracefulExit"
130+
; Wait a moment before forcefully terminating
131+
Filename: "{sys}\cmd.exe"; Parameters: "/c timeout /t 2 /nobreak > nul"; Flags: runhidden; RunOnceId: "WaitForExit"
132+
; Forcefully terminate any remaining processes
133+
Filename: "taskkill.exe"; Parameters: "/F /IM ""{#MyAppExeName}.exe"" /T"; Flags: runhidden skipifdoesntexist; RunOnceId: "KillMain"
134+
Filename: "taskkill.exe"; Parameters: "/F /IM ""MPS for Simkl.exe"" /T"; Flags: runhidden skipifdoesntexist; RunOnceId: "KillTray"
135+
; Add a Windows PowerShell command to find and kill all related processes - fix curly braces escaping
136+
Filename: "powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Get-Process | Where-Object {{$_.Path -like '*{{app}}*'}} | Stop-Process -Force"""; Flags: runhidden skipifdoesntexist runascurrentuser; RunOnceId: "KillAllRelated"
137+
; Final wait to ensure processes have terminated
138+
Filename: "{sys}\cmd.exe"; Parameters: "/c timeout /t 1 /nobreak > nul"; Flags: runhidden; RunOnceId: "FinalWait"
104139

105140
[Registry]
141+
; Create a version information file for the about dialog
142+
Root: HKCU; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletekey
143+
Root: HKCU; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "License"; ValueData: "{#MyLicense}"; Flags: uninsdeletekey
144+
106145
; Custom app registration (for uninstall)
107146
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayIcon"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
108147
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayName"; ValueData: "{#MyAppName}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
109148
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayVersion"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
110149
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "Publisher"; ValueData: "{#MyAppPublisher}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
111150
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "URLInfoAbout"; ValueData: "{#MyAppURL}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
112151

152+
; Custom app registration for uninstall with explicit icon path
153+
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "UninstallString"; ValueData: """{uninstallexe}"""; Flags: uninsdeletekey; Check: IsAdminInstallMode
154+
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayIcon"; ValueData: "{app}\{#MyAppExeName}.exe"; Flags: uninsdeletekey; Check: IsAdminInstallMode
155+
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayName"; ValueData: "{#MyAppShortName}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
156+
113157
; User installation registry entries (non-admin installations)
114158
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayIcon"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
115159
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayName"; ValueData: "{#MyAppName}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
116160
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayVersion"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
117161
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "Publisher"; ValueData: "{#MyAppPublisher}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
118162
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "URLInfoAbout"; ValueData: "{#MyAppURL}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
119163

164+
; User installation registry entries with updated uninstaller name and icon
165+
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "UninstallString"; ValueData: """{uninstallexe}"""; Flags: uninsdeletekey; Check: not IsAdminInstallMode
166+
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayIcon"; ValueData: "{app}\{#MyAppExeName}.exe"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
167+
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "DisplayName"; ValueData: "{#MyAppShortName}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
168+
120169
; Auto-update settings
121-
Root: HKCU; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
122-
Root: HKCU; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
170+
Root: HKCU; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey
171+
Root: HKLM; Subkey: "Software\{#MyAppPublisher}\{#MyAppName}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey; Check: IsAdminInstallMode
123172

124173
; Add to Apps & Features list for non-admin installs (Windows 10+)
125174
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Uninstall\{{3FF84A4E-B9C2-4F49-A8DE-5F7EA15F5D88}_is1"; ValueType: string; ValueName: "InstallLocation"; ValueData: "{app}"; Flags: uninsdeletekey; Check: not IsAdminInstallMode
@@ -168,23 +217,120 @@ begin
168217
end;
169218
end;
170219
220+
// Create a version file with info for the app to use
221+
procedure CreateVersionFile;
222+
var
223+
VersionFilePath: String;
224+
VersionContents: String;
225+
begin
226+
VersionFilePath := ExpandConstant('{app}\version.txt');
227+
VersionContents := '{#MyAppVersion}';
228+
229+
if not SaveStringToFile(VersionFilePath, VersionContents, False) then
230+
Log('Failed to create version.txt file');
231+
end;
232+
171233
// Called after files are copied
172234
procedure CurStepChanged(CurStep: TSetupStep);
173235
begin
174236
if CurStep = ssPostInstall then
175237
begin
238+
// Create version file
239+
CreateVersionFile();
240+
241+
// Create scheduled task if selected
176242
if WizardIsTaskSelected('scheduledupdate') then
177243
CreateUpdateScheduledTask();
178244
end;
179245
end;
180246
181-
// Called when uninstalling
247+
// Enhanced cleanup during uninstallation
182248
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
249+
var
250+
ConfigDirs: array of String;
251+
i: Integer;
252+
CleanupAll: Boolean;
253+
UserProfileDir, AppDataDir, LocalAppDataDir: String;
183254
begin
184255
if CurUninstallStep = usPostUninstall then
185256
begin
257+
// Remove scheduled task
186258
RemoveUpdateScheduledTask();
187-
if SuppressibleMsgBox('Do you want to remove all user settings?', mbConfirmation, MB_YESNO, IDNO) = IDYES then
188-
DelTree(ExpandConstant('{localappdata}\' + CONFIG_FOLDER), True, True, True);
259+
260+
// Ask user about data removal
261+
CleanupAll := SuppressibleMsgBox('Do you want to remove all user settings, logs, and application data?',
262+
mbConfirmation, MB_YESNO, IDNO) = IDYES;
263+
264+
if CleanupAll then
265+
begin
266+
// Get reliable paths for Windows environment folders
267+
UserProfileDir := GetEnv('USERPROFILE');
268+
AppDataDir := GetEnv('APPDATA');
269+
LocalAppDataDir := GetEnv('LOCALAPPDATA');
270+
271+
// All possible config directories to check and remove - Windows specific
272+
SetArrayLength(ConfigDirs, 6);
273+
274+
// Primary location: C:\Users\username\kavinthangavel\simkl-mps
275+
ConfigDirs[0] := UserProfileDir + '\kavinthangavel\' + CONFIG_FOLDER;
276+
277+
// Other possible locations - using environment variables instead of constants
278+
ConfigDirs[1] := LocalAppDataDir + '\' + CONFIG_FOLDER;
279+
ConfigDirs[2] := AppDataDir + '\' + CONFIG_FOLDER;
280+
ConfigDirs[3] := UserProfileDir + '\' + CONFIG_FOLDER;
281+
ConfigDirs[4] := UserProfileDir + '\AppData\Local\' + CONFIG_FOLDER;
282+
ConfigDirs[5] := UserProfileDir + '\Documents\' + CONFIG_FOLDER;
283+
284+
// Log what directories we're checking
285+
Log('Looking for configuration directories to clean up...');
286+
287+
// Loop through all possible locations and delete them if they exist
288+
for i := 0 to GetArrayLength(ConfigDirs) - 1 do
289+
begin
290+
if DirExists(ConfigDirs[i]) then
291+
begin
292+
Log('Deleting configuration directory: ' + ConfigDirs[i]);
293+
if not DelTree(ConfigDirs[i], True, True, True) then
294+
begin
295+
Log('Failed to delete directory with DelTree: ' + ConfigDirs[i]);
296+
// Try CMD as fallback for difficult directories
297+
Exec('cmd.exe', '/c rd /s /q "' + ConfigDirs[i] + '"', '', SW_HIDE, ewWaitUntilTerminated, i);
298+
end;
299+
end else
300+
Log('Directory not found: ' + ConfigDirs[i]);
301+
end;
302+
303+
// Also clean registry entries
304+
RegDeleteKeyIncludingSubkeys(HKCU, 'Software\{#MyAppPublisher}\{#MyAppName}');
305+
if IsAdminInstallMode then
306+
RegDeleteKeyIncludingSubkeys(HKLM, 'Software\{#MyAppPublisher}\{#MyAppName}');
307+
end;
189308
end;
309+
end;
310+
311+
// Enhanced uninstall preparation
312+
function InitializeUninstall(): Boolean;
313+
var
314+
ResultCode: Integer;
315+
ProcessName: string;
316+
begin
317+
// Ensure all application processes are terminated before continuing
318+
ProcessName := ExtractFileName(ExpandConstant('{app}\{#MyAppExeName}.exe'));
319+
320+
// Try graceful exit first
321+
Exec(ExpandConstant('{app}\{#MyAppExeName}.exe'), 'exit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
322+
323+
// Wait briefly
324+
Sleep(1000);
325+
326+
// Forceful termination of any remaining processes
327+
Exec('taskkill.exe', '/F /IM "' + ProcessName + '" /T', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
328+
Sleep(500);
329+
330+
// Also try to terminate the tray application
331+
Exec('taskkill.exe', '/F /IM "MPS for Simkl.exe" /T', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
332+
Sleep(500);
333+
334+
// Success - let uninstallation proceed
335+
Result := True;
190336
end;

0 commit comments

Comments
 (0)