Esempio n. 1
0
        protected async Task UpdateProfilesAsync(string updatedActiveProfileName)
        {
            try
            {
                // If the name of the new active profile wasn't provided we'll continue to use the
                // current one.
                if (updatedActiveProfileName == null)
                {
                    ProjectDebugger props = await _commonProjectServices.ActiveConfiguredProjectProperties.GetProjectDebuggerPropertiesAsync();

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

                LaunchSettingsData launchSettingData = await GetLaunchSettingsAsync();

                // If there are no profiles, we will add a default profile to run the project. 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
                ILaunchSettings prevSnapshot = CurrentSnapshot;
                if (prevSnapshot != null)
                {
                    MergeExistingInMemoryProfiles(launchSettingData, prevSnapshot);
                    MergeExistingInMemoryGlobalSettings(launchSettingData, prevSnapshot);
                }

                var newSnapshot = new LaunchSettings(launchSettingData, updatedActiveProfileName);

                FinishUpdate(newSnapshot);
            }
            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,
                        OtherSettings = ImmutableStringDictionary <object> .EmptyOrdinal.Add("ErrorString", ex.Message)
                    };
                    var snapshot = new LaunchSettings(new[] { errorProfile }, null, errorProfile.Name);
                    FinishUpdate(snapshot);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Does the processing to update the profiles when changes have been made to either the file, the active profile or projectData. Note that
        /// any of the parmaters can be null. This code must handle that correctly. Setting existingProfiles to null effectively re-intilaizes the
        /// entire list.
        /// </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(true);

                    var activeProfileVal = await props.ActiveDebugProfile.GetValueAsync().ConfigureAwait(true) as IEnumValue;

                    if (activeProfileVal != null)
                    {
                        activeProfile = activeProfileVal.Name;
                    }
                }

                var launchSettingData = GetLaunchSettings();


                // 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
                    });
                }

                var newSnapshot = new LaunchSettings(launchSettingData, activeProfile);

                FinishUpdate(newSnapshot);
            }
            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 = LaunchSettingsProvider.ErrorProfileCommandName
                    };
                    errorProfile.OtherSettings = ImmutableDictionary <string, object> .Empty.Add("ErrorString", ex.Message);

                    var snapshot = new LaunchSettings(new List <ILaunchProfile>()
                    {
                        errorProfile
                    }, null, errorProfile.Name);
                    FinishUpdate(snapshot);
                }
            }
        }
        /// <summary>
        /// Removes the specified global setting and saves the settings to disk
        /// </summary>
        public async Task RemoveGlobalSettingAsync(string settingName)
        {
            var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false);

            if (currentSettings.GlobalSettings.TryGetValue(settingName, out object currentValue))
            {
                var globalSettings = currentSettings.GlobalSettings.Remove(settingName);
                var newSnapshot    = new LaunchSettings(currentSettings.Profiles, globalSettings, currentSettings.ActiveProfile?.Name);
                await UpdateAndSaveSettingsAsync(newSnapshot).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Called when the active profile has changed. If there is a current snapshot it just updates that. Otherwwise, it creates
        /// a new snapshot
        /// </summary>
        protected async Task UpdateActiveProfileInSnapshotAsync(string activeProfile)
        {
            var snapshot = CurrentSnapshot;
            if (snapshot == null || await SettingsFileHasChangedAsync().ConfigureAwait(false))
            {
                await UpdateProfilesAsync(activeProfile).ConfigureAwait(false);
                return;
            }

            var newSnapshot = new LaunchSettings(snapshot.Profiles, snapshot.GlobalSettings, activeProfile);
            await FinishUpdateAsync(newSnapshot, ensureProfileProperty: false).ConfigureAwait(false);
        }
Esempio n. 5
0
        /// <summary>
        /// Replaces the current set of profiles with the contents of profiles. If changes were
        /// made, the file will be checked out and saved.
        /// </summary>
        public async Task UpdateAndSaveSettingsAsync(ILaunchSettings newSettings)
        {
            // Make sure the profiles are copied. We don't want them to mutate.
            ILaunchSettings newSnapshot = new LaunchSettings(newSettings.Profiles, newSettings.GlobalSettings, newSettings.ActiveProfile?.Name);

            // Being saved and changeMade are different since the active profile change does not require them to be saved.
            await CheckoutSettingsFileAsync().ConfigureAwait(false);

            SaveSettingsToDisk(newSettings);

            FinishUpdate(newSnapshot);
        }
        /// <summary>
        /// Removes the specified profile from the list and saves to disk.
        /// </summary>
        public async Task RemoveProfileAsync(string profileName)
        {
            var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false);

            var existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName));

            if (existingProfile != null)
            {
                var profiles    = currentSettings.Profiles.Remove(existingProfile);
                var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name);
                await UpdateAndSaveSettingsAsync(newSnapshot).ConfigureAwait(false);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Replaces the current set of profiles with the contents of profiles. If changes were
        /// made, the file will be checked out and saved. Note it ignores the value of the active profile
        /// as this setting is controlled by a user property.
        /// </summary>
        private async Task UpdateAndSaveSettingsInternalAsync(ILaunchSettings newSettings)
        {
            await CheckoutSettingsFileAsync().ConfigureAwait(false);

            // Make sure the profiles are copied. We don't want them to mutate.
            var activeProfileName = ActiveProfile?.Name;

            ILaunchSettings newSnapshot = new LaunchSettings(newSettings.Profiles, newSettings.GlobalSettings, activeProfileName);

            SaveSettingsToDisk(newSettings);

            FinishUpdate(newSnapshot);
        }
Esempio n. 8
0
 /// <summary>
 /// Removes the specified global setting and saves the settings to disk
 /// </summary>
 public async Task RemoveGlobalSettingAsync(string settingName)
 {
     // Updates need to be sequenced
     await _sequentialTaskQueue.ExecuteTask(async() =>
     {
         var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false);
         if (currentSettings.GlobalSettings.TryGetValue(settingName, out object currentValue))
         {
             var globalSettings = currentSettings.GlobalSettings.Remove(settingName);
             var newSnapshot    = new LaunchSettings(currentSettings.Profiles, globalSettings, currentSettings.ActiveProfile?.Name);
             await UpdateAndSaveSettingsInternalAsync(newSnapshot).ConfigureAwait(false);
         }
     }).ConfigureAwait(false);
 }
        /// <summary>
        /// Called when the active profile has changed. If there is a current snapshot it just updates that. Otherwise, it creates
        /// a new snapshot
        /// </summary>
        protected async Task UpdateActiveProfileInSnapshotAsync(string updatedActiveProfileName)
        {
            ILaunchSettings snapshot = CurrentSnapshot;

            if (snapshot == null || await SettingsFileHasChangedAsync())
            {
                await UpdateProfilesAsync(updatedActiveProfileName);

                return;
            }

            var newSnapshot = new LaunchSettings(snapshot.Profiles, snapshot.GlobalSettings, updatedActiveProfileName);

            FinishUpdate(newSnapshot);
        }
        /// <summary>
        /// Replaces the current set of profiles with the contents of profiles. If changes were
        /// made, the file will be checked out and saved. Note it ignores the value of the active profile
        /// as this setting is controlled by a user property.
        /// </summary>
        private async Task UpdateAndSaveSettingsInternalAsync(ILaunchSettings newSettings, bool persistToDisk = true)
        {
            await CheckoutSettingsFileAsync().ConfigureAwait(false);

            // Make sure the profiles are copied. We don't want them to mutate.
            var activeProfileName = ActiveProfile?.Name;

            ILaunchSettings newSnapshot = new LaunchSettings(newSettings.Profiles, newSettings.GlobalSettings, activeProfileName);
            if (persistToDisk)
            {
                await SaveSettingsToDiskAsync(newSettings).ConfigureAwait(false);
            }

            await FinishUpdateAsync(newSnapshot, ensureProfileProperty: true).ConfigureAwait(false);
        }
Esempio n. 11
0
 public Task RemoveGlobalSettingAsync(string settingName)
 {
     // Updates need to be sequenced
     return(_sequentialTaskQueue.ExecuteTask(async() =>
     {
         ILaunchSettings currentSettings = await GetSnapshotThrowIfErrors();
         if (currentSettings.GlobalSettings.TryGetValue(settingName, out object currentValue))
         {
             bool saveToDisk = !currentValue.IsInMemoryObject();
             ImmutableDictionary <string, object> globalSettings = currentSettings.GlobalSettings.Remove(settingName);
             var newSnapshot = new LaunchSettings(currentSettings.Profiles, globalSettings, currentSettings.ActiveProfile?.Name);
             await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk);
         }
     }));
 }
Esempio n. 12
0
 /// <summary>
 /// Removes the specified profile from the list and saves to disk.
 /// </summary>
 public async Task RemoveProfileAsync(string profileName)
 {
     // Updates need to be sequenced
     await _sequentialTaskQueue.ExecuteTask(async() =>
     {
         var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false);
         var existingProfile = currentSettings.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profileName));
         if (existingProfile != null)
         {
             var profiles    = currentSettings.Profiles.Remove(existingProfile);
             var newSnapshot = new LaunchSettings(profiles, currentSettings.GlobalSettings, currentSettings.ActiveProfile?.Name);
             await UpdateAndSaveSettingsInternalAsync(newSnapshot).ConfigureAwait(false);
         }
     }).ConfigureAwait(false);
 }
Esempio n. 13
0
        public Task AddOrUpdateProfileAsync(ILaunchProfile profile, bool addToFront)
        {
            // Updates need to be sequenced
            return(_sequentialTaskQueue.ExecuteTask(async() =>
            {
                ILaunchSettings currentSettings = await GetSnapshotThrowIfErrors();
                ILaunchProfile existingProfile = null;
                int insertionIndex = 0;
                foreach (ILaunchProfile p in currentSettings.Profiles)
                {
                    if (LaunchProfile.IsSameProfileName(p.Name, profile.Name))
                    {
                        existingProfile = p;
                        break;
                    }
                    insertionIndex++;
                }

                ImmutableList <ILaunchProfile> profiles;
                if (existingProfile != null)
                {
                    profiles = currentSettings.Profiles.Remove(existingProfile);
                }
                else
                {
                    profiles = currentSettings.Profiles;
                }

                if (addToFront)
                {
                    profiles = profiles.Insert(0, new LaunchProfile(profile));
                }
                else
                {
                    // Insertion index will be set to the current count (end of list) if an existing item was not found otherwise
                    // it will point to where the previous one was found
                    profiles = profiles.Insert(insertionIndex, new LaunchProfile(profile));
                }

                // If the new profile is in-memory only, we don't want to touch the disk unless it replaces an existing disk based
                // profile
                bool saveToDisk = !profile.IsInMemoryObject() || (existingProfile != null && !existingProfile.IsInMemoryObject());

                var newSnapshot = new LaunchSettings(profiles, currentSettings?.GlobalSettings, currentSettings?.ActiveProfile?.Name);
                await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk);
            }));
        }
Esempio n. 14
0
        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>
        /// Replaces the current set of profiles with the contents of profiles. If changes were
        /// made, the file will be checked out and saved. Note it ignores the value of the active profile
        /// as this setting is controlled by a user property.
        /// </summary>
        protected async Task UpdateAndSaveSettingsInternalAsync(ILaunchSettings newSettings, bool persistToDisk = true)
        {
            if (persistToDisk)
            {
                await CheckoutSettingsFileAsync();
            }

            // Make sure the profiles are copied. We don't want them to mutate.
            string?activeProfileName = ActiveProfile?.Name;

            ILaunchSettings newSnapshot = new LaunchSettings(newSettings.Profiles, newSettings.GlobalSettings, activeProfileName);

            if (persistToDisk)
            {
                await SaveSettingsToDiskAsync(newSettings);
            }

            FinishUpdate(newSnapshot);
        }
        /// <summary>
        /// Adds or updates the global settings represented by settingName. Saves the
        /// updated settings to disk. Note that the settings object must be serializable.
        /// </summary>
        public async Task AddOrUpdateGlobalSettingAsync(string settingName, object settingContent)
        {
            var currentSettings = await GetSnapshotThrowIfErrors().ConfigureAwait(false);

            ImmutableDictionary <string, object> globalSettings = ImmutableDictionary <string, object> .Empty;

            if (currentSettings.GlobalSettings.TryGetValue(settingName, out object currentValue))
            {
                globalSettings = currentSettings.GlobalSettings.Remove(settingName);
            }
            else
            {
                globalSettings = currentSettings.GlobalSettings;
            }

            var newSnapshot = new LaunchSettings(currentSettings.Profiles, globalSettings.Add(settingName, settingContent), currentSettings.ActiveProfile?.Name);

            await UpdateAndSaveSettingsAsync(newSnapshot).ConfigureAwait(false);
        }
Esempio n. 17
0
        /// <summary>
        /// Adds the given profile to the list and saves to disk. If a profile with the same
        /// name exists (case sensitive), it will be replaced with the new profile. If addToFront is
        /// true the profile will be the first one in the list. This is useful since quite often callers want
        /// their just added profile to be listed first in the start menu. If addToFront is false but there is
        /// an existing profile, the new one will be inserted at the same location rather than at the end.
        /// </summary>
        public async Task AddOrUpdateProfileAsync(ILaunchProfile profile, bool addToFront)
        {
            // Updates need to be sequenced
            await _sequentialTaskQueue.ExecuteTask(async() =>
            {
                var currentSettings            = await GetSnapshotThrowIfErrors().ConfigureAwait(false);
                ILaunchProfile existingProfile = null;
                int insertionIndex             = 0;
                foreach (var p in currentSettings.Profiles)
                {
                    if (LaunchProfile.IsSameProfileName(p.Name, profile.Name))
                    {
                        existingProfile = p;
                        break;
                    }
                    insertionIndex++;
                }

                ImmutableList <ILaunchProfile> profiles;
                if (existingProfile != null)
                {
                    profiles = currentSettings.Profiles.Remove(existingProfile);
                }
                else
                {
                    profiles = currentSettings.Profiles;
                }

                if (addToFront)
                {
                    profiles = profiles.Insert(0, new LaunchProfile(profile));
                }
                else
                {
                    // Insertion index will be set to the current count (end of list) if an existing item was not found otherwise
                    // it will point to where the previous one was found
                    profiles = profiles.Insert(insertionIndex, new LaunchProfile(profile));
                }

                var newSnapshot = new LaunchSettings(profiles, currentSettings?.GlobalSettings, currentSettings?.ActiveProfile?.Name);
                await UpdateAndSaveSettingsInternalAsync(newSnapshot).ConfigureAwait(false);
            }).ConfigureAwait(false);
        }
        public void LaunchSettings_CtorTests()
        {
            var profiles = new List <LaunchProfile>()
            {
                new LaunchProfile()
                {
                    Name = "abc", CommandLineArgs = "test"
                },
                new LaunchProfile()
                {
                    Name = "def"
                },
                new LaunchProfile()
                {
                    Name = "ghi"
                },
                new LaunchProfile()
                {
                    Name = "foo"
                },
            };
            var globals = new Dictionary <string, object>()
            {
                { "var1", true },
                { "var2", "some string" }
            };

            var settings = new LaunchSettings(profiles, null, null);

            Assert.True(settings.ActiveProfile.Name == "abc");
            Assert.Equal(profiles.Count, settings.Profiles.Count);
            Assert.Empty(settings.GlobalSettings);

            settings = new LaunchSettings(profiles, null, "ghi");
            Assert.True(settings.ActiveProfile.Name == "ghi");

            // Test
            settings = new LaunchSettings(profiles, globals, "foo");
            Assert.Equal(globals.Count, settings.GlobalSettings.Count);
        }
Esempio n. 19
0
        public Task AddOrUpdateGlobalSettingAsync(string settingName, object settingContent)
        {
            // Updates need to be sequenced
            return(_sequentialTaskQueue.ExecuteTask(async() =>
            {
                ILaunchSettings currentSettings = await GetSnapshotThrowIfErrors();
                ImmutableDictionary <string, object> globalSettings = ImmutableStringDictionary <object> .EmptyOrdinal;
                if (currentSettings.GlobalSettings.TryGetValue(settingName, out object currentValue))
                {
                    globalSettings = currentSettings.GlobalSettings.Remove(settingName);
                }
                else
                {
                    globalSettings = currentSettings.GlobalSettings;
                }

                bool saveToDisk = !settingContent.IsInMemoryObject() || (currentValue != null && !currentValue.IsInMemoryObject());

                var newSnapshot = new LaunchSettings(currentSettings.Profiles, globalSettings.Add(settingName, settingContent), currentSettings.ActiveProfile?.Name);
                await UpdateAndSaveSettingsInternalAsync(newSnapshot, saveToDisk);
            }));
        }