Exemplo n.º 1
0
        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);
            };
        }
Exemplo n.º 2
0
        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);
            };
        }