in src/dotnet/RiderPlugin.UnrealLink/PluginInstaller/UnrealPluginInstaller.cs [369:480]
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 = CreateTempDirectory();
if (pluginTmpDir.IsNullOrEmpty()) return false;
if (PlatformUtil.RuntimePlatform == JetPlatform.Windows && pluginTmpDir.FullPath.Any(c => c >= 128))
{
string nonAsciiCharactersText = Strings.NonASCIICharactersInTheBuildDirectory_Text;
myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(nonAsciiCharactersText, ContentType.Error));
}
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 = CreateTempDirectory();
if (pluginBuildOutput.IsNullOrEmpty()) return false;
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.Error($"Failed to build RiderLink for any available project");
myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(Strings.FailedToBuildRiderLinkPlugin_Text, ContentType.Error));
return false;
}
progressProperty.Value = buildProgress + BUILD_STEP;
lifetime.ToCancellationToken().ThrowIfCancellationRequested();
if (!PatchUpluginFileAfterInstallation(pluginBuildOutput))
{
var failedToPatch = Strings.FailedToPatchRiderLinkUplugin_Text;
var failedPatchText = Strings.FailedToPatchRiderLinkUplugin_Message;
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.PluginChecksum = myPathsProvider.CurrentPluginChecksum;
var title = Strings.RiderLinkPluginInstalled_Title;
var text = Strings.RiderLinkPluginInstalled_Message.Format(pluginRootFolder);
myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(title, ContentType.Normal));
myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(text, ContentType.Normal));
var notification = new NotificationModel(mySolution.GetRdProjectId(), title, text, true,
RdNotificationEntryType.INFO, new List<NotificationHyperlink>());
mySolution.Locks.ExecuteOrQueue(Lifetime, "UnrealLink.InstallPlugin",
() => { myNotificationsModel.Notification(notification); });
var cppUe4SolutionDetector = mySolution.GetComponent<ICppUE4SolutionDetector>();
var isSln = cppUe4SolutionDetector.SupportRiderProjectModel != CppUE4ProjectModelSupportMode.UprojectOpened;
if (isSln)
{
var refreshText = Strings.RefreshingProjectFiles_Text;
myUnrealHost.myModel.RiderLinkInstallMessage(new InstallMessage(refreshText, ContentType.Normal));
mySolution.Locks.ExecuteOrQueue(Lifetime, Strings.RefreshProjectsAfterRiderLinkInstallation_Text, () =>
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<RdPath>() { pluginRootFolder.ToRd() }, true));
});
}
return true;
}