/// <summary> /// Gets the serialization object for the set of profiles and custom settings. It filters out built in profiles that get added to /// wire up the debugger infrastructure (NoAction profiles). Returns a dictionary of the elements to serialize. /// </summary> protected Dictionary <string, object> GetSettingsToSerialize(ILaunchSettings curSettings) { var profileData = new Dictionary <string, Dictionary <string, object> >(StringComparer.Ordinal); foreach (var profile in curSettings.Profiles) { if (ProfileShouldBePersisted(profile)) { profileData.Add(profile.Name, LaunchProfileData.ToSerializableForm(profile)); } } Dictionary <string, object> dataToSave = new Dictionary <string, object>(StringComparer.Ordinal); foreach (var setting in curSettings.GlobalSettings) { dataToSave.Add(setting.Key, setting.Value); } if (profileData.Count > 0) { dataToSave.Add(ProfilesSectionName, profileData); } return(dataToSave); }
/// <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)); } } } } }
public void LaunchProfileData_FromILaunchProfileTests(bool isInMemory) { var profile = new LaunchProfile() { Name = "Test", CommandName = "Test", ExecutablePath = "c:\\this\\is\\a\\exe\\path", CommandLineArgs = "args", WorkingDirectory = "c:\\working\\directory\\", LaunchBrowser = true, LaunchUrl = "LaunchPage.html", EnvironmentVariables = new Dictionary <string, string>() { { "var1", "Value1" }, { "var2", "Value2" } }.ToImmutableDictionary(), OtherSettings = new Dictionary <string, object>(StringComparer.Ordinal) { { "setting1", true }, { "setting2", "mysetting" } }.ToImmutableDictionary(), DoNotPersist = isInMemory }; var data = LaunchProfileData.FromILaunchProfile(profile); Assert.Equal(data.Name, profile.Name); Assert.Equal(data.ExecutablePath, profile.ExecutablePath); Assert.Equal(data.CommandLineArgs, profile.CommandLineArgs); Assert.Equal(data.WorkingDirectory, profile.WorkingDirectory); Assert.Equal(data.LaunchBrowser, profile.LaunchBrowser); Assert.Equal(data.LaunchUrl, profile.LaunchUrl); Assert.Equal(data.EnvironmentVariables.ToImmutableDictionary(), profile.EnvironmentVariables, DictionaryEqualityComparer <string, string> .Instance); Assert.True(DictionaryEqualityComparer <string, string> .Instance.Equals(data.EnvironmentVariables.ToImmutableDictionary(), profile.EnvironmentVariables)); Assert.Equal(isInMemory, data.InMemoryProfile); }
/// <summary> /// Gets the serialization object for the set of profiles and custom settings. It filters out built in profiles that get added to /// wire up the debugger infrastructure (NoAction profiles). Returns a dictionary of the elements to serialize. /// Removes in-memory profiles and global objects /// </summary> protected static Dictionary <string, object> GetSettingsToSerialize(ILaunchSettings curSettings) { var profileData = new Dictionary <string, Dictionary <string, object> >(StringComparer.Ordinal); foreach (ILaunchProfile profile in curSettings.Profiles) { if (ProfileShouldBePersisted(profile)) { profileData.Add(profile.Name, LaunchProfileData.ToSerializableForm(profile)); } } var dataToSave = new Dictionary <string, object>(StringComparer.Ordinal); foreach ((string key, object value) in curSettings.GlobalSettings) { if (!value.IsInMemoryObject()) { dataToSave.Add(key, value); } } if (profileData.Count > 0) { dataToSave.Add(ProfilesSectionName, profileData); } return(dataToSave); }
public void LaunchProfileData_DeserializeEmptyProfilesTests() { var jsonObject = JObject.Parse(JsonString2); var profiles = LaunchProfileData.DeserializeProfiles((JObject)jsonObject["profiles"]); Assert.Empty(profiles); }
public void LaunchProfileData_DeserializeEmptyProfilesTests() { JObject jsonObject = JObject.Parse(JsonString2); var profiles = LaunchProfileData.DeserializeProfiles((JObject)jsonObject["profiles"]); Assert.Equal(0, profiles.Count); }
/// <summary> /// To handle custom settings, we serialize using LaunchProfileData first and then walk the settings /// to pick up other settings. Currently limited to boolean, integer, string and dictionary of string /// </summary> public static Dictionary <string, LaunchProfileData> DeserializeProfiles(JObject profilesObject) { var profiles = new Dictionary <string, LaunchProfileData>(StringComparers.LaunchProfileNames); if (profilesObject == null) { return(profiles); } // We walk the profilesObject and serialize each subobject component as either a string, or a dictionary<string,string> foreach ((string key, JToken jToken) in profilesObject) { // Name of profile is the key, value is it's contents. We have specific serializing of the data based on the // JToken type LaunchProfileData profileData = JsonConvert.DeserializeObject <LaunchProfileData>(jToken.ToString()); // Now pick up any custom properties. Handle string, int, boolean var customSettings = new Dictionary <string, object>(StringComparers.LaunchProfileProperties); foreach (JToken data in jToken.Children()) { if (data is JProperty property && !IsKnownProfileProperty(property.Name)) { try { object?value = property.Value.Type switch { JTokenType.Boolean => bool.Parse(property.Value.ToString()), JTokenType.Integer => int.Parse(property.Value.ToString()), JTokenType.Object => JsonConvert.DeserializeObject <Dictionary <string, string> >(property.Value.ToString()), JTokenType.String => property.Value.ToString(), _ => null }; if (value != null) { customSettings.Add(property.Name, value); } } catch { // TODO: should have message indicating the setting is being ignored. Fix as part of issue // https://github.com/dotnet/project-system/issues/424 } } } // Only add custom settings if we actually picked some up if (customSettings.Count > 0) { profileData.OtherSettings = customSettings; } profiles.Add(key, profileData); } return(profiles); }
public void LaunchProfileData_IsKnownPropertyTests() { Assert.True(LaunchProfileData.IsKnownProfileProperty("commandName")); Assert.True(LaunchProfileData.IsKnownProfileProperty("executablePath")); Assert.True(LaunchProfileData.IsKnownProfileProperty("commandLineArgs")); Assert.True(LaunchProfileData.IsKnownProfileProperty("workingDirectory")); Assert.True(LaunchProfileData.IsKnownProfileProperty("launchBrowser")); Assert.True(LaunchProfileData.IsKnownProfileProperty("launchUrl")); Assert.True(LaunchProfileData.IsKnownProfileProperty("environmentVariables")); Assert.False(LaunchProfileData.IsKnownProfileProperty("CommandName")); Assert.False(LaunchProfileData.IsKnownProfileProperty("applicationUrl")); }
public LaunchProfile(LaunchProfileData data) { Name = data.Name; ExecutablePath = data.ExecutablePath; CommandName = data.CommandName; CommandLineArgs = data.CommandLineArgs; WorkingDirectory = data.WorkingDirectory; LaunchBrowser = data.LaunchBrowser ?? false; LaunchUrl = data.LaunchUrl; EnvironmentVariables = data.EnvironmentVariables == null ? null : ImmutableDictionary <string, string> .Empty.AddRange(data.EnvironmentVariables); OtherSettings = data.OtherSettings == null ? null : ImmutableDictionary <string, object> .Empty.AddRange(data.OtherSettings); }
public LaunchProfile(LaunchProfileData data) { Name = data.Name; ExecutablePath = data.ExecutablePath; CommandName = data.CommandName; CommandLineArgs = data.CommandLineArgs; WorkingDirectory = data.WorkingDirectory; LaunchBrowser = data.LaunchBrowser ?? false; LaunchUrl = data.LaunchUrl; EnvironmentVariables = data.EnvironmentVariables?.ToImmutableDictionary(); OtherSettings = data.OtherSettings?.ToImmutableDictionary(); DoNotPersist = data.InMemoryProfile; }
public void LaunchProfileData_DeserializeProfilesTests() { var jsonObject = JObject.Parse(JsonString1); var profiles = LaunchProfileData.DeserializeProfiles((JObject?)jsonObject["profiles"]); Assert.Equal(4, profiles.Count); var profile = profiles["IIS Express"]; Assert.Equal("IISExpress", profile.CommandName); Assert.Equal("http://localhost:1234:/test.html", profile.LaunchUrl); Assert.True(profile.LaunchBrowser); Assert.False(profile.InMemoryProfile); profile = profiles["HasCustomValues"]; Assert.Equal("c:\\test\\project", profile.WorkingDirectory); Assert.Equal("c:\\test\\project\\bin\\project.exe", profile.ExecutablePath); Assert.Null(profile.LaunchBrowser); Assert.Null(profile.LaunchUrl); Assert.Null(profile.EnvironmentVariables); Assert.NotNull(profile.OtherSettings); Assert.True((bool)profile.OtherSettings["custom1"]); Assert.Equal(124, profile.OtherSettings["custom2"]); Assert.Equal("mycustomVal", profile.OtherSettings["custom3"]); Assert.False(profile.InMemoryProfile); profile = profiles["Docker"]; Assert.Equal("Docker", profile.CommandName); Assert.Null(profile.WorkingDirectory); Assert.Null(profile.ExecutablePath); Assert.False(profile.LaunchBrowser); Assert.Null(profile.LaunchUrl); Assert.Null(profile.EnvironmentVariables); Assert.NotNull(profile.OtherSettings); Assert.Equal("some option in docker", profile.OtherSettings["dockerOption1"]); Assert.Equal("Another option in docker", profile.OtherSettings["dockerOption2"]); Assert.False(profile.InMemoryProfile); profile = profiles["web"]; Assert.Equal("Project", profile.CommandName); Assert.Null(profile.WorkingDirectory); Assert.Null(profile.ExecutablePath); Assert.True(profile.LaunchBrowser); Assert.Null(profile.LaunchUrl); Assert.NotNull(profile.EnvironmentVariables); Assert.Equal("Development", profile.EnvironmentVariables["ASPNET_ENVIRONMENT"]); Assert.Equal("c:\\Users\\billhie\\Documents\\projects\\WebApplication8\\src\\WebApplication8", profile.EnvironmentVariables["ASPNET_APPLICATIONBASE"]); Assert.Null(profile.OtherSettings); Assert.False(profile.InMemoryProfile); }
/// <summary> /// Helper to convert an ILaunchProfile back to its serializable form. It does some /// fixup. Like setting empty values to null. /// </summary> public static LaunchProfileData FromILaunchProfile(ILaunchProfile profile) { var data = new LaunchProfileData(); data.Name = profile.Name; data.ExecutablePath = profile.ExecutablePath; data.CommandName = profile.CommandName; data.CommandLineArgs = profile.CommandLineArgs; data.WorkingDirectory = profile.WorkingDirectory; data.LaunchBrowser = profile.LaunchBrowser; data.LaunchUrl = profile.LaunchUrl; data.EnvironmentVariables = profile.EnvironmentVariables; data.OtherSettings = profile.OtherSettings; return(data); }
public void LaunchProfile_CtorTests() { var data = new LaunchProfileData() { Name = "Test", ExecutablePath = "c:\\this\\is\\a\\exe\\path", CommandName = null, CommandLineArgs = "args", WorkingDirectory = "c:\\working\\directory\\", LaunchBrowser = true, LaunchUrl = "LaunchPage.html", EnvironmentVariables = new Dictionary <string, string>() { { "var1", "Value1" }, { "var2", "Value2" } }, OtherSettings = new Dictionary <string, object>(StringComparer.Ordinal) { { "setting1", true }, { "setting2", "mysetting" } }, InMemoryProfile = true }; var profile = new LaunchProfile(data); Assert.Equal(data.Name, profile.Name); Assert.Equal(data.ExecutablePath, profile.ExecutablePath); Assert.Equal(data.CommandLineArgs, profile.CommandLineArgs); Assert.Equal(data.WorkingDirectory, profile.WorkingDirectory); Assert.Equal(data.LaunchBrowser, profile.LaunchBrowser); Assert.Equal(data.LaunchUrl, profile.LaunchUrl); Assert.True(DictionaryEqualityComparer <string, string> .Instance.Equals(data.EnvironmentVariables.ToImmutableDictionary(), profile.EnvironmentVariables !)); Assert.True(DictionaryEqualityComparer <string, object> .Instance.Equals(data.OtherSettings.ToImmutableDictionary(), profile.OtherSettings !)); Assert.Equal(data.InMemoryProfile, profile.DoNotPersist); // Test overload var profile2 = new LaunchProfile(profile); Assert.Equal(profile.Name, profile2.Name); Assert.Equal(profile.ExecutablePath, profile2.ExecutablePath); Assert.Equal(profile.CommandLineArgs, profile2.CommandLineArgs); Assert.Equal(profile.WorkingDirectory, profile2.WorkingDirectory); Assert.Equal(profile.LaunchBrowser, profile2.LaunchBrowser); Assert.Equal(profile.LaunchUrl, profile2.LaunchUrl); Assert.True(DictionaryEqualityComparer <string, string> .Instance.Equals(profile.EnvironmentVariables !, profile2.EnvironmentVariables !)); Assert.True(DictionaryEqualityComparer <string, object> .Instance.Equals(profile.OtherSettings !.ToImmutableDictionary(), profile2.OtherSettings !)); Assert.Equal(profile.DoNotPersist, profile2.DoNotPersist); }
/// <summary> /// Converts <paramref name="profile"/> to its serializable form. /// It does some fix up, like setting empty values to <see langword="null"/>. /// </summary> public static LaunchProfileData FromILaunchProfile(ILaunchProfile profile) { var profileData = new LaunchProfileData { Name = profile.Name, ExecutablePath = profile.ExecutablePath, CommandName = profile.CommandName, CommandLineArgs = profile.CommandLineArgs, WorkingDirectory = profile.WorkingDirectory, LaunchBrowser = profile.LaunchBrowser, LaunchUrl = profile.LaunchUrl, EnvironmentVariables = profile.EnvironmentVariables, OtherSettings = profile.OtherSettings, InMemoryProfile = profile.IsInMemoryObject() }; return(profileData); }
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); }
public void LaunchProfileData_DeserializeProfilesTests() { var jsonObject = JObject.Parse(JsonString1); var profiles = LaunchProfileData.DeserializeProfiles((JObject)jsonObject["profiles"]); Assert.Equal(4, profiles.Count); var profile = profiles["IIS Express"]; Assert.Equal("IISExpress", profile.CommandName); Assert.Equal("http://localhost:1234:/test.html", profile.LaunchUrl); Assert.True(profile.LaunchBrowser); Assert.False(profile.InMemoryProfile); profile = profiles["HasCustomValues"]; Assert.Equal("c:\\test\\project", profile.WorkingDirectory); Assert.Equal("c:\\test\\project\\bin\\project.exe", profile.ExecutablePath); Assert.Null(profile.LaunchBrowser); Assert.Null(profile.LaunchUrl); Assert.Null(profile.EnvironmentVariables); Assert.NotNull(profile.OtherSettings); Assert.True((bool)profile.OtherSettings !["custom1"]);
public void LaunchProfileData_ToSerializableFormTests() { var jsonObject = JObject.Parse(JsonString1); var profiles = LaunchProfileData.DeserializeProfiles((JObject)jsonObject["profiles"]); var profile = profiles["IIS Express"]; var serializableProfile = LaunchProfileData.ToSerializableForm(new LaunchProfile(profile)); AssertEx.CollectionLength(serializableProfile, 3); Assert.Equal("IISExpress", serializableProfile["commandName"]); Assert.Equal("http://localhost:1234:/test.html", serializableProfile["launchUrl"]); Assert.True((bool)serializableProfile["launchBrowser"]); profile = profiles["HasCustomValues"]; serializableProfile = LaunchProfileData.ToSerializableForm(new LaunchProfile(profile)); Assert.Equal(6, serializableProfile.Count); Assert.Equal("c:\\test\\project", serializableProfile["workingDirectory"]); Assert.Equal("c:\\test\\project\\bin\\project.exe", serializableProfile["executablePath"]); Assert.Equal("--arg1 --arg2", serializableProfile["commandLineArgs"]); Assert.True((bool)serializableProfile["custom1"]); Assert.Equal(124, serializableProfile["custom2"]); Assert.Equal("mycustomVal", serializableProfile["custom3"]); // tests launchBrowser:false is not rewritten profile = profiles["Docker"]; serializableProfile = LaunchProfileData.ToSerializableForm(new LaunchProfile(profile)); AssertEx.CollectionLength(serializableProfile, 3); Assert.Equal("Docker", serializableProfile["commandName"]); Assert.Equal("some option in docker", serializableProfile["dockerOption1"]); Assert.Equal("Another option in docker", serializableProfile["dockerOption2"]); profile = profiles["web"]; serializableProfile = LaunchProfileData.ToSerializableForm(new LaunchProfile(profile)); AssertEx.CollectionLength(serializableProfile, 3); Assert.Equal("Project", serializableProfile["commandName"]); Assert.True((bool)serializableProfile["launchBrowser"]); Assert.Equal("Development", ((IDictionary)serializableProfile["environmentVariables"])["ASPNET_ENVIRONMENT"]); Assert.Equal("c:\\Users\\billhie\\Documents\\projects\\WebApplication8\\src\\WebApplication8", ((IDictionary)serializableProfile["environmentVariables"])["ASPNET_APPLICATIONBASE"]); }
/// <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)); } } } } }
/// <summary> /// To handle custom settings, we serialize using LaunchProfileData first and then walk the settings /// to pick up other settings. Currently limited to boolean, integer, string and dictionary of string /// </summary> public static Dictionary <string, LaunchProfileData> DeserializeProfiles(JObject profilesObject) { var profiles = new Dictionary <string, LaunchProfileData>(StringComparer.Ordinal); if (profilesObject == null) { return(profiles); } // We walk the profilesObject and serialize each subobject component as either a string, or a dictionary<string,string> foreach (var profile in profilesObject) { // Name of profile is the key, value is it's contents. We have specific serializing of the data based on the // JToken type LaunchProfileData profileData = JsonConvert.DeserializeObject <LaunchProfileData>(profile.Value.ToString()); // Now pick up any custom properties. Handle string, int, boolean Dictionary <string, object> customSettings = new Dictionary <string, object>(StringComparer.Ordinal); foreach (var data in profile.Value.Children()) { JProperty dataProperty = data as JProperty; if (dataProperty == null) { continue; } if (!IsKnownProfileProperty(dataProperty.Name)) { try { switch (dataProperty.Value.Type) { case JTokenType.Boolean: { bool value = bool.Parse(dataProperty.Value.ToString()); customSettings.Add(dataProperty.Name, value); break; } case JTokenType.Integer: { int value = int.Parse(dataProperty.Value.ToString()); customSettings.Add(dataProperty.Name, value); break; } case JTokenType.Object: { var value = JsonConvert.DeserializeObject <Dictionary <string, string> >(dataProperty.Value.ToString()); customSettings.Add(dataProperty.Name, value); break; } case JTokenType.String: { customSettings.Add(dataProperty.Name, dataProperty.Value.ToString()); break; } default: { break; } } } catch { // TODO: should have message indicating the setting is being ignored. Fix as part of issue // https://github.com/dotnet/roslyn-project-system/issues/424 } } } // Only add custom settings if we actually picked some up if (customSettings.Count > 0) { profileData.OtherSettings = customSettings; } profiles.Add(profile.Key, profileData); } return(profiles); }
/// <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; } }