/// <returns>
        /// If the profile does not exist, returns <see langword="null"/>. Otherwise, returns the value
        /// of the property if the property is not defined, or <see langword="null"/> otherwise. The
        /// standard properties are always considered to be defined.
        /// </returns>
        public async Task <string?> GetUnevaluatedPropertyValueAsync(string propertyName)
        {
            ILaunchSettings snapshot = await _launchSettingsProvider.WaitForFirstSnapshot();

            ILaunchProfile?profile = snapshot.Profiles.FirstOrDefault(p => StringComparers.LaunchProfileNames.Equals(p.Name, _context.ItemName));

            if (profile is null)
            {
                return(null);
            }

            return(propertyName switch
            {
                CommandNamePropertyName => profile.CommandName ?? string.Empty,
                ExecutablePathPropertyName => profile.ExecutablePath ?? string.Empty,
                CommandLineArgumentsPropertyName => profile.CommandLineArgs ?? string.Empty,
                WorkingDirectoryPropertyName => profile.WorkingDirectory ?? string.Empty,
                LaunchBrowserPropertyName => profile.LaunchBrowser ? "true" : "false",
                LaunchUrlPropertyName => profile.LaunchUrl ?? string.Empty,
                EnvironmentVariablesPropertyName => LaunchProfileEnvironmentVariableEncoding.Format(profile),
                _ => GetExtensionPropertyValue(propertyName, profile, snapshot.GlobalSettings)
            });
        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);
            }));
        }
        public WritableLaunchSettings(ILaunchSettings settings)
        {
            if (settings.Profiles != null)
            {
                foreach (ILaunchProfile profile in settings.Profiles)
                {
                    Profiles.Add(new WritableLaunchProfile(profile));
                }
            }

            // For global settings we want to make new copies of each entry so that the snapshot remains immutable. If the object implements
            // ICloneable that is used, otherwise, it is serialized back to json, and a new object rehydrated from that
            if (settings.GlobalSettings != null)
            {
                var jsonSerializerSettings = new JsonSerializerSettings()
                {
                    NullValueHandling = NullValueHandling.Ignore
                };

                foreach ((string key, object value) in settings.GlobalSettings)
                {
                    if (value is ICloneable cloneableObject)
                    {
                        GlobalSettings.Add(key, cloneableObject.Clone());
                    }
                    else
                    {
                        string jsonString   = JsonConvert.SerializeObject(value, Formatting.Indented, jsonSerializerSettings);
                        object clonedObject = JsonConvert.DeserializeObject(jsonString, value.GetType());
                        GlobalSettings.Add(key, clonedObject);
                    }
                }
            }

            if (settings.ActiveProfile != null)
            {
                ActiveProfile = Profiles.FirstOrDefault((profile) => LaunchProfile.IsSameProfileName(profile.Name, settings.ActiveProfile.Name));
            }
        }
        public override Task <string?> OnSetPropertyValueAsync(string unevaluatedPropertyValue, IProjectProperties defaultProperties, IReadOnlyDictionary <string, string>?dimensionalConditions = null)
        {
            _projectThreadingService.RunAndForget(async() =>
            {
                ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

                var writableLaunchSettings = launchSettings.ToWritableLaunchSettings();
                var activeProfile          = writableLaunchSettings.ActiveProfile;
                if (activeProfile != null)
                {
                    UpdateActiveLaunchProfile(activeProfile, unevaluatedPropertyValue);

                    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 <string> GetPropertyValueAsync()
        {
            ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot();

            string?commandName = launchSettings.ActiveProfile?.CommandName;

            if (commandName == null)
            {
                return(string.Empty);
            }

            ConfiguredProject?configuredProject = await _project.GetSuggestedConfiguredProjectAsync();

            IPropertyPagesCatalogProvider?catalogProvider = configuredProject?.Services.PropertyPagesCatalog;

            if (catalogProvider == null)
            {
                return(string.Empty);
            }

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

            foreach (string schemaName in catalog.GetPropertyPagesSchemas())
            {
                Rule?rule = catalog.GetSchema(schemaName);
                if (rule != null &&
                    string.Equals(rule.PageTemplate, "CommandNameBasedDebugger", StringComparison.OrdinalIgnoreCase) &&
                    rule.Metadata.TryGetValue("CommandName", out object pageCommandNameObj) &&
                    pageCommandNameObj is string pageCommandName &&
                    pageCommandName.Equals(commandName))
                {
                    return(schemaName);
                }
            }

            return(string.Empty);
        }
 /// <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 void MergeExistingInMemoryProfiles(LaunchSettingsData newSnapshot, ILaunchSettings prevSnapshot)
 {
     for (int i = 0; i < prevSnapshot.Profiles.Count; i++)
     {
         var profile = prevSnapshot.Profiles[i];
         if (profile.IsInMemoryObject() && !string.Equals(profile.CommandName, ErrorProfileCommandName))
         {
             // 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>
        /// Saves the launch settings to the launch settings file. Adds an errorstring and throws if an exception. Note
        /// that the caller is responsible for checking out the file
        /// </summary>
        protected async Task SaveSettingsToDiskAsync(ILaunchSettings newSettings)
        {
            // Clear stale errors since we are saving
            ClearErrors();
            var    serializationData = GetSettingsToSerialize(newSettings);
            string fileName          = await _launchSettingsFilePath.GetValueAsync()
                                       .ConfigureAwait(false);

            try
            {
                await EnsureSettingsFolderAsync().ConfigureAwait(false);

                // We don't want to write null values. We want to keep the file as small as possible
                JsonSerializerSettings settings = new JsonSerializerSettings()
                {
                    NullValueHandling = NullValueHandling.Ignore
                };
                string jsonString = JsonConvert.SerializeObject(serializationData, Formatting.Indented, settings);

                IgnoreFileChanges = true;
                FileManager.WriteAllText(fileName, jsonString);

                // Update the last write time
                LastSettingsFileSyncTime = FileManager.LastFileWriteTime(fileName);
            }
            catch (Exception ex)
            {
                string err = string.Format(Resources.ErrorWritingDebugSettings, fileName, ex.Message);
                LogError(err, false);
                throw;
            }
            finally
            {
                IgnoreFileChanges = false;
            }
        }
 /// <summary>
 /// Retrieves the property specified by <paramref name="propertyName"/> from the
 /// given <see cref="ILaunchSettings"/>.
 /// </summary>
 /// <returns>
 /// The value of the property if it is found in the <paramref name="launchSettings"/>;
 /// otherwise a default value or <see langword="null"/> if there is no applicable default.
 /// </returns>
 /// <exception cref="InvalidOperationException">
 /// Thrown if the given <paramref name="propertyName"/> is not known (that is, it is
 /// not declared in the implementor's <see cref="ExportInterceptingPropertyValueProviderAttribute"/>).
 /// </exception>
 public abstract string?GetPropertyValue(string propertyName, ILaunchSettings launchSettings);
        private async Task <string> GetPropertyValueAsync()
        {
            ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

            return(GetValueFromLaunchSettings(launchSettings.ActiveProfile));
        }
Exemplo n.º 10
0
 public static IWritableLaunchSettings ToWritableLaunchSettings(this ILaunchSettings curSettings)
 {
     return(new WritableLaunchSettings(curSettings));
 }
Exemplo n.º 11
0
 public Task UpdateAndSaveSettingsInternalAsyncTest(ILaunchSettings curSettings, bool persistToDisk)
 {
     return(UpdateAndSaveSettingsInternalAsync(curSettings, persistToDisk));
 }
Exemplo n.º 12
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;
                 }
             }
         }
     }
 }
Exemplo n.º 13
0
 public Task SaveSettingsToDiskAsyncTest(ILaunchSettings curSettings)
 {
     return(SaveSettingsToDiskAsync(curSettings));
 }
Exemplo n.º 14
0
        internal virtual void InitializeDebugTargetsCore(ILaunchSettings profiles)
        {
            IWritableLaunchSettings newSettings = profiles.ToWritableLaunchSettings();

            // Since this get's reentered if the user saves or the user switches active profiles.
            if (CurrentLaunchSettings != null && !CurrentLaunchSettings.SettingsDiffer(newSettings))
            {
                return;
            }

            try
            {
                // This should never change the dirty state when loading the dialog
                PushIgnoreEvents();

                // Remember the current selection
                string curProfileName = SelectedDebugProfile?.Name;

                // Update the set of settings and generate a property change so the list of profiles gets updated. Note that we always
                // clear the active profile on the CurrentLaunchSettings so that when we do set one and property changed event is set
                CurrentLaunchSettings = newSettings;
                CurrentLaunchSettings.ActiveProfile = null;

                // Reload the launch profiles collection
                LaunchProfiles.Clear();
                foreach (IWritableLaunchProfile profile in CurrentLaunchSettings.Profiles)
                {
                    LaunchProfiles.Add(profile);
                }

                // When loading new profiles we need to clear the launch type. This is so the external changes cause the current
                // active provider to be refreshed
                _selectedLaunchType = null;
                NotifyProfileCollectionChanged();

                // If we have a selection, we want to leave it as is
                if (curProfileName == null || newSettings.Profiles.Find(p => LaunchProfile.IsSameProfileName(p.Name, curProfileName)) == null)
                {
                    // Note that we have to be careful since the collection can be empty.
                    if (profiles.ActiveProfile != null && !string.IsNullOrEmpty(profiles.ActiveProfile.Name))
                    {
                        SelectedDebugProfile = LaunchProfiles.Single(p => LaunchProfile.IsSameProfileName(p.Name, profiles.ActiveProfile.Name));
                    }
                    else
                    {
                        if (LaunchProfiles.Count > 0)
                        {
                            SelectedDebugProfile = LaunchProfiles[0];
                        }
                        else
                        {
                            SetEnvironmentGrid(null);
                        }
                    }
                }
                else
                {
                    SelectedDebugProfile = LaunchProfiles.Single(p => LaunchProfile.IsSameProfileName(p.Name, curProfileName));
                }
            }
            finally
            {
                PopIgnoreEvents();
                _firstSnapshotCompleteSource?.TrySetResult();
                _debugTargetsCoreInitialized = true;
            }
        }
Exemplo n.º 15
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);
        }
 public void SaveSettingsToDiskTest(ILaunchSettings curSettings)
 {
     SaveSettingsToDisk(curSettings);
 }
        private async Task <string> GetPropertyValueAsync(string propertyName)
        {
            ILaunchSettings launchSettings = await _launchSettingsProvider.WaitForFirstSnapshot(Timeout.Infinite);

            return(GetPropertyValue(propertyName, launchSettings) ?? string.Empty);
        }
Exemplo n.º 18
0
 public WorkItemTracker(IAzureService azureService, ILaunchSettings launchSettings)
 {
     this.azureService   = azureService;
     this.launchSettings = launchSettings;
 }
        /// <summary>
        /// Called whenever the debug targets change. Note that after a save this function will be
        /// called. It looks for changes and applies them to the UI as needed. Switching profiles
        /// will also cause this to change as the active profile is stored in profiles snaphost.
        /// </summary>
        internal virtual void InitializeDebugTargetsCore(ILaunchSettings profiles)
        {
            bool profilesChanged    = true;
            bool IISSettingsChanged = true;

            // Since this get's reentered if the user saves or the user switches active profiles.
            if (DebugProfiles != null)
            {
                profilesChanged = profiles.ProfilesAreDifferent(DebugProfiles.Select(p => (ILaunchProfile)p).ToList());
                if (!profilesChanged && !IISSettingsChanged)
                {
                    return;
                }
            }

            try
            {
                // This should never change the dirty state
                PushIgnoreEvents();

                if (profilesChanged)
                {
                    // Remember the current selection
                    string curProfileName = SelectedDebugProfile == null ? null : SelectedDebugProfile.Name;

                    // Load debug profiles
                    var debugProfiles = new ObservableCollection <LaunchProfile>();

                    foreach (var profile in profiles.Profiles)
                    {
                        // Don't show the dummy NoAction profile
                        if (profile.CommandName != ProfileCommandNames.NoAction)
                        {
                            var newProfile = new LaunchProfile(profile);
                            debugProfiles.Add(newProfile);
                        }
                    }

                    DebugProfiles = debugProfiles;

                    // If we have a selection, we want to leave it as is
                    if (curProfileName == null || profiles.Profiles.FirstOrDefault(p => { return(LaunchProfile.IsSameProfileName(p.Name, curProfileName)); }) == null)
                    {
                        // Note that we have to be careful since the collection can be empty.
                        if (!string.IsNullOrEmpty(profiles.ActiveProfile.Name))
                        {
                            SelectedDebugProfile = DebugProfiles.Where((p) => LaunchProfile.IsSameProfileName(p.Name, profiles.ActiveProfile.Name)).Single();
                        }
                        else
                        {
                            if (debugProfiles.Count > 0)
                            {
                                SelectedDebugProfile = debugProfiles[0];
                            }
                            else
                            {
                                SetEnvironmentGrid(null);
                            }
                        }
                    }
                    else
                    {
                        SelectedDebugProfile = DebugProfiles.Where((p) => LaunchProfile.IsSameProfileName(p.Name, curProfileName)).Single();
                    }
                }
            }
            finally
            {
                PopIgnoreEvents();
            }
        }
Exemplo n.º 20
0
 public TestAssembly(ILaunchSettings launchSettings)
 {
     this.assemblyPath = launchSettings.Arguments.AssemblyPath;
     this.testStrategy = launchSettings.Arguments.TestStratgey;
 }
Exemplo n.º 21
0
 // Wrappers to call protected members
 public void SetCurrentSnapshot(ILaunchSettings profiles)
 {
     CurrentSnapshot = profiles;
 }
Exemplo n.º 22
0
        /// <summary>
        /// Helper function to set the new snapshot and post the changes to consumers.
        /// </summary>
        protected void FinishUpdate(ILaunchSettings newSnapshot)
        {
            CurrentSnapshot = newSnapshot;

            _broadcastBlock?.Post(newSnapshot);
        }
Exemplo n.º 23
0
        protected async Task UpdateProfilesAsync(string activeProfile)
        {
            try
            {
                // If no active profile specified, try to get one
                if (activeProfile == null)
                {
                    ProjectDebugger props = await _commonProjectServices.ActiveConfiguredProjectProperties.GetProjectDebuggerPropertiesAsync();

                    if (await props.ActiveDebugProfile.GetValueAsync() is IEnumValue activeProfileVal)
                    {
                        activeProfile = 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, activeProfile);

                await FinishUpdateAsync(newSnapshot, ensureProfileProperty : true);
            }
            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);
                }
            }
        }
 /// <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>
                     {
                         [kvp.Key] = kvp.Value
                     };
                 }
                 else if (!newSnapshot.OtherSettings.TryGetValue(kvp.Key, out object existingValue))
                 {
                     newSnapshot.OtherSettings[kvp.Key] = kvp.Value;
                 }
             }
         }
     }
 }
Exemplo n.º 25
0
 public Task UpdateAndSaveSettingsAsync(ILaunchSettings newSettings)
 {
     // Updates need to be sequenced. Do not call this version from within an ExecuteTask as it
     // will deadlock
     return(_sequentialTaskQueue.ExecuteTask(() => UpdateAndSaveSettingsInternalAsync(newSettings)));
 }
Exemplo n.º 26
0
 public Executor(ITestPlansController testPlansController, ITestAssembly testAssembly, ILaunchSettings launchSettings)
 {
     this.testPlansController = testPlansController;
     this.testAssembly        = testAssembly;
     this.launchSettings      = launchSettings;
 }