/// <summary>
        /// Creates the intiial set of settings based on the file on disk
        /// </summary>
        protected async Task <LaunchSettingsData> GetLaunchSettingsAsync()
        {
            string fileName = await GetLaunchSettingsFilePathAsync().ConfigureAwait(false);

            LaunchSettingsData settings;

            if (FileManager.FileExists(fileName))
            {
                settings = await ReadSettingsFileFromDiskAsync().ConfigureAwait(false);
            }
            else
            {
                // Still clear errors even if no file on disk. This handles the case where there was a file with errors on
                // disk and the user deletes the file.
                ClearErrors();
                settings = new LaunchSettingsData();
            }

            // Make sure there is at least an empty profile list
            if (settings.Profiles == null)
            {
                settings.Profiles = new List <LaunchProfileData>();
            }

            return(settings);
        }
예제 #2
0
        /// <summary>
        /// Re-applies in-memory profiles to the newly created snapshot. Note that we don't want to merge in the error
        /// profile
        /// </summary>
        protected static void MergeExistingInMemoryProfiles(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot)
        {
            for (int i = 0; i < prevSnapshot.Profiles.Count; i++)
            {
                ILaunchProfile profile = prevSnapshot.Profiles[i];
                if (profile.IsInMemoryObject() && !string.Equals(profile.CommandName, ErrorProfileCommandName))
                {
                    Assumes.NotNull(newSnapshot.Profiles);

                    // Does it already have one with this name?
                    if (newSnapshot.Profiles.FirstOrDefault((p1, p2) => LaunchProfile.IsSameProfileName(p1.Name, p2.Name), profile) == null)
                    {
                        // Create a new one from the existing in-memory profile and insert it in the same location, or the end if it
                        // is beyond the end of the list
                        if (i > newSnapshot.Profiles.Count)
                        {
                            newSnapshot.Profiles.Add(LaunchProfileData.FromILaunchProfile(profile));
                        }
                        else
                        {
                            newSnapshot.Profiles.Insert(i, LaunchProfileData.FromILaunchProfile(profile));
                        }
                    }
                }
            }
        }
예제 #3
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);
                }
            }
        }
        public LaunchSettings(LaunchSettingsData settingsData, string activeProfile = null)
        {
            Profiles = ImmutableList <ILaunchProfile> .Empty;
            foreach (var profile in settingsData.Profiles)
            {
                Profiles = Profiles.Add(new LaunchProfile(profile));
            }

            GlobalSettings     = settingsData.OtherSettings == null? ImmutableDictionary <string, object> .Empty : settingsData.OtherSettings.ToImmutableDictionary();
            _activeProfileName = activeProfile;
        }
예제 #5
0
        public LaunchSettings(LaunchSettingsData settingsData, string?activeProfile = null)
        {
            Requires.NotNull(settingsData.Profiles !, nameof(settingsData.Profiles));

            Profiles = ImmutableList <ILaunchProfile> .Empty;
            foreach (LaunchProfileData profile in settingsData.Profiles)
            {
                Profiles = Profiles.Add(new LaunchProfile(profile));
            }

            GlobalSettings     = settingsData.OtherSettings == null ? ImmutableStringDictionary <object> .EmptyOrdinal : settingsData.OtherSettings.ToImmutableDictionary();
            _activeProfileName = activeProfile;
        }
예제 #6
0
        /// <summary>
        /// Creates the initial set of settings based on the file on disk
        /// </summary>
        protected async Task <LaunchSettingsData> GetLaunchSettingsAsync()
        {
            string fileName = await GetLaunchSettingsFilePathAsync();

            LaunchSettingsData settings = _fileSystem.FileExists(fileName)
                ? await ReadSettingsFileFromDiskAsync()
                : new LaunchSettingsData();

            // Make sure there is at least an empty profile list
            settings.Profiles ??= new List <LaunchProfileData>();

            return(settings);
        }
예제 #7
0
        protected async Task <LaunchSettingsData> ReadSettingsFileFromDiskAsync()
        {
            string fileName = await GetLaunchSettingsFilePathAsync();

            string jsonString = _fileSystem.ReadAllText(fileName);

            // Since the sections in the settings file are extensible we iterate through each one and have the appropriate provider
            // serialize their section. Unfortunately, this means the data is string to object which is messy to deal with
            var launchSettingsData = new LaunchSettingsData()
            {
                OtherSettings = new Dictionary <string, object>(StringComparer.Ordinal)
            };
            var jsonObject = JObject.Parse(jsonString);

            foreach ((string key, JToken jToken) in jsonObject)
            {
                if (key.Equals(ProfilesSectionName, StringComparison.Ordinal) && jToken is JObject jObject)
                {
                    Dictionary <string, LaunchProfileData> profiles = LaunchProfileData.DeserializeProfiles(jObject);
                    launchSettingsData.Profiles = FixupProfilesAndLogErrors(profiles);
                }
                else
                {
                    // Find the matching json serialization handler for this section
                    Lazy <ILaunchSettingsSerializationProvider, IJsonSection> handler = JsonSerializationProviders.FirstOrDefault(sp => string.Equals(sp.Metadata.JsonSection, key));
                    if (handler != null)
                    {
                        object sectionObject = JsonConvert.DeserializeObject(jToken.ToString(), handler.Metadata.SerializationType);
                        launchSettingsData.OtherSettings.Add(key, sectionObject);
                    }
                    else
                    {
                        // We still need to remember settings for which we don't have an extensibility component installed. For this we
                        // just keep the jObject which can be serialized back out when the file is written.
                        launchSettingsData.OtherSettings.Add(key, jToken);
                    }
                }
            }

            // Remember the time we are sync'd to
            LastSettingsFileSyncTime = _fileSystem.LastFileWriteTime(fileName);
            return(launchSettingsData);
        }
 /// <summary>
 /// Re-applies in-memory global options to the newly created snapshot
 /// </summary>
 protected static void MergeExistingInMemoryGlobalSettings(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot)
 {
     if (prevSnapshot.GlobalSettings != null)
     {
         foreach (KeyValuePair <string, object> kvp in prevSnapshot.GlobalSettings)
         {
             if (kvp.Value.IsInMemoryObject())
             {
                 if (newSnapshot.OtherSettings == null)
                 {
                     newSnapshot.OtherSettings          = new Dictionary <string, object>();
                     newSnapshot.OtherSettings[kvp.Key] = kvp.Value;
                 }
                 else if (!newSnapshot.OtherSettings.TryGetValue(kvp.Key, out object existingValue))
                 {
                     newSnapshot.OtherSettings[kvp.Key] = kvp.Value;
                 }
             }
         }
     }
 }
예제 #9
0
        protected async Task <LaunchSettingsData> GetLaunchSettingsAsync()
        {
            string fileName = await GetLaunchSettingsFilePathAsync();

            LaunchSettingsData settings;

            if (_fileSystem.FileExists(fileName))
            {
                settings = await ReadSettingsFileFromDiskAsync();
            }
            else
            {
                settings = new LaunchSettingsData();
            }

            // Make sure there is at least an empty profile list
            if (settings.Profiles == null)
            {
                settings.Profiles = new List <LaunchProfileData>();
            }

            return(settings);
        }
예제 #10
0
 protected static void MergeExistingInMemoryGlobalSettings(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot)
 {
     if (prevSnapshot.GlobalSettings != null)
     {
         foreach ((string key, object value) in prevSnapshot.GlobalSettings)
         {
             if (value.IsInMemoryObject())
             {
                 if (newSnapshot.OtherSettings == null)
                 {
                     newSnapshot.OtherSettings = new Dictionary <string, object>
                     {
                         [key] = value
                     };
                 }
                 else if (!newSnapshot.OtherSettings.TryGetValue(key, out _))
                 {
                     newSnapshot.OtherSettings[key] = value;
                 }
             }
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Creates the intiial set of settings based on the file on disk
        /// </summary>
        protected LaunchSettingsData GetLaunchSettings()
        {
            LaunchSettingsData settings;

            if (FileManager.FileExists(LaunchSettingsFile))
            {
                settings = ReadSettingsFileFromDisk();
            }
            else
            {
                // Still clear errors even if no file on disk. This handles the case where there was a file with errors on
                // disk and the user deletes the file.
                ClearErrors();
                settings = new LaunchSettingsData();
            }

            // Make sure there is at least an empty profile list
            if (settings.Profiles == null)
            {
                settings.Profiles = new List <LaunchProfileData>();
            }

            return(settings);
        }
 /// <summary>
 /// Re-applies in-memory profiles to the newly created snapshot
 /// </summary>
 protected void MergeExistingInMemoryProfiles(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot)
 {
     for (int i = 0; i < prevSnapshot.Profiles.Count; i++)
     {
         var profile = prevSnapshot.Profiles[i];
         if (profile.IsInMemoryObject())
         {
             // Does it already have one with this name?
             if (newSnapshot.Profiles.FirstOrDefault(p => LaunchProfile.IsSameProfileName(p.Name, profile.Name)) == null)
             {
                 // Create a new one from the existing in-memory profile and insert it in the same location, or the end if it
                 // is beyond the end of the list
                 if (i > newSnapshot.Profiles.Count)
                 {
                     newSnapshot.Profiles.Add(LaunchProfileData.FromILaunchProfile(profile));
                 }
                 else
                 {
                     newSnapshot.Profiles.Insert(i, LaunchProfileData.FromILaunchProfile(profile));
                 }
             }
         }
     }
 }
예제 #13
0
        /// <summary>
        /// Reads the data from the launch settings file and returns it in a dictionary of settings section to object. Adds n error list entries
        /// and throws if an exception occurs
        /// </summary>
        protected LaunchSettingsData ReadSettingsFileFromDisk()
        {
            // Clear errors
            ClearErrors();
            try
            {
                string jsonString = FileManager.ReadAllText(LaunchSettingsFile);

                // Since the sections in the settings file are extensible we iterate through each one and have the appropriate provider
                // serialize their section. Unfortunately, this means the data is string to object which is messy to deal with
                var launchSettingsData = new LaunchSettingsData()
                {
                    OtherSettings = new Dictionary <string, object>(StringComparer.Ordinal)
                };
                JObject jsonObject = JObject.Parse(jsonString);
                foreach (var pair in jsonObject)
                {
                    if (pair.Key.Equals(ProfilesSectionName, StringComparison.Ordinal) && pair.Value is JObject)
                    {
                        var profiles = LaunchProfileData.DeserializeProfiles((JObject)pair.Value);
                        launchSettingsData.Profiles = FixupProfilesAndLogErrors(profiles);
                    }
                    else
                    {
                        // Find the matching json serialization handler for this section
                        var handler = JsonSerializationProviders.FirstOrDefault(sp => string.Equals(sp.Metadata.JsonSection, pair.Key));
                        if (handler != null)
                        {
                            object sectionObject = JsonConvert.DeserializeObject(pair.Value.ToString(), handler.Metadata.SerializationType);
                            launchSettingsData.OtherSettings.Add(pair.Key, sectionObject);
                        }
                        else
                        {
                            // We still need to remember settings for which we don't have an extensibility component installed. For this we
                            // just keep the jObject which can be serialized back out when the file is written.
                            launchSettingsData.OtherSettings.Add(pair.Key, pair.Value);
                        }
                    }
                }

                // Remember the time we are sync'd to
                LastSettingsFileSyncTime = FileManager.LastFileWriteTime(LaunchSettingsFile);
                return(launchSettingsData);
            }
            catch (JsonReaderException readerEx)
            {
                string err = string.Format(Resources.JsonErrorReadingLaunchSettings, readerEx.Message);
                LogError(err, LaunchSettingsFile, readerEx.LineNumber, readerEx.LinePosition, false);
                throw;
            }
            catch (JsonException jsonEx)
            {
                string err = string.Format(Resources.JsonErrorReadingLaunchSettings, jsonEx.Message);
                LogError(err, LaunchSettingsFile, -1, -1, false);
                throw;
            }
            catch (Exception ex)
            {
                string err = string.Format(Resources.ErrorReadingLaunchSettings, Path.Combine(LaunchSettingsFileFolder, LaunchSettingsFilename), ex.Message);
                LogError(err, false);
                throw;
            }
        }