/// <summary> /// Start MSBuild build submission /// </summary> /// If buildKind is ASYNC, this method starts the submission ane returns. uiThreadCallback will be called on UI thread once submissions completes. /// if buildKind is SYNC, this method executes the submission and runs uiThreadCallback /// <param name="buildKind">Is it a SYNC or ASYNC build</param> /// <param name="target">target to build</param> /// <param name="projectInstance">project instance to build; if null, this.BuildProject.CreateProjectInstance() is used to populate</param> /// <param name="uiThreadCallback">callback to be run UI thread </param> /// <returns></returns> internal virtual BuildSubmission DoMSBuildSubmission(BuildKind buildKind, string target, ref ProjectInstance projectInstance, MSBuildCoda uiThreadCallback) { UIThread.MustBeCalledFromUIThread(); bool designTime = BuildKind.SYNC == buildKind; //projectInstance = null; var accessor = (IVsBuildManagerAccessor)this.Site.GetService(typeof(SVsBuildManagerAccessor)); if (!TryBeginBuild(designTime)) { if (null != uiThreadCallback) { uiThreadCallback(MSBuildResult.Failed, projectInstance); } return null; } string[] targetsToBuild = new string[target != null ? 1 : 0]; if (target != null) { targetsToBuild[0] = target; } if (null == projectInstance) { projectInstance = BuildProject.CreateProjectInstance(); } projectInstance.SetProperty(GlobalProperty.VisualStudioStyleErrors.ToString(), "true"); projectInstance.SetProperty("UTFOutput", "true"); projectInstance.SetProperty(GlobalProperty.BuildingInsideVisualStudio.ToString(), "true"); this.BuildProject.ProjectCollection.HostServices.SetNodeAffinity(projectInstance.FullPath, NodeAffinity.InProc); BuildRequestData requestData = new BuildRequestData(projectInstance, targetsToBuild, this.BuildProject.ProjectCollection.HostServices, BuildRequestDataFlags.ReplaceExistingProjectInstance); BuildSubmission submission = BuildManager.DefaultBuildManager.PendBuildRequest(requestData); try { if (useProvidedLogger && buildLogger != null) { ErrorHandler.ThrowOnFailure(accessor.RegisterLogger(submission.SubmissionId, buildLogger)); } if (buildKind == BuildKind.ASYNC) { ProjectInstance projectInstanceCopy = projectInstance; submission.ExecuteAsync(sub => { UIThread.Run(() => { this.FlushBuildLoggerContent(); EndBuild(sub, designTime); uiThreadCallback((sub.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed, projectInstanceCopy); }); }, null); } else { submission.Execute(); EndBuild(submission, designTime); MSBuildResult msbuildResult = (submission.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed; if (uiThreadCallback != null) { uiThreadCallback(msbuildResult, projectInstance); } } } catch (Exception e) { Debug.Fail(e.ToString()); EndBuild(submission, designTime); if (uiThreadCallback != null) { uiThreadCallback(MSBuildResult.Failed, projectInstance); } throw; } return submission; }
/// <summary> /// Do the build asynchronously. /// </summary> /// <param name="vsopts"></param> /// <param name="configCanonicalName"></param> /// <param name="output"></param> /// <param name="target"></param> /// <param name="coda"></param> internal virtual void BuildAsync(uint vsopts, ConfigCanonicalName configCanonicalName, IVsOutputWindowPane output, string target, MSBuildCoda coda) { bool engineLogOnlyCritical = BuildPrelude(output); MSBuildCoda fullCoda = (res, instance) => { coda(res, instance); }; try { this.SetBuildConfigurationProperties(configCanonicalName); ProjectInstance ignoreMeToo = null; this.DoMSBuildSubmission(BuildKind.ASYNC, target, ref ignoreMeToo, fullCoda); } catch (Exception) { fullCoda(MSBuildResult.Failed, null); throw; } }