Beispiel #1
0
        public async Task CreateInMemoryImport()
        {
            if (_unloadCancellationToken.IsCancellationRequested)
            {
                return;
            }

            using (var access = await _projectLockService.WriteLockAsync(_unloadCancellationToken)) {
                // A bit odd but we have to "check it out" prior to creating it to avoid some of the validations in chk CPS
                await access.CheckoutAsync(_inMemoryImportFullPath);

                // Now either open or create the in-memory file. Normally Create will happen, but in
                // a scenario where your project had previously failed to load for some reason, need to TryOpen
                // to avoid a new reason for a project load failure
                _inMemoryImport = ProjectRootElement.TryOpen(_inMemoryImportFullPath, access.ProjectCollection);
                if (_inMemoryImport != null)
                {
                    // The file already exists. Scrape it out so we don’t add duplicate items.
                    _inMemoryImport.RemoveAllChildren();
                }
                else
                {
                    // The project didn’t already exist, so create it, and then mark the evaluated project dirty
                    // so that MSBuild will notice. This step isn’t necessary if the project was already in memory.
                    _inMemoryImport = CreateEmptyMsBuildProject(_inMemoryImportFullPath, access.ProjectCollection);

                    // Note that we actually need to mark every project evaluation dirty that is already loaded.
                    await ReevaluateLoadedConfiguredProjects(_unloadCancellationToken, access);
                }

                _filesItemGroup          = _inMemoryImport.AddItemGroup();
                _directoriesItemGroup    = _inMemoryImport.AddItemGroup();
                _temporaryAddedItemGroup = _inMemoryImport.AddItemGroup();
            }
        }
        public async Task SubscribeProjectXmlChangedEventAsync(UnconfiguredProject unconfiguredProject, EventHandler <ProjectXmlChangedEventArgs> handler)
        {
            var configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync().ConfigureAwait(false);

            using (var access = await _projectLockService.WriteLockAsync())
            {
                var xmlProject = await access.GetProjectAsync(configuredProject).ConfigureAwait(true);

                xmlProject.ProjectCollection.ProjectXmlChanged += handler;
            }
        }
Beispiel #3
0
        public async Task EnterWriteLockAsync(Func <ProjectCollection, CancellationToken, Task> action, CancellationToken cancellationToken = default)
        {
            Requires.NotNull(action, nameof(action));

            await _projectLockService.WriteLockAsync(async access =>
            {
                // Only async to let the caller call one of the other project accessor methods
                await action(access.ProjectCollection, cancellationToken);

                // Avoid blocking thread on Dispose
                await access.ReleaseAsync();
            }, cancellationToken);
        }
Beispiel #4
0
        /// <summary>
        /// Called when a project.lock.json file changes.
        /// </summary>
        public int FilesChanged(uint cChanges, string[] rgpszFile, uint[] rggrfChange)
        {
            // Kick off the operation to notify the project change in a different thread irregardless of
            // the kind of change since we are interested in all changes.
            _projectServices.ThreadingService.Fork(async() =>
            {
                try
                {
                    await _projectServices.Project.Services.ProjectAsynchronousTasks.LoadedProjectAsync(async() =>
                    {
                        using (var access = await _projectLockService.WriteLockAsync())
                        {
                            // notify all the loaded configured projects
                            var currentProjects = _projectServices.Project.LoadedConfiguredProjects;
                            foreach (var configuredProject in currentProjects)
                            {
                                // Inside a write lock, we should get back to the same thread.
                                var project = await access.GetProjectAsync(configuredProject).ConfigureAwait(true);
                                project.MarkDirty();
                                configuredProject.NotifyProjectChange();
                            }
                        }
                    });
                }
                catch (OperationCanceledException)
                {
                    // Project is already unloaded
                }
            }, unconfiguredProject: _projectServices.Project);

            return(VSConstants.S_OK);
        }
Beispiel #5
0
        public async Task OpenProjectXmlForWriteAsync(UnconfiguredProject project, Action <ProjectRootElement> action, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNull(project, nameof(action));

            using (ProjectWriteLockReleaser access = await _projectLockService.WriteLockAsync(cancellationToken))
            {
                await access.CheckoutAsync(project.FullPath)
                .ConfigureAwait(true);

                ProjectRootElement rootElement = await access.GetProjectXmlAsync(project.FullPath, cancellationToken)
                                                 .ConfigureAwait(true);

                // Deliberately not async to reduce the type of
                // code you can run while holding the lock.
                action(rootElement);
            }
        }
Beispiel #6
0
        public static async Task InstallTargets(EnvDTE.Project envDteProject, IProjectLockService projectLockService, UnconfiguredProject unconfiguredProject, string toolsPath)
        {
            var logger = new TraceLogger();

            try
            {
                if (projectLockService == null)
                {
                    throw new ArgumentNullException("projectLockService");
                }

                if (unconfiguredProject == null)
                {
                    throw new ArgumentNullException("unconfiguredProject");
                }

                using (var access = await projectLockService.WriteLockAsync())
                {
                    var configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync();

                    Project project = await access.GetProjectAsync(configuredProject);

                    // If you're going to change the project in any way,
                    // check it out from SCC first:
                    await access.CheckoutAsync(configuredProject.UnconfiguredProject.FullPath);

                    // install targets

                    var installer = new InstallTargetsHelper(logger);
                    installer.Install(project, toolsPath);
                    // configureCallback(project);

                    IProjectTreeService projectTreeService = configuredProject.Services.ExportProvider.GetExportedValue <IProjectTreeService>();
                    await projectTreeService.PublishLatestTreeAsync();

                    // envDteProject.Save(envDteProject.FullName);

                    // save changes.
                    //project.Save(project.FullPath);
                }
            }
            catch (AggregateException ex)
            {
                logger.LogError(ex.Message);
                foreach (var e in ex.InnerExceptions)
                {
                    logger.LogError(e.Message);
                }

                throw;
            }
            catch (Exception e)
            {
                logger.LogError(e.Message);
            }
        }
Beispiel #7
0
        public async Task ExecuteInWriteLock(Action <ProjectRootElement> action)
        {
            using (var access = await _projectLockService.WriteLockAsync())
            {
                await access.CheckoutAsync(_unconfiguredProject.FullPath).ConfigureAwait(true);

                var msbuildProject = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath).ConfigureAwait(false);

                action.Invoke(msbuildProject);
            }
        }
Beispiel #8
0
        public async Task SaveProjectXmlAsync(string toSave)
        {
            using (var access = await _projectLockService.WriteLockAsync())
            {
                await access.CheckoutAsync(_unconfiguredProject.FullPath).ConfigureAwait(true);

                var encoding = await _unconfiguredProject.GetFileEncodingAsync().ConfigureAwait(false);

                _fileSystem.WriteAllText(_unconfiguredProject.FullPath, toSave, encoding);
            }
        }
Beispiel #9
0
        public async Task SaveProjectXmlAsync(string toSave)
        {
            using (var access = await _projectLockService.WriteLockAsync())
            {
                await access.CheckoutAsync(_unconfiguredProject.FullPath).ConfigureAwait(true);

                // We must clear the project dirty flag first. If it's dirty in memory, the ProjectReloadManager will detect that
                // the project is dirty and fail the reload, and discard the changes.
                var projectRoot = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath).ConfigureAwait(true);

                var stringWriter = new StringWriter();

                // Calling save on the ProjectRootElement clears the dirty flag. However, we don't care about the result, to just
                // throw it into a stringwriter and discard.
                projectRoot.Save(stringWriter);
                var encoding = await _unconfiguredProject.GetFileEncodingAsync().ConfigureAwait(false);

                _fileSystem.WriteAllText(_unconfiguredProject.FullPath, toSave, encoding);
            }
        }
Beispiel #10
0
        public void Add(string bstrImport)
        {
            if (!_importsList.IsPresent(bstrImport))
            {
                _threadingService.ExecuteSynchronously(async() =>
                {
                    using (var access = await _lockService.WriteLockAsync())
                    {
                        var project = await access.GetProjectAsync(ConfiguredProject).ConfigureAwait(true);
                        await access.CheckoutAsync(project.Xml.ContainingProject.FullPath).ConfigureAwait(true);
                        project.AddItem(importItemTypeName, bstrImport);
                    }
                });

                OnImportAdded(bstrImport);
            }
            else
            {
                throw new ArgumentException(string.Format("{0} - Namespace is already imported", bstrImport), nameof(bstrImport));
            }
        }
Beispiel #11
0
        public override async Task <string> OnSetPropertyValueAsync(
            string unevaluatedPropertyValue,
            IProjectProperties defaultProperties,
            IReadOnlyDictionary <string, string> dimensionalConditions = null)
        {
            await _projectLockService.WriteLockAsync(async access =>
            {
                ProjectRootElement projectXml = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath);
                await _helper.SetPropertyAsync(unevaluatedPropertyValue, defaultProperties, projectXml);
            });

            return(null);
        }
Beispiel #12
0
        public override async Task <string> OnSetPropertyValueAsync(
            string unevaluatedPropertyValue,
            IProjectProperties defaultProperties,
            IReadOnlyDictionary <string, string> dimensionalConditions = null)
        {
            using (ProjectWriteLockReleaser access = await _projectLockService.WriteLockAsync())
            {
                Microsoft.Build.Construction.ProjectRootElement projectXml = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath);

                await _helper.SetPropertyAsync(unevaluatedPropertyValue, defaultProperties, projectXml);
            }

            return(null);
        }
Beispiel #13
0
        public override async Task <string> OnSetPropertyValueAsync(
            string unevaluatedPropertyValue,
            IProjectProperties defaultProperties,
            IReadOnlyDictionary <string, string> dimensionalConditions = null)
        {
            using (var access = await _projectLockService.WriteLockAsync())
            {
                var projectXml = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath).ConfigureAwait(true);

                await _helper.SetPropertyAsync(unevaluatedPropertyValue, defaultProperties, projectXml).ConfigureAwait(true);
            }

            return(null);
        }
Beispiel #14
0
 public async Task SaveProjectSettings()
 {
     await threadHandler.AsyncPump.RunAsync(async() =>
     {
         using (var writeLock = await projectLockService.WriteLockAsync())
         {
             await writeLock.CheckoutAsync(project.FullPath);
             var msBuildProject = await writeLock.GetProjectAsync(await project.GetSuggestedConfiguredProjectAsync());
             msBuildProject.SetProperty(nameof(GitHub) + nameof(Branch), Branch);
             msBuildProject.SetProperty(nameof(VersionNamePattern), VersionNamePattern);
             msBuildProject.SetProperty(nameof(RepositoryName), RepositoryName);
             msBuildProject.Save();
         }
     });
 }
Beispiel #15
0
        /// <summary>
        /// Called when a project.lock.json file changes.
        /// </summary>
        public int FilesChanged(uint cChanges, string[] rgpszFile, uint[] rggrfChange)
        {
            // Kick off the operation to notify the project change in a different thread irregardless of
            // the kind of change since we are interested in all changes.
            _projectServices.ThreadingService.Fork(async() => {
                using (var access = await _projectLockService.WriteLockAsync())
                {
                    // Inside a write lock, we should get back to the same thread.
                    var project = await access.GetProjectAsync(_projectServices.ActiveConfiguredProject).ConfigureAwait(true);
                    project.MarkDirty();
                    _projectServices.ActiveConfiguredProject.NotifyProjectChange();
                }
            }, configuredProject: _projectServices.ActiveConfiguredProject);

            return(VSConstants.S_OK);
        }
Beispiel #16
0
 public async Task RunLockedAsync(bool writeLock, Func <Task> task)
 {
     if (writeLock)
     {
         using (await _projectLockService.WriteLockAsync())
         {
             await task().ConfigureAwait(true);
         }
     }
     else
     {
         using (await _projectLockService.ReadLockAsync())
         {
             await task().ConfigureAwait(true);
         }
     }
 }
Beispiel #17
0
        internal async Task Save()
        {
            await threadHandling.AsyncPump.RunAsync(async() =>
            {
                using (var writeLock = await lockService.WriteLockAsync())
                {
                    await writeLock.CheckoutAsync(project.FullPath);
                    var msBuildProject = await writeLock.GetProjectAsync(await project.GetSuggestedConfiguredProjectAsync());
                    msBuildProject.SetProperty("SelectedDeployTarget", SelectedTarget?.Name ?? "");
                    msBuildProject.Save();
                }
            });

            if (SelectedTarget != null)
            {
                await SelectedTarget.DeployTarget.SaveProjectSettings();
            }
        }
Beispiel #18
0
        private async Task ProjectRenamedOnWriter(object sender, ProjectRenamedEventArgs args)
        {
            var oldImportName = FileSystemMirroringProjectUtilities.GetInMemoryTargetsFileName(args.OldFullPath);
            var newImportName = FileSystemMirroringProjectUtilities.GetInMemoryTargetsFileName(args.NewFullPath);

            using (var access = await _projectLockService.WriteLockAsync()) {
                await access.CheckoutAsync(_unconfiguredProject.FullPath);

                var xml = await access.GetProjectXmlAsync(_unconfiguredProject.FullPath);

                var import = xml.Imports.FirstOrDefault(i => i.Project.EqualsIgnoreCase(oldImportName));
                if (import != null)
                {
                    import.Project   = newImportName;
                    import.Condition = $"Exists('{newImportName}')";
                    await Project.UpdateFullPathAsync(access);
                }
            }
        }
Beispiel #19
0
        public async Task <bool> ApplyAsync()
        {
            using (var projectWriteLock = await mProjectLockService.WriteLockAsync())
            {
                var configuredProject = await mUnconfiguredProject.GetSuggestedConfiguredProjectAsync();

                var project = await projectWriteLock.GetProjectAsync(configuredProject);

                await projectWriteLock.CheckoutAsync(mUnconfiguredProject.FullPath);

                foreach (var property in mBuildProperties.GetProperties())
                {
                    project.SetProperty(property.Key, property.Value);
                }

                project.Save();
            }

            return(true);
        }
Beispiel #20
0
        public async Task ApplyChangesAsync()
        {
            var xConfiguredProject = await mUnconfiguredProject.GetSuggestedConfiguredProjectAsync();

            using (var xAccess = await mProjectLockService.WriteLockAsync())
            {
                var xProject = await xAccess.GetProjectAsync(xConfiguredProject);

                await xAccess.CheckoutAsync(xConfiguredProject.UnconfiguredProject.FullPath);

                foreach (var xProperty in Properties)
                {
                    if (PropertyChanged(xProperty))
                    {
                        xProject.SetProperty(xProperty.Key, xProperty.Value);
                    }
                }

                xProject.Save();
            }
        }
        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();
            }
        }