public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) { // Only check this project if the solution is opened and we haven't already warned at the maximum level. Note that fAdded // is true for both add and a reload of an unloaded project if (SolutionOpen && fAdded == 1 && CompatibilityLevelWarnedForCurrentSolution != CompatibilityLevel.NotSupported) { UnconfiguredProject? project = pHierarchy.AsUnconfiguredProject(); if (project != null) { _threadHandling.Value.RunAndForget(async () => { // Run on the background await TaskScheduler.Default; VersionCompatibilityData compatData = GetVersionCompatibilityData(); // We need to check if this project has been newly created. Our projects will implement IProjectCreationState -we can // skip any that don't if (IsNewlyCreated(project)) { bool isPreviewSDKInUse = await IsPreviewSDKInUseAsync(); CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatData, isPreviewSDKInUse); if (compatLevel != CompatibilityLevel.Recommended) { await WarnUserOfIncompatibleProjectAsync(compatLevel, compatData, isPreviewSDKInUse); } } }, unconfiguredProject: null); } } return HResult.OK; }
public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) { // Only check this project if the solution is opened and we haven't already warned at the maximum level. Note that fAdded // is true for both add and a reload of an unloaded project if (_solutionOpened && fAdded == 1 && _compatibilityLevelWarnedForThisSolution != CompatibilityLevel.NotSupported) { UnconfiguredProject project = pHierarchy.AsUnconfiguredProject(); if (project != null) { _threadHandling.Value.JoinableTaskFactory.RunAsync(async() => { // Run on the background await TaskScheduler.Default; VersionCompatibilityData compatData = GetVersionCmpatibilityData(); // We need to check if this project has been newly created. Our projects will implement IProjectCreationState -we can // skip any that don't IProjectCreationState projectCreationState = project.Services.ExportProvider.GetExportedValueOrDefault <IProjectCreationState>(); if (projectCreationState != null && !projectCreationState.WasNewlyCreated) { CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatData).ConfigureAwait(false); if (compatLevel != CompatibilityLevel.Recommended) { await WarnUserOfIncompatibleProjectAsync(compatLevel, compatData).ConfigureAwait(false); } } }); } } return(VSConstants.S_OK); }
// We use queryunload instead of onbeforeunload because this gives us the chance to cancel unload if the user presses cancel // when closing the temporary project file buffer. Otherwise, they could press cancel and the project would close with the editor // still open, leaving things in a very broken state. public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int shouldCancel) { var realUnconfiguredProject = pRealHierarchy.AsUnconfiguredProject(); // Ensure that this project is actually the project we're interested in. if (realUnconfiguredProject == null || !StringComparers.Paths.Equals(realUnconfiguredProject.FullPath, _unconfiguredProject.FullPath)) { // Do not block unload of the project shouldCancel = 0; return(VSConstants.S_OK); } // CloseWindowAsync returns true if closing the window succeeded. If it succeeded, we return false // to continue unloading the project. If the user cancelled close, we return true to cancel unload shouldCancel = _threadingService.ExecuteSynchronously(_editorModel.CanCloseWindowAsync) ? 0 : 1; return(VSConstants.S_OK); }