public UnrealPluginInstaller(Lifetime lifetime, ILogger logger, UnrealPluginDetector pluginDetector, PluginPathsProvider pathsProvider, ISolution solution, ISettingsStore settingsStore, UnrealHost unrealHost, NotificationsModel notificationsModel, RiderBackgroundTaskHost backgroundTaskHost) { Lifetime = lifetime; myLogger = logger; myPathsProvider = pathsProvider; mySolution = solution; myUnrealHost = unrealHost; myNotificationsModel = notificationsModel; myBackgroundTaskHost = backgroundTaskHost; myBoundSettingsStore = settingsStore.BindToContextLive(Lifetime, ContextRange.Smart(solution.ToDataContext())); myPluginDetector = pluginDetector; myPluginDetector.InstallInfoProperty.Change.Advise_NewNotNull(Lifetime, installInfo => { mySolution.Locks.ExecuteOrQueueReadLockEx(Lifetime, "UnrealPluginInstaller.CheckAllProjectsIfAutoInstallEnabled", () => { HandleAutoUpdatePlugin(installInfo.New); }); }); BindToInstallationSettingChange(); BindToNotificationFixAction(); }
private async Task <bool> InstallPlugin(Lifetime lifetime, UnrealPluginInstallInfo.InstallDescription installDescription, FileSystemPath uprojectFile, 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.6 * range; var REFRESH_STEP = 0.1 * range; var pluginRootFolder = installDescription.UnrealPluginRootFolder; var editorPluginPathFile = myPathsProvider.PathToPackedPlugin; var pluginTmpDir = FileSystemDefinition.CreateTemporaryDirectory(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 = FileSystemDefinition.CreateTemporaryDirectory(null, TMP_PREFIX); def.Lifetime.OnTermination(() => { pluginBuildOutput.Delete(); }); var buildProgress = progressProperty.Value; var isPluginBuilt = await BuildPlugin(lifetime, upluginFile, pluginBuildOutput, uprojectFile, 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); progressProperty.Value += REFRESH_STEP; 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); }); mySolution.Locks.ExecuteOrQueueReadLock(Lifetime, "UnrealLink.RegenerateProjectFiles", () => { var cppUe4SolutionDetector = mySolution.GetComponent <CppUE4SolutionDetector>(); if (cppUe4SolutionDetector.SupportRiderProjectModel != CppUE4ProjectModelSupportMode.UprojectOpened) { RegenerateProjectFiles(uprojectFile); } }); return(true); }