/// <summary>
        /// The main entry point to the console application.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        /// <returns><code>0</code> if the application ran successfully with no errors, otherwise <code>1</code>.</returns>
        public static async Task <int> Main(string[] args)
        {
            var debug = IsDebug();

            if (debug)
            {
                Debugger.Launch();
            }

            // Parse command-line arguments
            if (!TryParseArguments(args, out (Dictionary <string, string> Options, FileInfo MSBuildExeFilePath, string EntryProjectFilePath, Dictionary <string, string> MSBuildGlobalProperties)arguments))
            {
                return(1);
            }

            // Enable MSBuild feature flags
            MSBuildFeatureFlags.MSBuildExeFilePath           = arguments.MSBuildExeFilePath.FullName;
            MSBuildFeatureFlags.EnableCacheFileEnumerations  = true;
            MSBuildFeatureFlags.LoadAllFilesAsReadonly       = true;
            MSBuildFeatureFlags.SkipEagerWildcardEvaluations = true;
#if NETFRAMEWORK
            if (AppDomain.CurrentDomain.IsDefaultAppDomain())
            {
                // MSBuild.exe.config has binding redirects that change from time to time and its very hard to make sure that NuGet.Build.Tasks.Console.exe.config is correct.
                // It also can be different per instance of Visual Studio so when running unit tests it always needs to match that instance of MSBuild
                // The code below runs this EXE in an AppDomain as if its MSBuild.exe so the assembly search location is next to MSBuild.exe and all binding redirects are used
                // allowing this process to evaluate MSBuild projects as if it is MSBuild.exe
                var thisAssembly = Assembly.GetExecutingAssembly();

                AppDomain appDomain = AppDomain.CreateDomain(
                    thisAssembly.FullName,
                    securityInfo: null,
                    info: new AppDomainSetup
                {
                    ApplicationBase   = arguments.MSBuildExeFilePath.DirectoryName,
                    ConfigurationFile = Path.Combine(arguments.MSBuildExeFilePath.DirectoryName, "MSBuild.exe.config")
                });

                return(appDomain
                       .ExecuteAssembly(
                           thisAssembly.Location,
                           args));
            }
#endif

            // Check whether the ask is to generate the restore graph file.
            if (MSBuildStaticGraphRestore.IsOptionTrue("GenerateRestoreGraphFile", arguments.Options))
            {
                using (var dependencyGraphSpecGenerator = new MSBuildStaticGraphRestore(debug: debug))
                {
                    return(dependencyGraphSpecGenerator.WriteDependencyGraphSpec(arguments.EntryProjectFilePath, arguments.MSBuildGlobalProperties, arguments.Options) ? 0 : 1);
                }
            }

            // Otherwise run restore!
            using (var dependencyGraphSpecGenerator = new MSBuildStaticGraphRestore(debug: debug))
            {
                return(await dependencyGraphSpecGenerator.RestoreAsync(arguments.EntryProjectFilePath, arguments.MSBuildGlobalProperties, arguments.Options) ? 0 : 1);
            }
        }
Exemple #2
0
        /// <summary>
        /// The main entry point to the console application.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        /// <returns><code>0</code> if the application ran successfully with no errors, otherwise <code>1</code>.</returns>
        public static async Task <int> Main(string[] args)
        {
            var debug = IsDebug();

            if (debug)
            {
#if IS_CORECLR
                System.Console.WriteLine("Waiting for debugger to attach to Process ID: {Process.GetCurrentProcess().Id}");

                while (!Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }

                Debugger.Break();
#else
                Debugger.Launch();
#endif
            }

            // Parse command-line arguments
            if (!TryParseArguments(args, out (Dictionary <string, string> Options, FileInfo MSBuildExeFilePath, string EntryProjectFilePath, Dictionary <string, string> MSBuildGlobalProperties)arguments))
            {
                return(1);
            }

            // Enable MSBuild feature flags
            MSBuildFeatureFlags.MSBuildExeFilePath           = arguments.MSBuildExeFilePath.FullName;
            MSBuildFeatureFlags.EnableCacheFileEnumerations  = true;
            MSBuildFeatureFlags.LoadAllFilesAsReadonly       = true;
            MSBuildFeatureFlags.SkipEagerWildcardEvaluations = true;

            // Only wire up an AssemblyResolve event handler if being debugged.
            if (debug)
            {
                // The App.config contains relative paths to MSBuild which won't work for locally built copies so an AssemblyResolve event
                // handler is used in order to locate the MSBuild assemblies
                string msbuildDirectory = arguments.MSBuildExeFilePath.DirectoryName;

                AppDomain.CurrentDomain.AssemblyResolve += (sender, resolveArgs) =>
                {
                    var assemblyName = new AssemblyName(resolveArgs.Name);

                    var path = Path.Combine(msbuildDirectory, $"{assemblyName.Name}.dll");

                    return(File.Exists(path) ? Assembly.LoadFrom(path) : null);
                };
            }

            using (var dependencyGraphSpecGenerator = new MSBuildStaticGraphRestore(debug: debug))
            {
                return(await dependencyGraphSpecGenerator.RestoreAsync(arguments.EntryProjectFilePath, arguments.MSBuildGlobalProperties, arguments.Options) ? 0 : 1);
            }
        }