private static async ATask SetVCProjectsConfigurationProperties12(DTEProject project,
                                                                          string configurationName, string platformName)
        {
            // Inspired from Nuget: https://github.com/Haacked/NuGet/blob/master/src/VisualStudio12/ProjectHelper.cs
            IVsBrowseObjectContext context             = project.Object as IVsBrowseObjectContext;
            UnconfiguredProject    unconfiguredProject = context.UnconfiguredProject;
            IProjectLockService    service             = unconfiguredProject.ProjectService.Services.ProjectLockService;

            using (ProjectWriteLockReleaser releaser = await service.WriteLockAsync())
            {
                ProjectCollection collection = releaser.ProjectCollection;

                ConfigureCollection(collection, configurationName, platformName);

                _VCProjectCollectionLoaded = true;

                // The following was present in the NuGet code: it seesms unecessary,
                // as the lock it's release anyway after the using block (check
                // service.IsAnyLockHeld). Also it seemed to cause a deadlock sometimes
                // when switching solution configuration
                //await releaser.ReleaseAsync();
            }
        }
示例#2
0
 private Task RemoveFiles(HashSet <string> filesToRemove, ProjectWriteLockReleaser access)
 {
     return(RemoveItems(_filesItemGroup, _fileItems, filesToRemove, access));
 }
示例#3
0
        private async Task ReevaluateLoadedConfiguredProjects(CancellationToken cancellationToken, ProjectWriteLockReleaser access)
        {
            foreach (var configuredProject in _unconfiguredProject.LoadedConfiguredProjects)
            {
                try {
                    var jsproj = await access.GetProjectAsync(configuredProject, cancellationToken);

                    jsproj.ReevaluateIfNecessary();
                } catch (Exception ex) {
                    System.Diagnostics.Debug.Fail("We were unable to mark a configuration as dirty" + ex.Message, ex.StackTrace);
                }
            }
        }
 public Task UpdateFullPathAsync(ProjectWriteLockReleaser access, CancellationToken cancellationToken = default(CancellationToken)) {
     _inMemoryImportFullPath = _unconfiguredProject.GetInMemoryTargetsFileFullPath();
     _inMemoryImport.FullPath = _inMemoryImportFullPath;
     return ReevaluateLoadedConfiguredProjects(cancellationToken, access);
 }
示例#5
0
        async Task <bool> BuildProjectAsync(ProjectWriteLockReleaser writeAccess)
        {
            var msBuildProject = await writeAccess.GetProjectAsync(ConfiguredProject);

            var solutionPath = QtProjectTracker.SolutionPath;
            var configProps  = new Dictionary <string, string>(
                ConfiguredProject.ProjectConfiguration.Dimensions.ToImmutableDictionary())
            {
                { "SolutionPath", solutionPath },
                { "SolutionFileName", Path.GetFileName(solutionPath) },
                { "SolutionName", Path.GetFileNameWithoutExtension(solutionPath) },
                { "SolutionExt", Path.GetExtension(solutionPath) },
                { "SolutionDir", Path.GetDirectoryName(solutionPath).TrimEnd('\\') + '\\' }
            };

            foreach (var property in Properties)
            {
                configProps[property.Key] = property.Value;
            }

            var projectInstance = new ProjectInstance(msBuildProject.Xml,
                                                      configProps, null, new ProjectCollection());

            var loggerVerbosity = LoggerVerbosity;

            if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
            {
                loggerVerbosity = QtVsToolsPackage.Instance.Options.BuildLoggerVerbosity;
            }
            var buildParams = new BuildParameters()
            {
                Loggers = (loggerVerbosity != LoggerVerbosity.Quiet)
                        ? new[] { new QtProjectLogger()
                                  {
                                      Verbosity = loggerVerbosity
                                  } }
                        : null
            };

            var buildRequest = new BuildRequestData(projectInstance,
                                                    Targets.ToArray(),
                                                    hostServices: null,
                                                    flags: BuildRequestDataFlags.ProvideProjectStateAfterBuild);

            if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
            {
                Messages.Print(string.Format(
                                   "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Build [{2}] {3}",
                                   DateTime.Now, Thread.CurrentThread.ManagedThreadId,
                                   ConfiguredProject.ProjectConfiguration.Name,
                                   UnconfiguredProject.FullPath));
                Messages.Print("=== Targets");
                foreach (var target in buildRequest.TargetNames)
                {
                    Messages.Print(string.Format("    {0}", target));
                }
                Messages.Print("=== Properties");
                foreach (var property in Properties)
                {
                    Messages.Print(string.Format("    {0}={1}",
                                                 property.Key, property.Value));
                }
            }

            BuildResult result = null;

            while (result == null)
            {
                try {
                    result = BuildManager.DefaultBuildManager.Build(
                        buildParams, buildRequest);
                } catch (InvalidOperationException) {
                    if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
                    {
                        Messages.Print(string.Format(
                                           "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] "
                                           + "Warning: Another build is in progress; waiting...",
                                           DateTime.Now,
                                           Thread.CurrentThread.ManagedThreadId,
                                           ConfiguredProject.ProjectConfiguration.Name));
                    }
                    await Task.Delay(3000);
                }
            }

            if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
            {
                string        resMsg;
                StringBuilder resInfo = new StringBuilder();
                if (result?.OverallResult == BuildResultCode.Success)
                {
                    resMsg = "Build ok";
                }
                else
                {
                    resMsg = "Build FAIL";
                    if (result == null)
                    {
                        resInfo.AppendLine("####### Build returned 'null'");
                    }
                    else
                    {
                        resInfo.AppendLine("####### Build returned 'Failure' code");
                        if (result.ResultsByTarget != null)
                        {
                            foreach (var tr in result.ResultsByTarget)
                            {
                                var res = tr.Value;
                                if (res.ResultCode != TargetResultCode.Failure)
                                {
                                    continue;
                                }
                                resInfo.AppendFormat("### Target '{0}' FAIL\r\n", tr.Key);
                                if (res.Items != null && res.Items.Length > 0)
                                {
                                    resInfo.AppendFormat(
                                        "Items: {0}\r\n", string.Join(", ", res.Items
                                                                      .Select(it => it.ItemSpec)));
                                }
                                var e = tr.Value?.Exception;
                                if (e != null)
                                {
                                    resInfo.AppendFormat(
                                        "Exception: {0}\r\nStacktrace:\r\n{1}\r\n",
                                        e.Message, e.StackTrace);
                                }
                            }
                        }
                    }
                }
                Messages.Print(string.Format(
                                   "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] {3}\r\n{4}",
                                   DateTime.Now, Thread.CurrentThread.ManagedThreadId,
                                   ConfiguredProject.ProjectConfiguration.Name,
                                   resMsg, resInfo.ToString()));
            }

            bool ok = false;

            if (result == null ||
                result.ResultsByTarget == null ||
                result.OverallResult != BuildResultCode.Success)
            {
                Messages.Print(string.Format("{0}: background build FAILED!",
                                             Path.GetFileName(UnconfiguredProject.FullPath)));
            }
            else
            {
                var checkResults = result.ResultsByTarget
                                   .Where(x => Targets.Contains(x.Key))
                                   .Select(x => x.Value);
                ok = checkResults.Any() &&
                     checkResults.All(x => x.ResultCode == TargetResultCode.Success);
                if (ok)
                {
                    msBuildProject.MarkDirty();
                }
            }
            await writeAccess.ReleaseAsync();

            return(ok);
        }
示例#6
0
        private async Task RenameItems(Dictionary <string, ProjectItemElement> items, IReadOnlyDictionary <string, string> itemsToRename, ProjectWriteLockReleaser access)
        {
            await access.CheckoutAsync(itemsToRename.Keys);

            foreach (var kvp in itemsToRename)
            {
                ProjectItemElement item;
                if (items.TryGetValue(kvp.Key, out item))
                {
                    items.Remove(kvp.Key);
                    item.Include     = kvp.Value;
                    items[kvp.Value] = item;
                }
            }
        }
示例#7
0
 private async Task RenameDirectories(IReadOnlyDictionary <string, string> directoriesToRename, ProjectWriteLockReleaser access)
 {
     foreach (var kvp in directoriesToRename)
     {
         await RenameItems(_fileItems, kvp.Key, kvp.Value, access);
         await RenameItems(_directoryItems, kvp.Key, kvp.Value, access);
     }
 }
示例#8
0
        private async Task RemoveItems(ProjectItemGroupElement parent, Dictionary <string, ProjectItemElement> items, IReadOnlyCollection <string> itemsToRemove, ProjectWriteLockReleaser access)
        {
            await access.CheckoutAsync(itemsToRemove);

            foreach (var path in itemsToRemove)
            {
                RemoveItem(parent, items, path);
            }
        }
 private async Task RemoveItems(ProjectItemGroupElement parent, Dictionary<string, ProjectItemElement> items, IReadOnlyCollection<string> itemsToRemove, ProjectWriteLockReleaser access) {
     await access.CheckoutAsync(itemsToRemove);
     foreach (var path in itemsToRemove) {
         RemoveItem(parent, items, path);
     }
 }
 private Task RemoveItems(ProjectItemGroupElement parent, Dictionary<string, ProjectItemElement> items, string directoryName, ProjectWriteLockReleaser access) {
     return RemoveItems(parent, items, items.Keys.Where(f => f.StartsWithIgnoreCase(directoryName)).ToList(), access);
 }
 private async Task RemoveDirectories(IReadOnlyCollection<string> directoriesToRemove, ProjectWriteLockReleaser access) {
     foreach (var directoryName in directoriesToRemove) {
         await RemoveItems(_filesItemGroup, _fileItems, directoryName, access);
         await RemoveItems(_directoriesItemGroup, _directoryItems, directoryName, access);
     }
 }
 private Task RemoveFiles(HashSet<string> filesToRemove, ProjectWriteLockReleaser access) {
     return RemoveItems(_filesItemGroup, _fileItems, filesToRemove, access);
 }
 private async Task ReevaluateLoadedConfiguredProjects(CancellationToken cancellationToken, ProjectWriteLockReleaser access) {
     foreach (var configuredProject in _unconfiguredProject.LoadedConfiguredProjects) {
         try {
             var jsproj = await access.GetProjectAsync(configuredProject, cancellationToken);
             jsproj.ReevaluateIfNecessary();
         } catch (Exception ex) {
             System.Diagnostics.Debug.Fail("We were unable to mark a configuration as dirty" + ex.Message, ex.StackTrace);
         }
     }
 }
示例#14
0
 private async Task RemoveDirectories(IReadOnlyCollection <string> directoriesToRemove, ProjectWriteLockReleaser access)
 {
     foreach (var directoryName in directoriesToRemove)
     {
         await RemoveItems(_filesItemGroup, _fileItems, directoryName, access);
         await RemoveItems(_directoriesItemGroup, _directoryItems, directoryName, access);
     }
 }
 private Task RenameFiles(IReadOnlyDictionary<string, string> filesToRename, ProjectWriteLockReleaser access) {
     return RenameItems(_fileItems, filesToRename, access);
 }
示例#16
0
 private Task RemoveItems(ProjectItemGroupElement parent, Dictionary <string, ProjectItemElement> items, string directoryName, ProjectWriteLockReleaser access)
 {
     return(RemoveItems(parent, items, items.Keys.Where(f => f.StartsWithIgnoreCase(directoryName)).ToList(), access));
 }
 private async Task RenameDirectories(IReadOnlyDictionary<string, string> directoriesToRename, ProjectWriteLockReleaser access) {
     foreach (var kvp in directoriesToRename) {
         await RenameItems(_fileItems, kvp.Key, kvp.Value, access);
         await RenameItems(_directoryItems, kvp.Key, kvp.Value, access);
     }
 }
示例#18
0
 private Task RenameFiles(IReadOnlyDictionary <string, string> filesToRename, ProjectWriteLockReleaser access)
 {
     return(RenameItems(_fileItems, filesToRename, access));
 }
        private Task RenameItems(Dictionary<string, ProjectItemElement> items, string oldDirectoryName, string newDirectoryName, ProjectWriteLockReleaser access) {
            var itemsToRename = items.Keys
                .Where(f => f.StartsWithIgnoreCase(oldDirectoryName))
                .ToDictionary(f => f, f => newDirectoryName + f.Substring(oldDirectoryName.Length));

            return RenameItems(items, itemsToRename, access);
        }
示例#20
0
        private Task RenameItems(Dictionary <string, ProjectItemElement> items, string oldDirectoryName, string newDirectoryName, ProjectWriteLockReleaser access)
        {
            var itemsToRename = items.Keys
                                .Where(f => f.StartsWithIgnoreCase(oldDirectoryName))
                                .ToDictionary(f => f, f => newDirectoryName + f.Substring(oldDirectoryName.Length));

            return(RenameItems(items, itemsToRename, access));
        }
 private async Task RenameItems(Dictionary<string, ProjectItemElement> items, IReadOnlyDictionary<string, string> itemsToRename, ProjectWriteLockReleaser access) {
     await access.CheckoutAsync(itemsToRename.Keys);
     foreach (var kvp in itemsToRename) {
         ProjectItemElement item;
         if (items.TryGetValue(kvp.Key, out item)) {
             items.Remove(kvp.Key);
             item.Include = kvp.Value;
             items[kvp.Value] = item;
         }
     }
 }
        /// <summary>
        /// Deletes items from the project, and optionally from disk.
        /// Note: Delete and Remove commands are handled via IVsHierarchyDeleteHandler3, not by
        /// IAsyncCommandGroupHandler and first asks us we CanRemove nodes. If yes then RemoveAsync is called.
        /// We can remove only nodes that are standard and based on project items, i.e. nodes that
        /// are created by default IProjectDependenciesSubTreeProvider implementations and have
        /// DependencyNode.GenericDependencyFlags flags and IRule with Context != null, in order to obtain
        /// node's itemSpec. ItemSpec then used to remove a project item having same Include.
        /// </summary>
        /// <param name="nodes">The nodes that should be deleted.</param>
        /// <param name="deleteOptions">A value indicating whether the items should be deleted from disk as well as
        /// from the project file.
        /// </param>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="IProjectTreeProvider.CanRemove"/>
        /// would return <c>false</c> for this operation.</exception>
        public override async Task RemoveAsync(IImmutableSet <IProjectTree> nodes,
                                               DeleteOptions deleteOptions = DeleteOptions.None)
        {
            if (deleteOptions.HasFlag(DeleteOptions.DeleteFromStorage))
            {
                throw new NotSupportedException();
            }

            // Get the list of shared import nodes.
            IEnumerable <IProjectTree> sharedImportNodes = nodes.Where(node =>
                                                                       node.Flags.Contains(DependencyTreeFlags.SharedProjectFlags));

            // Get the list of normal reference Item Nodes (this excludes any shared import nodes).
            IEnumerable <IProjectTree> referenceItemNodes = nodes.Except(sharedImportNodes);

            using (ProjectWriteLockReleaser access = await ProjectLockService.WriteLockAsync())
            {
                Project project = await access.GetProjectAsync(ActiveConfiguredProject).ConfigureAwait(true);

                // Handle the removal of normal reference Item Nodes (this excludes any shared import nodes).
                foreach (IProjectTree node in referenceItemNodes)
                {
                    if (node.BrowseObjectProperties == null || node.BrowseObjectProperties.Context == null)
                    {
                        // if node does not have an IRule with valid ProjectPropertiesContext we can not
                        // get it's itemsSpec. If nodes provided by custom IProjectDependenciesSubTreeProvider
                        // implementation, and have some custom IRule without context, it is not a problem,
                        // since they wouldnot have DependencyNode.GenericDependencyFlags and we would not
                        // end up here, since CanRemove would return false and Remove command would not show
                        // up for those nodes.
                        continue;
                    }

                    IProjectPropertiesContext nodeItemContext = node.BrowseObjectProperties.Context;
                    ProjectItem unresolvedReferenceItem       = project.GetItemsByEvaluatedInclude(nodeItemContext.ItemName)
                                                                .FirstOrDefault(item => string.Equals(item.ItemType,
                                                                                                      nodeItemContext.ItemType,
                                                                                                      StringComparison.OrdinalIgnoreCase));

                    Report.IfNot(unresolvedReferenceItem != null, "Cannot find reference to remove.");
                    if (unresolvedReferenceItem != null)
                    {
                        await access.CheckoutAsync(unresolvedReferenceItem.Xml.ContainingProject.FullPath)
                        .ConfigureAwait(true);

                        project.RemoveItem(unresolvedReferenceItem);
                    }
                }

                IDependenciesSnapshot snapshot = DependenciesSnapshotProvider.CurrentSnapshot;
                Requires.NotNull(snapshot, nameof(snapshot));
                if (snapshot == null)
                {
                    return;
                }

                // Handle the removal of shared import nodes.
                ProjectRootElement projectXml = await access.GetProjectXmlAsync(UnconfiguredProject.FullPath)
                                                .ConfigureAwait(true);

                foreach (IProjectTree sharedImportNode in sharedImportNodes)
                {
                    string sharedFilePath = UnconfiguredProject.GetRelativePath(sharedImportNode.FilePath);
                    if (string.IsNullOrEmpty(sharedFilePath))
                    {
                        continue;
                    }

                    IDependency sharedProjectDependency = snapshot.FindDependency(sharedFilePath, topLevel: true);
                    if (sharedProjectDependency != null)
                    {
                        sharedFilePath = sharedProjectDependency.Path;
                    }

                    // Find the import that is included in the evaluation of the specified ConfiguredProject that
                    // imports the project file whose full path matches the specified one.
                    IEnumerable <ResolvedImport> matchingImports = from import in project.Imports
                                                                   where import.ImportingElement.ContainingProject == projectXml
                                                                   where PathHelper.IsSamePath(import.ImportedProject.FullPath, sharedFilePath)
                                                                   select import;
                    foreach (ResolvedImport importToRemove in matchingImports)
                    {
                        ProjectImportElement importingElementToRemove = importToRemove.ImportingElement;
                        Report.IfNot(importingElementToRemove != null,
                                     "Cannot find shared project reference to remove.");
                        if (importingElementToRemove != null)
                        {
                            await access.CheckoutAsync(importingElementToRemove.ContainingProject.FullPath)
                            .ConfigureAwait(true);

                            importingElementToRemove.Parent.RemoveChild(importingElementToRemove);
                        }
                    }
                }
            }
        }
示例#23
0
 public Task UpdateFullPathAsync(ProjectWriteLockReleaser access, CancellationToken cancellationToken = default(CancellationToken))
 {
     _inMemoryImportFullPath  = _unconfiguredProject.GetInMemoryTargetsFileFullPath();
     _inMemoryImport.FullPath = _inMemoryImportFullPath;
     return(ReevaluateLoadedConfiguredProjects(cancellationToken, access));
 }