@@ -42,7 +42,6 @@ private enum ExecutionState : uint
4242
4343 public PreventLockApp ( )
4444 {
45- // Safe version initialization with null checks
4645 var version = Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ?? new Version ( 1 , 0 , 0 ) ;
4746 appVersion = $ "v{ version . Major } .{ version . Minor } .{ version . Build } ";
4847 versionFont = new Font ( "Segoe UI" , 8.25f , FontStyle . Italic ) ;
@@ -56,7 +55,6 @@ public PreventLockApp()
5655 settings = LoadSettings ( ) ;
5756 isRunning = true ;
5857
59- // Validate and fix startup path if needed (NEW)
6058 ValidateAndFixStartupPath ( ) ;
6159
6260 trayIcon = new NotifyIcon ( )
@@ -70,7 +68,6 @@ public PreventLockApp()
7068 new Thread ( WorkerThreadMethod ) { IsBackground = true } . Start ( ) ;
7169 }
7270
73- // NEW METHOD: Fixes startup path if executable was moved
7471 private void ValidateAndFixStartupPath ( )
7572 {
7673 try
@@ -92,7 +89,6 @@ private void ValidateAndFixStartupPath()
9289 catch { /* Silent failure is acceptable */ }
9390 }
9491
95- /* ALL OTHER METHODS REMAIN EXACTLY THE SAME AS YOUR ORIGINAL CODE */
9692 private AppSettings LoadSettings ( )
9793 {
9894 try
@@ -379,16 +375,174 @@ protected override void Dispose(bool disposing)
379375
380376 static class Program
381377 {
378+ private static Mutex ? _mutex ;
379+ private const string AppName = "Spotify Prevent Lock" ;
380+
382381 [ STAThread ]
383382 static void Main ( )
384383 {
385- Application . EnableVisualStyles ( ) ;
386- Application . SetCompatibleTextRenderingDefault ( false ) ;
387-
388- // Wait for system tray to initialize
389- Thread . Sleep ( 3000 ) ;
390-
391- Application . Run ( new PreventLockApp ( ) ) ;
384+ const string mutexName = "Global\\ SpotifyPreventLock" ;
385+ bool createdNew ;
386+ _mutex = new Mutex ( true , mutexName , out createdNew ) ;
387+
388+ if ( ! createdNew )
389+ {
390+ ShowRunningInstanceWarning ( ) ;
391+ return ;
392+ }
393+
394+ try
395+ {
396+ var versionCheck = CheckRunningVersions ( ) ;
397+ if ( versionCheck != VersionCheckResult . Continue )
398+ {
399+ if ( versionCheck == VersionCheckResult . Restart )
400+ {
401+ Thread . Sleep ( 500 ) ; // Brief pause before restart
402+ Process . Start ( new ProcessStartInfo
403+ {
404+ FileName = Application . ExecutablePath ,
405+ UseShellExecute = true
406+ } ) ;
407+ }
408+ return ;
409+ }
410+
411+ Application . EnableVisualStyles ( ) ;
412+ Application . SetCompatibleTextRenderingDefault ( false ) ;
413+ Application . Run ( new PreventLockApp ( ) ) ;
414+ }
415+ finally
416+ {
417+ _mutex ? . ReleaseMutex ( ) ;
418+ _mutex ? . Dispose ( ) ;
419+ }
420+ }
421+
422+ private enum VersionCheckResult
423+ {
424+ Continue ,
425+ Exit ,
426+ Restart
427+ }
428+
429+ private static void ShowRunningInstanceWarning ( )
430+ {
431+ MessageBox . Show (
432+ $ "{ AppName } is already running.\n \n " +
433+ "If updating version or exe file location.\n " +
434+ "Please exit old instance and rerun new version to update." ,
435+ "Application Running" ,
436+ MessageBoxButtons . OK ,
437+ MessageBoxIcon . Information ) ;
438+ }
439+
440+ private static VersionCheckResult CheckRunningVersions ( )
441+ {
442+ var currentProcess = Process . GetCurrentProcess ( ) ;
443+ var currentVersion = GetCurrentVersion ( ) ;
444+
445+ foreach ( var process in Process . GetProcessesByName ( currentProcess . ProcessName ) )
446+ {
447+ try
448+ {
449+ if ( process . Id == currentProcess . Id ) continue ;
450+
451+ var runningVersion = GetProcessVersion ( process ) ;
452+ if ( runningVersion == null ) continue ;
453+
454+ int comparison = runningVersion . CompareTo ( currentVersion ) ;
455+
456+ if ( comparison > 0 ) // Newer version running
457+ {
458+ MessageBox . Show (
459+ $ "A newer version (v{ runningVersion } ) is already running!\n \n " +
460+ $ "Please close this version (v{ currentVersion } ) and use the newer one.",
461+ "New Version Detected" ,
462+ MessageBoxButtons . OK ,
463+ MessageBoxIcon . Information ) ;
464+ return VersionCheckResult . Exit ;
465+ }
466+ else if ( comparison < 0 ) // Older version running
467+ {
468+ return HandleOlderVersion ( process , currentVersion , runningVersion ) ;
469+ }
470+ else // Same version running
471+ {
472+ return VersionCheckResult . Exit ;
473+ }
474+ }
475+ catch { /* Ignore inaccessible processes */ }
476+ }
477+ return VersionCheckResult . Continue ;
478+ }
479+
480+ private static Version GetCurrentVersion ( )
481+ {
482+ return Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version ?? new Version ( 1 , 0 , 0 ) ;
483+ }
484+
485+ private static Version ? GetProcessVersion ( Process process )
486+ {
487+ try
488+ {
489+ string ? path = process . MainModule ? . FileName ;
490+ if ( string . IsNullOrEmpty ( path ) ) return null ;
491+
492+ var versionInfo = FileVersionInfo . GetVersionInfo ( path ) ;
493+ return string . IsNullOrEmpty ( versionInfo . FileVersion )
494+ ? null
495+ : new Version ( versionInfo . FileVersion ) ;
496+ }
497+ catch
498+ {
499+ return null ;
500+ }
501+ }
502+
503+ private static VersionCheckResult HandleOlderVersion ( Process process , Version currentVersion , Version runningVersion )
504+ {
505+ var result = MessageBox . Show (
506+ $ "An older version (v{ runningVersion } ) is running.\n \n " +
507+ $ "Current version: v{ currentVersion } \n \n " +
508+ "Would you like to upgrade now?" ,
509+ "Upgrade Available" ,
510+ MessageBoxButtons . YesNo ,
511+ MessageBoxIcon . Question ) ;
512+
513+ if ( result != DialogResult . Yes ) return VersionCheckResult . Exit ;
514+
515+ try
516+ {
517+ // Try graceful shutdown first
518+ if ( ! process . CloseMainWindow ( ) )
519+ {
520+ process . Kill ( ) ;
521+ }
522+
523+ if ( ! process . WaitForExit ( 3000 ) )
524+ {
525+ MessageBox . Show (
526+ "Could not close the previous version.\n " +
527+ "Please close it manually and run the new version again." ,
528+ "Upgrade Warning" ,
529+ MessageBoxButtons . OK ,
530+ MessageBoxIcon . Warning ) ;
531+ return VersionCheckResult . Exit ;
532+ }
533+
534+ return VersionCheckResult . Restart ;
535+ }
536+ catch ( Exception ex )
537+ {
538+ MessageBox . Show (
539+ $ "Upgrade failed: { ex . Message } \n \n " +
540+ "Please close the old version manually and try again." ,
541+ "Upgrade Error" ,
542+ MessageBoxButtons . OK ,
543+ MessageBoxIcon . Error ) ;
544+ return VersionCheckResult . Exit ;
545+ }
392546 }
393547 }
394548}
0 commit comments