// Based on MSBuild.exe's restore logic when using /restore. https://github.com/Microsoft/msbuild/blob/master/src/MSBuild/XMake.cs#L1242 private static BuildResult ExecuteRestore(ProjectInstance projectInstance, BuildManager buildManager) { const string UniqueProperty = "MSBuildRestoreSessionId"; // Set a property with a random value to ensure that restore happens under a different evaluation context // If the evaluation context is not different, then projects won't be re-evaluated after restore projectInstance.SetProperty(UniqueProperty, Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture)); // Create a new request with a Restore target only and specify: // - BuildRequestDataFlags.ClearCachesAfterBuild to ensure the projects will be reloaded from disk for subsequent builds // - BuildRequestDataFlags.SkipNonexistentTargets to ignore missing targets since Restore does not require that all targets exist // - BuildRequestDataFlags.IgnoreMissingEmptyAndInvalidImports to ignore imports that don't exist, are empty, or are invalid because restore might // make available an import that doesn't exist yet and the <Import /> might be missing a condition. var request = new BuildRequestData( projectInstance, targetsToBuild: RestoreTargets, hostServices: null, flags: BuildRequestDataFlags.ClearCachesAfterBuild | BuildRequestDataFlags.SkipNonexistentTargets | BuildRequestDataFlags.IgnoreMissingEmptyAndInvalidImports); var result = ExecuteBuild(buildManager, request); // Revert the property projectInstance.RemoveProperty(UniqueProperty); return(result); }