private void BindToNotificationFixAction() { myUnrealHost.PerformModelAction(model => { model.InstallEditorPlugin.Advise(Lifetime, installPluginDescription => HandleManualInstallPlugin(installPluginDescription)); model.EnableAutoupdatePlugin.AdviseNotNull(Lifetime, unit => { myBoundSettingsStore.SetValue <UnrealLinkSettings, bool>(s => s.InstallRiderLinkPlugin, true); }); model.RefreshProjects.Advise(Lifetime, _ => UnrealProjectsRefresher.RefreshProjects(Lifetime, mySolution, myPluginDetector.InstallInfoProperty.Value)); }); }
private bool InstallPlugin(Lifetime lifetime, UnrealPluginInstallInfo.InstallDescription installDescription, VirtualFileSystemPath engineRoot, IProperty <double> progressProperty, double range) { using var def = new LifetimeDefinition(); var ZIP_STEP = 0.1 * range; var PATCH_STEP = 0.1 * range; var BUILD_STEP = 0.7 * range; var pluginRootFolder = installDescription.UnrealPluginRootFolder; var editorPluginPathFile = myPathsProvider.PathToPackedPlugin; var pluginTmpDir = VirtualFileSystemDefinition.CreateTemporaryDirectory(InteractionContext.SolutionContext, null, TMP_PREFIX); def.Lifetime.OnTermination(() => { pluginTmpDir.Delete(); }); try { ZipFile.ExtractToDirectory(editorPluginPathFile.FullPath, pluginTmpDir.FullPath); progressProperty.Value += ZIP_STEP; } catch (Exception exception) { myLogger.Warn(exception, $"[UnrealLink]: Couldn't extract {editorPluginPathFile} to {pluginTmpDir}"); const string unzipFailTitle = "Failed to unzip new RiderLink plugin"; var unzipFailText = $"Failed to unzip new version of RiderLink ({editorPluginPathFile.FullPath}) to user folder ({pluginTmpDir.FullPath})\n" + "Try restarting Rider in administrative mode"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(unzipFailTitle, ContentType.Error)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(unzipFailText, ContentType.Error)); return(false); } lifetime.ToCancellationToken().ThrowIfCancellationRequested(); var upluginFile = UnrealPluginDetector.GetPathToUpluginFile(pluginTmpDir); var pluginBuildOutput = VirtualFileSystemDefinition.CreateTemporaryDirectory(InteractionContext.SolutionContext, null, TMP_PREFIX); def.Lifetime.OnTermination(() => { pluginBuildOutput.Delete(); }); var buildProgress = progressProperty.Value; var isPluginBuilt = BuildPlugin(lifetime, upluginFile, pluginBuildOutput, engineRoot, value => progressProperty.SetValue(buildProgress + value * BUILD_STEP)); if (!isPluginBuilt) { myLogger.Warn($"Failed to build RiderLink for any available project"); const string failedBuildText = "Failed to build RiderLink plugin"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedBuildText, ContentType.Error)); return(false); } progressProperty.Value = buildProgress + BUILD_STEP; lifetime.ToCancellationToken().ThrowIfCancellationRequested(); if (!PatchUpluginFileAfterInstallation(pluginBuildOutput)) { const string failedToPatch = "Failed to patch RiderLink.uplugin"; var failedPatchText = "Failed to set `EnableByDefault` to true in RiderLink.uplugin\n" + "You need to manually enable RiderLink in UnrealEditor"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedToPatch, ContentType.Normal)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(failedPatchText, ContentType.Normal)); } progressProperty.Value += PATCH_STEP; lifetime.ToCancellationToken().ThrowIfCancellationRequested(); pluginRootFolder.CreateDirectory().DeleteChildren(); pluginBuildOutput.Copy(pluginRootFolder); installDescription.IsPluginAvailable = true; installDescription.PluginVersion = myPathsProvider.CurrentPluginVersion; const string title = "RiderLink plugin installed"; var text = $"RiderLink plugin was installed to: {pluginRootFolder}"; myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(title, ContentType.Normal)); myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(text, ContentType.Normal)); var notification = new NotificationModel(title, text, true, RdNotificationEntryType.INFO, new List <NotificationHyperlink>()); mySolution.Locks.ExecuteOrQueue(Lifetime, "UnrealLink.InstallPlugin", () => { myNotificationsModel.Notification(notification); }); var cppUe4SolutionDetector = mySolution.GetComponent <CppUE4SolutionDetector>(); bool isSln; using (mySolution.Locks.UsingReadLock()) { isSln = cppUe4SolutionDetector.SupportRiderProjectModel != CppUE4ProjectModelSupportMode.UprojectOpened; } if (isSln) { mySolution.Locks.ExecuteOrQueue(Lifetime, "Refresh projects after RiderLink installation", () => UnrealProjectsRefresher.RefreshProjects(Lifetime, mySolution, installDescription, engineRoot)); } else { var actionTitle = "Update VirtualFileSystem after RiderLink installation"; mySolution.Locks.Queue(Lifetime, actionTitle, () => { myLogger.Verbose(actionTitle); var fileSystemModel = mySolution.GetProtocolSolution().GetFileSystemModel(); fileSystemModel.RefreshPaths.Start(lifetime, new RdFsRefreshRequest(new List <string>() { pluginRootFolder.FullPath }, true)); }); } return(true); }