@@ -1192,9 +1192,9 @@ private static string BuildVibeshineInstallWarning(InstallerRunner.InstalledProd
11921192 : string . Empty ;
11931193
11941194 return "Vibeshine" + versionSuffix + " was detected on this PC.\n \n "
1195- + "Vibeshine does not carry over Vibeshine settings.\n "
1195+ + "Vibepollo does not carry over Vibeshine settings.\n "
11961196 + "If you intend to stay in the Sunshine ecosystem, Vibeshine is recommended instead.\n \n "
1197- + "If this is intentional, continue with Vibeshine .\n "
1197+ + "If this is intentional, continue with Vibepollo .\n "
11981198 + "Continuing will uninstall Vibeshine before installation." ;
11991199 }
12001200
@@ -1204,7 +1204,7 @@ private static string BuildApolloInstallWarning(InstallerRunner.InstalledProduct
12041204 : string . Empty ;
12051205
12061206 return "Apollo" + versionSuffix + " was detected on this PC.\n \n "
1207- + "Vibeshine replaces Apollo and cannot be installed while Apollo is installed.\n "
1207+ + "Vibepollo replaces Apollo and cannot be installed while Apollo is installed.\n "
12081208 + "Continuing will uninstall Apollo before installation.\n \n "
12091209 + "Click Uninstall Apollo to proceed." ;
12101210 }
@@ -1217,8 +1217,8 @@ private string BuildLegacySunshineMigrationWarning() {
12171217 versionSuffix = " (v" + _legacySunshineRegistration . DisplayVersion + ")" ;
12181218 }
12191219
1220- return "Sunshine" + versionSuffix + " was detected on this PC.\n \n "
1221- + "Vibeshine replaces Sunshine and will automatically uninstall Sunshine first, then install Vibeshine .\n "
1220+ return "Legacy Sunshine" + versionSuffix + " was detected on this PC.\n \n "
1221+ + "Vibepollo replaces Sunshine. The bootstrapper will uninstall Sunshine first, then start the installation .\n "
12221222 + "No settings will be lost during this migration.\n \n "
12231223 + "Click Uninstall Sunshine to proceed." ;
12241224 }
@@ -1230,7 +1230,7 @@ private string BuildLegacyApolloMigrationWarning() {
12301230 }
12311231
12321232 return "Legacy Apollo" + versionSuffix + " was detected on this PC.\n \n "
1233- + "Vibeshine replaces legacy Apollo and will automatically uninstall it first, then install Vibeshine .\n "
1233+ + "Vibepollo replaces legacy Apollo and will automatically uninstall it first, then install Vibepollo .\n "
12341234 + "No settings will be carried over.\n \n "
12351235 + "Click Uninstall Apollo to proceed." ;
12361236 }
@@ -2604,6 +2604,24 @@ public static InstallerResult RunInteractiveInstall(
26042604 return RunElevatedBootstrapperInstall ( arguments , installDirectory , installVirtualDisplayDriver , saveInstallLogs ) ;
26052605 }
26062606
2607+ var uninstallCompetingProductsResult = UninstallInstalledProducts (
2608+ "install_remove_competing" ,
2609+ true ,
2610+ false ,
2611+ false ,
2612+ false ,
2613+ false ,
2614+ new [ ] { InstalledProductKind . Apollo , InstalledProductKind . Vibepollo , InstalledProductKind . Sunshine } ) ;
2615+ var competingProductsRequireRestart = uninstallCompetingProductsResult . ExitCode == 3010 ;
2616+ if ( ! uninstallCompetingProductsResult . Succeeded ) {
2617+ return new InstallerResult {
2618+ Operation = InstallerOperation . Install ,
2619+ ExitCode = uninstallCompetingProductsResult . ExitCode ,
2620+ Message = BuildCompetingProductUninstallFailureMessage ( uninstallCompetingProductsResult . Message ) ,
2621+ LogPath = uninstallCompetingProductsResult . LogPath
2622+ } ;
2623+ }
2624+
26072625 var msiPath = ResolveMsiPath ( arguments . MsiPathOverride ) ;
26082626 var migrationCleanupResult = RunPreinstallMigrationCleanup ( "preinstall" , true , false ) ;
26092627 if ( migrationCleanupResult . ExitCode != 0 ) {
@@ -2625,13 +2643,17 @@ public static InstallerResult RunInteractiveInstall(
26252643 logPath ,
26262644 CreatePropertyArgument ( "INSTALL_ROOT" , installDirectory ) ,
26272645 "INSTALL_SUDOVDA=" + ( installVirtualDisplayDriver ? "1" : "0" ) ,
2646+ "SKIP_REMOVE_CONFLICTING_PRODUCTS=1" ,
26282647 "REBOOT=ReallySuppress" ,
26292648 "SUPPRESSMSGBOXES=1"
26302649 } ;
26312650 TryAppendSameProductReinstallProperties ( args , msiPath ) ;
26322651
26332652 var exitCode = RunMsiexec ( args , true , false ) ;
26342653 exitCode = RetryInstallWithSameProductReinstallIfNeeded ( exitCode , args , msiPath , true , false ) ;
2654+ if ( exitCode == 0 && competingProductsRequireRestart ) {
2655+ exitCode = 3010 ;
2656+ }
26352657 if ( exitCode != 0 && exitCode != 3010 ) {
26362658 TryRecoverServiceStateAfterFailedInstall ( ) ;
26372659 }
@@ -3037,13 +3059,41 @@ public static InstallerResult RunCli(InstallerArguments arguments) {
30373059 cliArgs . Add ( logPath ) ;
30383060 }
30393061
3062+ var uninstallCompetingProducts = ShouldPreUninstallCompetingProducts ( cliArgs ) ;
3063+ var competingProductsRequireRestart = false ;
3064+ if ( uninstallCompetingProducts ) {
3065+ var uninstallCompetingProductsResult = UninstallInstalledProducts (
3066+ "cli_remove_competing" ,
3067+ arguments . IsCliQuietMode ( ) ,
3068+ true ,
3069+ false ,
3070+ false ,
3071+ false ,
3072+ new [ ] { InstalledProductKind . Apollo , InstalledProductKind . Vibepollo , InstalledProductKind . Sunshine } ) ;
3073+ if ( ! uninstallCompetingProductsResult . Succeeded ) {
3074+ return new InstallerResult {
3075+ Operation = InstallerOperation . Install ,
3076+ ExitCode = uninstallCompetingProductsResult . ExitCode ,
3077+ Message = BuildCompetingProductUninstallFailureMessage ( uninstallCompetingProductsResult . Message ) ,
3078+ LogPath = uninstallCompetingProductsResult . LogPath
3079+ } ;
3080+ }
3081+ competingProductsRequireRestart = uninstallCompetingProductsResult . ExitCode == 3010 ;
3082+ }
3083+ if ( uninstallCompetingProducts && ! HasProperty ( cliArgs , "SKIP_REMOVE_CONFLICTING_PRODUCTS" ) ) {
3084+ cliArgs . Add ( "SKIP_REMOVE_CONFLICTING_PRODUCTS=1" ) ;
3085+ }
3086+
30403087 var exitCode = RunMsiexec ( cliArgs , arguments . IsCliQuietMode ( ) , true ) ;
30413088 exitCode = RetryInstallWithSameProductReinstallIfNeeded (
30423089 exitCode ,
30433090 cliArgs ,
30443091 installMsiPath ,
30453092 arguments . IsCliQuietMode ( ) ,
30463093 true ) ;
3094+ if ( exitCode == 0 && competingProductsRequireRestart ) {
3095+ exitCode = 3010 ;
3096+ }
30473097 if ( exitCode != 0 && exitCode != 3010 ) {
30483098 TryRecoverServiceStateAfterFailedInstall ( ) ;
30493099 }
@@ -3336,6 +3386,14 @@ private static bool IsServiceRunning(string serviceName) {
33363386 }
33373387 }
33383388
3389+ private static string BuildCompetingProductUninstallFailureMessage ( string uninstallMessage ) {
3390+ var prefix = "Failed to uninstall Apollo, Vibepollo, or Sunshine before starting Vibepollo installation." ;
3391+ if ( string . IsNullOrWhiteSpace ( uninstallMessage ) ) {
3392+ return prefix ;
3393+ }
3394+ return prefix + " " + uninstallMessage ;
3395+ }
3396+
33393397 private static InstallerResult UninstallInstalledProducts (
33403398 string logPhase ,
33413399 bool hiddenWindow ,
@@ -3645,6 +3703,17 @@ private static bool HasLogSwitch(List<string> args) {
36453703 string . Equals ( arg , "/log" , StringComparison . OrdinalIgnoreCase ) ) ;
36463704 }
36473705
3706+ private static bool ShouldPreUninstallCompetingProducts ( List < string > args ) {
3707+ var operation = args . FirstOrDefault ( IsOperationSwitch ) ;
3708+ if ( string . IsNullOrWhiteSpace ( operation ) ) {
3709+ return false ;
3710+ }
3711+
3712+ return string . Equals ( operation , "/i" , StringComparison . OrdinalIgnoreCase )
3713+ || string . Equals ( operation , "/package" , StringComparison . OrdinalIgnoreCase )
3714+ || string . Equals ( operation , "/a" , StringComparison . OrdinalIgnoreCase ) ;
3715+ }
3716+
36483717 private static string BuildLogPath ( string phase ) {
36493718 var timestamp = DateTime . UtcNow . ToString ( "yyyyMMdd_HHmmss" ) ;
36503719 return Path . Combine ( Path . GetTempPath ( ) , "vibeshine_" + phase + "_" + timestamp + ".log" ) ;
0 commit comments