internal static void SetupNuGet(string packageName, string packageVersion) { // Make sure our nuget local store is added to nuget config var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string strideFolder = null; while (folder != null) { if (File.Exists(Path.Combine(folder, @"build\Stride.sln"))) { strideFolder = folder; var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null); Directory.CreateDirectory(Environment.ExpandEnvironmentVariables(DevSource)); CheckPackageSource(settings, "Stride Dev", NuGet.Configuration.Settings.ApplyEnvironmentTransform(DevSource)); settings.SaveToDisk(); break; } folder = Path.GetDirectoryName(folder); } // Note: we perform nuget restore inside the assembly resolver rather than top level module ctor (otherwise it freezes) AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => { // Check if already loaded. // Somehow it happens for Microsoft.NET.Build.Tasks -> NuGet.ProjectModel, probably due to the specific way it's loaded. var matchingAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName == eventArgs.Name); if (matchingAssembly != null) { return(matchingAssembly); } if (!assembliesResolved) { lock (assembliesLock) { // Note: using NuGet will try to recursively resolve NuGet.*.resources.dll, so set assembliesResolved right away so that it bypasses everything assembliesResolved = true; var logger = new Logger(); #if STRIDE_NUGET_RESOLVER_UX var dialogNotNeeded = new TaskCompletionSource <bool>(); var dialogClosed = new TaskCompletionSource <bool>(); // Display splash screen after a 500 msec (when NuGet takes some time to restore) var newWindowThread = new Thread(() => { Thread.Sleep(500); if (!dialogNotNeeded.Task.IsCompleted) { var splashScreen = new Stride.NuGetResolver.SplashScreenWindow(); splashScreen.Show(); // Register log logger.SetupLogAction((level, message) => { splashScreen.Dispatcher.InvokeAsync(() => { splashScreen.AppendMessage(level, message); }); }); dialogNotNeeded.Task.ContinueWith(t => { splashScreen.Dispatcher.Invoke(() => splashScreen.Close()); }); splashScreen.Closed += (sender2, e2) => splashScreen.Dispatcher.InvokeShutdown(); System.Windows.Threading.Dispatcher.Run(); splashScreen.Close(); } dialogClosed.SetResult(true); }); newWindowThread.SetApartmentState(ApartmentState.STA); newWindowThread.IsBackground = true; newWindowThread.Start(); #endif var previousSynchronizationContext = SynchronizationContext.Current; try { // Since we execute restore synchronously, we don't want any surprise concerning synchronization context (i.e. Avalonia one doesn't work with this) SynchronizationContext.SetSynchronizationContext(null); // Determine current TFM var framework = Assembly .GetEntryAssembly()? .GetCustomAttribute <TargetFrameworkAttribute>()? .FrameworkName ?? ".NETFramework,Version=v4.7.2"; var nugetFramework = NuGetFramework.ParseFrameworkName(framework, DefaultFrameworkNameProvider.Instance); #if NETCOREAPP // Add TargetPlatform to net6.0 TFM (i.e. net6.0 to net6.0-windows7.0) var platform = Assembly.GetEntryAssembly()?.GetCustomAttribute <TargetPlatformAttribute>()?.PlatformName ?? string.Empty; if (framework.StartsWith(FrameworkConstants.FrameworkIdentifiers.NetCoreApp) && platform != string.Empty) { var platformParseResult = Regex.Match(platform, @"([a-zA-Z]+)(\d+.*)"); if (platformParseResult.Success && Version.TryParse(platformParseResult.Groups[2].Value, out var platformVersion)) { var platformName = platformParseResult.Groups[1].Value; nugetFramework = new NuGetFramework(nugetFramework.Framework, nugetFramework.Version, platformName, platformVersion); } } #endif // Only allow this specific version var versionRange = new VersionRange(new NuGetVersion(packageVersion), true, new NuGetVersion(packageVersion), true); var(request, result) = RestoreHelper.Restore(logger, nugetFramework, "win", packageName, versionRange); if (!result.Success) { throw new InvalidOperationException($"Could not restore NuGet packages"); } assemblies = RestoreHelper.ListAssemblies(result.LockFile); } catch (Exception e) { #if STRIDE_NUGET_RESOLVER_UX logger.LogError($@"Error restoring NuGet packages: {e}"); dialogClosed.Task.Wait(); #else // Display log in console var logText = $@"Error restoring NuGet packages! ==== Exception details ==== {e} ==== Log ==== {string.Join(Environment.NewLine, logger.Logs.Select(x => $"[{x.Level}] {x.Message}"))} "; Console.WriteLine(logText); #endif Environment.Exit(1); } finally { #if STRIDE_NUGET_RESOLVER_UX dialogNotNeeded.TrySetResult(true); #endif SynchronizationContext.SetSynchronizationContext(previousSynchronizationContext); } } } if (assemblies != null) { var aname = new AssemblyName(eventArgs.Name); if (aname.Name.StartsWith("Microsoft.Build") && aname.Name != "Microsoft.Build.Locator") { return(null); } var assemblyPath = assemblies.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == aname.Name); if (assemblyPath != null) { return(Assembly.LoadFrom(assemblyPath)); } } return(null); }; }
internal static void SetupNuGet(string packageName, string packageVersion) { // Make sure our nuget local store is added to nuget config var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string strideFolder = null; while (folder != null) { if (File.Exists(Path.Combine(folder, @"build\Stride.sln"))) { strideFolder = folder; var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null); Directory.CreateDirectory(Environment.ExpandEnvironmentVariables(DevSource)); CheckPackageSource(settings, "Stride Dev", NuGet.Configuration.Settings.ApplyEnvironmentTransform(DevSource)); settings.SaveToDisk(); break; } folder = Path.GetDirectoryName(folder); } // Note: we perform nuget restore inside the assembly resolver rather than top level module ctor (otherwise it freezes) AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => { // Check if already loaded. // Somehow it happens for Microsoft.NET.Build.Tasks -> NuGet.ProjectModel, probably due to the specific way it's loaded. var matchingAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName == eventArgs.Name); if (matchingAssembly != null) { return(matchingAssembly); } if (!assembliesResolved) { lock (assembliesLock) { // Note: using NuGet will try to recursively resolve NuGet.*.resources.dll, so set assembliesResolved right away so that it bypasses everything assembliesResolved = true; var logger = new Logger(); var previousSynchronizationContext = SynchronizationContext.Current; try { // Since we execute restore synchronously, we don't want any surprise concerning synchronization context (i.e. Avalonia one doesn't work with this) SynchronizationContext.SetSynchronizationContext(null); // Determine current TFM var framework = Assembly .GetEntryAssembly()? .GetCustomAttribute <TargetFrameworkAttribute>()? .FrameworkName ?? ".NETFramework,Version=v4.7.2"; var nugetFramework = NuGetFramework.ParseFrameworkName(framework, DefaultFrameworkNameProvider.Instance); // Only allow this specific version var versionRange = new VersionRange(new NuGetVersion(packageVersion), true, new NuGetVersion(packageVersion), true); var(request, result) = RestoreHelper.Restore(logger, nugetFramework, "win", packageName, versionRange); if (!result.Success) { throw new InvalidOperationException($"Could not restore NuGet packages"); } assemblies = RestoreHelper.ListAssemblies(result.LockFile); } catch (Exception e) { var logFile = Path.GetTempPath() + Guid.NewGuid().ToString() + ".txt"; var logText = $@"Error restoring NuGet packages! ==== Exception details ==== {e} ==== Log ==== {string.Join(Environment.NewLine, logger.Logs.Select(x => $"[{x.Level}] {x.Message}"))} "; File.WriteAllText(logFile, logText); #if STRIDE_NUGET_RESOLVER_UX // Write log to file System.Windows.Forms.MessageBox.Show($"{e.Message}{Environment.NewLine}{Environment.NewLine}Please see details in {logFile} (which will be automatically opened)", "Error restoring NuGet packages"); Process.Start(logFile); #else // Display log in console Console.WriteLine(logText); #endif Environment.Exit(1); } finally { SynchronizationContext.SetSynchronizationContext(previousSynchronizationContext); } } } if (assemblies != null) { var aname = new AssemblyName(eventArgs.Name); if (aname.Name.StartsWith("Microsoft.Build") && aname.Name != "Microsoft.Build.Locator") { return(null); } var assemblyPath = assemblies.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == aname.Name); if (assemblyPath != null) { return(Assembly.LoadFrom(assemblyPath)); } } return(null); }; }