public void LaunchProfile_IsSameProfileNameTests()
 {
     Assert.True(LaunchProfile.IsSameProfileName("test", "test"));
     Assert.False(LaunchProfile.IsSameProfileName("test", "Test"));
 }
        /// <summary>
        /// Removes the specified profile from the list and saves to disk.
        /// </summary>
        public Task RemoveProfileAsync(string profileName)
        {
            // Updates need to be sequenced
            return(_sequentialTaskQueue.ExecuteTask(async() =>
            {
                ILaunchSettings currentSettings = await GetSnapshotThrowIfErrors();
                ILaunchProfile existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName));
                if (existingProfile != null)
                {
                    ImmutableList <ILaunchProfile> profiles = currentSettings.Profiles.Remove(existingProfile);

                    // If the new profile is in-memory only, we don't want to touch the disk
                    bool saveToDisk = !existingProfile.IsInMemoryObject();
                    var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name);
                    await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk);
                }
            }));
        }
        /// <summary>
        /// Does the processing to update the profiles when changes have been made to either the file or the active profile.
        /// When merging with the disk, it needs to honor in-memory only profiles that may have been programmatically added. If
        /// a profile on disk has the same name as an in-memory profile, the one on disk wins. It tries to add the in-memory profiles
        /// in the same order they appeared prior to the disk change.
        /// </summary>
        protected async Task UpdateProfilesAsync(string activeProfile)
        {
            try
            {
                // If no active profile specified, try to get one
                if (activeProfile == null)
                {
                    var props = await CommonProjectServices.ActiveConfiguredProjectProperties.GetProjectDebuggerPropertiesAsync().ConfigureAwait(false);

                    if (await props.ActiveDebugProfile.GetValueAsync().ConfigureAwait(false) is IEnumValue activeProfileVal)
                    {
                        activeProfile = activeProfileVal.Name;
                    }
                }

                var launchSettingData = await GetLaunchSettingsAsync().ConfigureAwait(false);

                // If there are no profiles, we will add a default profile to run the prroject. W/o it our debugger
                // won't be called on F5 and the user will see a poor error message
                if (launchSettingData.Profiles.Count == 0)
                {
                    launchSettingData.Profiles.Add(new LaunchProfileData()
                    {
                        Name = Path.GetFileNameWithoutExtension(CommonProjectServices.Project.FullPath), CommandName = RunProjectCommandName
                    });
                }

                // If we have a previous snapshot merge in in-memory profiles
                var prevSnapshot = CurrentSnapshot;
                if (prevSnapshot != null)
                {
                    MergeExistingInMemoryProfiles(launchSettingData, prevSnapshot);
                    MergeExistingInMemoryGlobalSettings(launchSettingData, prevSnapshot);
                }

                var newSnapshot = new LaunchSettings(launchSettingData, activeProfile);

                await FinishUpdateAsync(newSnapshot, ensureProfileProperty : true).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                // Errors are added as error list entries. We don't want to throw out of here
                // However, if we have never created a snapshot it means there is some error in the file and we want
                // to have the user see that, so we add a dummy profile which will bind to an existing debugger which will
                // display the error when run
                if (CurrentSnapshot == null)
                {
                    var errorProfile = new LaunchProfile()
                    {
                        Name = Resources.NoActionProfileName, CommandName = ErrorProfileCommandName, DoNotPersist = true
                    };
                    errorProfile.OtherSettings = ImmutableStringDictionary <object> .EmptyOrdinal.Add("ErrorString", ex.Message);

                    var snapshot = new LaunchSettings(new List <ILaunchProfile>()
                    {
                        errorProfile
                    }, null, errorProfile.Name);
                    await FinishUpdateAsync(snapshot, ensureProfileProperty : false).ConfigureAwait(false);
                }
            }
        }
 /// <summary>
 /// See <see cref="IDynamicEnumValuesGenerator"/>
 /// </summary>
 public async Task <IEnumValue> TryCreateEnumValueAsync(string userSuppliedValue)
 {
     return((await _listedValues.GetValueAsync().ConfigureAwait(true))
            .FirstOrDefault(v => LaunchProfile.IsSameProfileName(v.Name, userSuppliedValue)));
 }