public async Task <ILaunchProfile?> DuplicateLaunchProfileAsync(string currentProfileName, string?newProfileName, string?newProfileCommandName, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ILaunchSettings?launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite).WithCancellation(cancellationToken);

            Assumes.NotNull(launchSettings);

            ILaunchProfile?existingProfile = launchSettings.Profiles.FirstOrDefault(p => StringComparers.LaunchProfileNames.Equals(p.Name, currentProfileName));

            if (existingProfile is not null)
            {
                newProfileName ??= await GetNewProfileNameAsync(cancellationToken);

                newProfileCommandName ??= existingProfile.CommandName;

                var writableProfile = new WritableLaunchProfile(existingProfile);
                writableProfile.Name        = newProfileName;
                writableProfile.CommandName = newProfileCommandName;

                await _launchSettingsProvider.AddOrUpdateProfileAsync(writableProfile.ToLaunchProfile(), addToFront : false);

                return(_launchSettingsProvider.CurrentSnapshot?.Profiles.FirstOrDefault(p => StringComparers.LaunchProfileNames.Equals(newProfileName, p.Name)));
            }

            return(null);
        }
Beispiel #2
0
        public async Task <IEntityValue?> RetrieveLaunchProfileEntityAsync(IQueryExecutionContext queryExecutionContext, EntityIdentity id, ILaunchProfilePropertiesAvailableStatus requestedProperties)
        {
            string desiredProfileName = ValidateIdAndExtractProfileName(id);

            if (await _project.GetProjectLevelPropertyPagesCatalogAsync() is IPropertyPagesCatalog projectCatalog)
            {
                ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot();

                if (launchSettings is IVersionedLaunchSettings versionedLaunchSettings)
                {
                    queryExecutionContext.ReportInputDataVersion(_launchSettingsTracker.VersionKey, versionedLaunchSettings.Version);

                    IProjectState projectState = new LaunchProfileProjectState(_project, _launchSettingsProvider, _launchSettingsTracker);

                    foreach ((int index, ProjectSystem.Debug.ILaunchProfile profile) in launchSettings.Profiles.WithIndices())
                    {
                        if (StringComparers.LaunchProfileNames.Equals(profile.Name, desiredProfileName) &&
                            !Strings.IsNullOrEmpty(profile.CommandName))
                        {
                            foreach (Rule rule in DebugUtilities.GetDebugChildRules(projectCatalog))
                            {
                                if (rule.Metadata.TryGetValue(s_commandNameMetadataName, out object?commandNameObj) &&
                                    commandNameObj is string commandName &&
                                    StringComparers.LaunchProfileCommandNames.Equals(commandName, profile.CommandName))
                                {
                                    QueryProjectPropertiesContext propertiesContext = new(
                                        isProjectFile : true,
                                        file : _project.FullPath,
                                        itemType : LaunchProfileProjectItemProvider.ItemType,
                                        itemName : profile.Name);

                                    IEntityValue launchProfileValue = CreateLaunchProfileValue(
                                        queryExecutionContext,
                                        id,
                                        propertiesContext,
                                        rule,
                                        index,
                                        projectState,
                                        requestedProperties);
                                    return(launchProfileValue);
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// This is called on F5 to return the list of debug targets. What is returned depends on the debug provider extensions
        /// which understands how to launch the currently active profile type.
        /// </summary>
        private async Task <IReadOnlyList <IDebugLaunchSettings> > QueryDebugTargetsInternalAsync(DebugLaunchOptions launchOptions, bool fromDebugLaunch)
        {
            // Get the active debug profile (timeout of 5s, though in reality is should never take this long as even in error conditions
            // a snapshot is produced).
            ILaunchSettings currentProfiles = await _launchSettingsProvider.WaitForFirstSnapshot(5000);

            ILaunchProfile?activeProfile = currentProfiles?.ActiveProfile;

            // Should have a profile
            if (activeProfile == null)
            {
                throw new Exception(VSResources.ActiveLaunchProfileNotFound);
            }

            // Now find the DebugTargets provider for this profile
            IDebugProfileLaunchTargetsProvider launchProvider = GetLaunchTargetsProvider(activeProfile) ??
                                                                throw new Exception(string.Format(VSResources.DontKnowHowToRunProfile, activeProfile.Name));

            IReadOnlyList <IDebugLaunchSettings> launchSettings;

            if (fromDebugLaunch && launchProvider is IDebugProfileLaunchTargetsProvider2 launchProvider2)
            {
                launchSettings = await launchProvider2.QueryDebugTargetsForDebugLaunchAsync(launchOptions, activeProfile);
            }
            else
            {
                launchSettings = await launchProvider.QueryDebugTargetsAsync(launchOptions, activeProfile);
            }

            _lastLaunchProvider = launchProvider;
            return(launchSettings);
        }
        public override async Task <string?> OnSetPropertyValueAsync(string propertyName, string unevaluatedPropertyValue, IProjectProperties defaultProperties, IReadOnlyDictionary <string, string>?dimensionalConditions = null)
        {
            ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot();

            IWritableLaunchSettings writableLaunchSettings = launchSettings.ToWritableLaunchSettings();

            if (SetPropertyValue(propertyName, unevaluatedPropertyValue, writableLaunchSettings))
            {
                await _launchSettingsProvider.UpdateAndSaveSettingsAsync(writableLaunchSettings.ToLaunchSettings());
            }

            // We've intercepted the "set" operation and redirected it to the launch settings.
            // Return "null" to indicate that the value should _not_ be set in the project file
            // as well.
            return(null);
        }
Beispiel #5
0
        private async Task <ILaunchProfile?> GetActiveProfileAsync()
        {
            ILaunchSettings currentProfiles = await _launchSettingsProvider.WaitForFirstSnapshot();

            ILaunchProfile?activeProfile = currentProfiles.ActiveProfile;

            return(activeProfile);
        }
Beispiel #6
0
        /// <summary>
        /// Handles the core logic of retrieving the property.
        /// </summary>
        /// <remarks>
        /// Since we're redirecting the properties through the <see cref="ILaunchSettingsProvider"/>
        /// there's no distinction between "evaluated" and "unevaluated" properties, so
        /// we handle both in the same way.
        /// </remarks>
        private async Task <string> GetPropertyValueAsync()
        {
            // Infinite timeout means this will not actually be null.
            ILaunchSettings?launchSettings = await _launchSettings.WaitForFirstSnapshot(Timeout.Infinite);

            Assumes.NotNull(launchSettings);

            return(launchSettings.ActiveProfile?.Name ?? string.Empty);
        }
        public override async Task <string?> OnSetPropertyValueAsync(string propertyName, string unevaluatedPropertyValue, IProjectProperties defaultProperties, IReadOnlyDictionary <string, string>?dimensionalConditions = null)
        {
            ConfiguredProject?configuredProject = await _project.GetSuggestedConfiguredProjectAsync();

            IPropertyPagesCatalogProvider?catalogProvider = configuredProject?.Services.PropertyPagesCatalog;

            if (catalogProvider == null)
            {
                return(null);
            }

            IPropertyPagesCatalog catalog = await catalogProvider.GetCatalogAsync(PropertyPageContexts.Project);

            Rule?rule = catalog.GetSchema(unevaluatedPropertyValue);

            if (rule == null)
            {
                return(null);
            }

            if (rule.Metadata.TryGetValue("CommandName", out object pageCommandNameObj) &&
                pageCommandNameObj is string pageCommandName)
            {
                _projectThreadingService.RunAndForget(async() =>
                {
                    // Infinite timeout means this will not actually be null.
                    ILaunchSettings?launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);
                    Assumes.NotNull(launchSettings);

                    IWritableLaunchSettings writableLaunchSettings = launchSettings.ToWritableLaunchSettings();
                    IWritableLaunchProfile?activeProfile           = writableLaunchSettings.ActiveProfile;
                    if (activeProfile != null)
                    {
                        activeProfile.CommandName = pageCommandName;

                        await _launchSettingsProvider.UpdateAndSaveSettingsAsync(writableLaunchSettings.ToLaunchSettings());
                    }
                },
                                                      options: ForkOptions.HideLocks,
                                                      unconfiguredProject: _project);
            }

            return(null);
        }
        public override Task <string?> OnSetPropertyValueAsync(string propertyName, string unevaluatedPropertyValue, IProjectProperties defaultProperties, IReadOnlyDictionary <string, string>?dimensionalConditions = null)
        {
            _projectThreadingService.RunAndForget(async() =>
            {
                ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

                var writableLaunchSettings = launchSettings.ToWritableLaunchSettings();
                if (SetPropertyValue(propertyName, unevaluatedPropertyValue, writableLaunchSettings))
                {
                    await _launchSettingsProvider.UpdateAndSaveSettingsAsync(writableLaunchSettings.ToLaunchSettings());
                }
            },
                                                  options: ForkOptions.HideLocks,
                                                  unconfiguredProject: _project);

            // We've intercepted the "set" operation and redirected it to the launch settings.
            // Return "null" to indicate that the value should _not_ be set in the project file
            // as well.
            return(Task.FromResult <string?>(null));
        }
        private async Task <ILaunchProfile> GetActiveProfileAsync()
        {
            ILaunchSettings currentProfiles = await _launchSettingsProvider.WaitForFirstSnapshot();

            ILaunchProfile?activeProfile = currentProfiles.ActiveProfile;

            // Should have a profile
            if (activeProfile == null)
            {
                throw new Exception(VSResources.ActiveLaunchProfileNotFound);
            }

            return(activeProfile);
        }
        /// <summary>
        /// Blocks until at least one snapshot has been generated.
        /// </summary>
        /// <param name="provider">The underlying provider to satisfy this request.</param>
        /// <param name="token">An optional token to signal cancellation of the request.</param>
        /// <returns>
        /// The current <see cref="ILaunchSettings"/> snapshot.
        /// </returns>
        public static async Task <ILaunchSettings> WaitForFirstSnapshot(this ILaunchSettingsProvider provider, CancellationToken token = default)
        {
            // With an infinite timeout, the provider is contractually obligated to return a non-null value.
            Task <ILaunchSettings?> task = provider.WaitForFirstSnapshot(Timeout.Infinite);

            if (token.CanBeCanceled)
            {
                task = task.WithCancellation(token);
            }

            ILaunchSettings?launchSettings = await task;

            Assumes.NotNull(launchSettings);

            return(launchSettings);
        }
        private async Task <ILaunchProfile> GetActiveProfileAsync()
        {
            // Get the active debug profile (timeout of 5s, though in reality is should never take this long as even in error conditions
            // a snapshot is produced).
            ILaunchSettings?currentProfiles = await _launchSettingsProvider.WaitForFirstSnapshot(5000);

            ILaunchProfile?activeProfile = currentProfiles?.ActiveProfile;

            // Should have a profile
            if (activeProfile == null)
            {
                throw new Exception(VSResources.ActiveLaunchProfileNotFound);
            }

            return(activeProfile);
        }
        protected override async Task ExecuteAsync(ILaunchSettingsProvider launchSettingsProvider, CancellationToken cancellationToken)
        {
            ILaunchSettings?launchSettings = await launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite).WithCancellation(cancellationToken);

            Assumes.NotNull(launchSettings);

            ILaunchProfile?existingProfile = launchSettings.Profiles.FirstOrDefault(p => StringComparers.LaunchProfileNames.Equals(p.Name, _executableStep.CurrentProfileName));

            if (existingProfile is not null)
            {
                var writableProfile = new WritableLaunchProfile(existingProfile);
                writableProfile.Name        = _executableStep.NewProfileName;
                writableProfile.CommandName = _executableStep.NewProfileCommandName;

                await launchSettingsProvider.AddOrUpdateProfileAsync(writableProfile.ToLaunchProfile(), addToFront : false);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Handles the core logic of retrieving the property.
        /// </summary>
        /// <remarks>
        /// Since we're redirecting the properties through the <see cref="ILaunchSettingsProvider"/>
        /// there's no distinction between "evaluated" and "unevaluated" properties, so
        /// we handle both in the same way.
        /// </remarks>
        private async Task <string> GetPropertyValueAsync()
        {
            ILaunchSettings launchSettings = await _launchSettings.WaitForFirstSnapshot();

            return(launchSettings.ActiveProfile?.Name ?? string.Empty);
        }
        private async Task <string> GetPropertyValueAsync()
        {
            ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

            return(GetValueFromLaunchSettings(launchSettings.ActiveProfile));
        }