private void UpdateCommandsForProjectOnDispatcher(IVsHierarchy project, bool onlyIfVcsSupportEnabled) { Logger.Info($"Dispatching update commands function call"); JoinableTaskFactory.RunAsync(async delegate { // git branch and merge might lead to a race condition here. // If a branch is checkout where the json file differs, the // filewatcher will trigger an event which is dispatched here. // However, while the function call is queued VS may reopen the // solution due to changes. This will ultimately result in a // null ref exception because the project object is unloaded. // UpdateCommandsForProject() will skip such projects because // their guid is empty. await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (onlyIfVcsSupportEnabled && !IsVcsSupportEnabled) { return; } Logger.Info($"Dispatched update commands function call for project '{project.GetDisplayName()}'"); if (project.GetGuid() == Guid.Empty) { Logger.Info($"Race condition might occurred while dispatching update commands function call. Project is already unloaded."); } ToolWindowHistory.SaveState(); UpdateCommandsForProject(project); }); }
public void RenameProject(IVsHierarchy project, string oldProjectDir, string oldProjectName, Action hack) { if (cmdPackage.IsUseSolutionDirEnabled) { return; } var guid = project.GetGuid(); if (projectFsWatchers.TryGetValue(guid, out FileSystemWatcher fsWatcher)) { projectFsWatchers.Remove(guid); using (fsWatcher.TemporarilyDisable()) { var newFileName = FullFilenameForProjectJsonFileFromProject(project); var oldFileName = FullFilenameForProjectJsonFileFromProjectPath(oldProjectDir, oldProjectName); Logger.Info($"Renaming json-file '{oldFileName}' to new name '{newFileName}'"); if (File.Exists(newFileName)) { File.Delete(oldFileName); hack(); // TODO } else if (File.Exists(oldFileName)) { File.Move(oldFileName, newFileName); } fsWatcher.Filter = Path.GetFileName(newFileName); } projectFsWatchers.Add(guid, fsWatcher); } }
private void UpdateCommandsForProjectOnDispatcher(IVsHierarchy project) { Logger.Info($"Dispatching update commands function call for project '{project.GetDisplayName()}'"); Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Normal, new Action(() => { // git branch and merge might lead to a race condition here. // If a branch is checkout where the json file differs, the // filewatcher will trigger an event which is dispatched here. // However, while the function call is queued VS may reopen the // solution due to changes. This will ultimately result in a // null ref exception because the project object is unloaded. // UpdateCommandsForProject() will skip such projects because // their guid is empty. Logger.Info($"Dispatched update commands function call for project '{project.GetDisplayName()}'"); if (project.GetGuid() == Guid.Empty) { Logger.Info($"Race condition might occurred while dispatching update commands function call. Project is already unloaded."); } UpdateCommandsForProject(project); })); }
int IVsSolutionEvents.OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) { var project = ProjectForHierarchy(pHierarchy); if (!ProjectArguments.IsSupportedProject(project)) { return(LogIgnoringUnsupportedProjectType()); } Guid projectGuid = pHierarchy.GetGuid(); string projectPath = project.FullName; string projectName = project.UniqueName; bool isLoaded = pHierarchy.IsLoaded(); bool isLoadProcess = ProjectStateMap.TryGetValue(projectGuid, out var state) && state.IsLoaded; ProjectStateMap[projectGuid] = new ProjectState { FilePath = projectPath, UniqueName = projectName, IsLoaded = isLoaded }; ProjectAfterOpen?.Invoke(this, new ProjectAfterOpenEventArgs { Project = project, IsLoadProcess = isLoadProcess, IsSolutionOpenProcess = fAdded == 0 }); return(S_OK); }
private void DetachFsWatcherFromProject(IVsHierarchy project) { var guid = project.GetGuid(); if (projectFsWatchers.TryGetValue(guid, out FileSystemWatcher fsWatcher)) { fsWatcher.Dispose(); projectFsWatchers.Remove(guid); Logger.Info($"Detached FileSystemWatcher for project '{project.GetName()}'."); } }
private void SaveJsonForProject(IVsHierarchy project) { if (!cmdPackage.IsVcsSupportEnabled || project == null) { return; } var guid = project.GetGuid(); var vm = cmdPackage.ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(guid); string filePath = FullFilenameForProjectJsonFileFromProject(project); FileSystemWatcher fsWatcher = projectFsWatchers.GetValueOrDefault(guid); if (vm != null && vm.Items.Any()) { using (fsWatcher?.TemporarilyDisable()) { // Tell VS that we're about to change this file // This matters if the user has TFVC with server workpace (see #57) if (!vsHelper.CanEditFile(filePath)) { Logger.Error($"VS or the user did no let us edit our file :/"); } else { try { using (Stream fileStream = File.Open(filePath, FileMode.Create, FileAccess.Write)) { ProjectDataSerializer.Serialize(vm, fileStream); } } catch (Exception e) { Logger.Warn($"Failed to write to file '{filePath}' with error '{e}'."); } } } } else if (File.Exists(filePath)) { Logger.Info("Deleting json file because command list is empty but json-file exists."); try { File.Delete(filePath); } catch (Exception e) { Logger.Warn($"Failed to delete file '{filePath}' with error '{e}'."); } } }
int IVsSolutionEvents.OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy) { if (!ProjectArguments.IsSupportedProject(pRealHierarchy)) { return(LogIgnoringUnsupportedProjectType()); } ProjectStateMap[pRealHierarchy.GetGuid()].IsLoaded = false; ProjectBeforeUnload?.Invoke(this, pRealHierarchy); return(S_OK); }
int IVsSolutionEvents.OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy) { var project = ProjectForHierarchy(pRealHierarchy); if (!ProjectArguments.IsSupportedProject(project)) { return(LogIgnoringUnsupportedProjectType()); } ProjectStateMap[pRealHierarchy.GetGuid()].IsLoaded = true; ProjectAfterLoad?.Invoke(this, project); return(S_OK); }
private void AttachFsWatcherToProject(IVsHierarchy project) { string realProjectJsonFileFullName = SymbolicLinkUtils.GetRealPath(FullFilenameForProjectJsonFileFromProject(project)); try { var projectJsonFileWatcher = new FileSystemWatcher(); projectJsonFileWatcher.Path = Path.GetDirectoryName(realProjectJsonFileFullName); projectJsonFileWatcher.Filter = Path.GetFileName(realProjectJsonFileFullName); projectJsonFileWatcher.EnableRaisingEvents = true; projectFsWatchers.Add(project.GetGuid(), projectJsonFileWatcher); projectJsonFileWatcher.Changed += (fsWatcher, args) => { Logger.Info($"SystemFileWatcher file Change '{args.FullPath}'"); if (IsVcsSupportEnabled) { UpdateCommandsForProjectOnDispatcher(project); } }; projectJsonFileWatcher.Created += (fsWatcher, args) => { Logger.Info($"SystemFileWatcher file Created '{args.FullPath}'"); if (IsVcsSupportEnabled) { UpdateCommandsForProjectOnDispatcher(project); } }; projectJsonFileWatcher.Renamed += (fsWatcher, args) => { Logger.Info($"FileWachter file Renamed '{args.FullPath}'. realProjectJsonFileFullName='{realProjectJsonFileFullName}'"); if (IsVcsSupportEnabled && realProjectJsonFileFullName == args.FullPath) { UpdateCommandsForProjectOnDispatcher(project); } }; Logger.Info($"Attached FileSystemWatcher to file '{realProjectJsonFileFullName}' for project '{project.GetName()}'."); } catch (Exception e) { Logger.Warn($"Failed to attach FileSystemWatcher to file '{realProjectJsonFileFullName}' for project '{project.GetName()}' with error '{e}'."); } }
private void SaveJsonForProject(IVsHierarchy project) { if (!IsVcsSupportEnabled || project == null) { return; } var guid = project.GetGuid(); var vm = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(guid); string filePath = FullFilenameForProjectJsonFileFromProject(project); FileSystemWatcher fsWatcher = projectFsWatchers.GetValueOrDefault(guid); if (vm != null && vm.Items.Any()) { using (fsWatcher?.TemporarilyDisable()) { try { using (Stream fileStream = File.Open(filePath, FileMode.Create, FileAccess.Write)) { Logic.ToolWindowProjectDataSerializer.Serialize(vm, fileStream); } } catch (Exception e) { Logger.Warn($"Failed to write to file '{filePath}' with error '{e}'."); } } } else if (File.Exists(filePath)) { Logger.Info("Deleting json file because command list is empty but json-file exists."); try { File.Delete(filePath); } catch (Exception e) { Logger.Warn($"Failed to delete file '{filePath}' with error '{e}'."); } } }
int IVsSolutionEvents4.OnAfterRenameProject(IVsHierarchy pHierarchy) { if (!ProjectArguments.IsSupportedProject(pHierarchy)) { return(LogIgnoringUnsupportedProjectType()); } Guid projectGuid = pHierarchy.GetGuid(); var oldProjectDir = ProjectStateMap[projectGuid].ProjectDir; var oldProjectName = ProjectStateMap[projectGuid].ProjectName; ProjectStateMap[projectGuid].ProjectDir = pHierarchy.GetProjectDir(); ProjectStateMap[projectGuid].ProjectName = pHierarchy.GetName(); ProjectAfterRename?.Invoke(this, new ProjectAfterRenameEventArgs { OldProjectDir = oldProjectDir, OldProjectName = oldProjectName, Project = pHierarchy }); return(S_OK); }
int IVsSolutionEvents4.OnAfterRenameProject(IVsHierarchy pHierarchy) { var project = ProjectForHierarchy(pHierarchy); if (!ProjectArguments.IsSupportedProject(project)) { return(LogIgnoringUnsupportedProjectType()); } Guid projectGuid = pHierarchy.GetGuid(); var oldFilePath = ProjectStateMap[projectGuid].FilePath; var oldProjectName = ProjectStateMap[projectGuid].UniqueName; ProjectStateMap[projectGuid].FilePath = project.FullName; ProjectStateMap[projectGuid].UniqueName = project.UniqueName; ProjectAfterRename?.Invoke(this, new ProjectAfterRenameEventArgs { OldFilePath = oldFilePath, OldUniqueName = oldProjectName, Project = project }); return(S_OK); }
int IVsSolutionEvents.OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved) { if (!ProjectArguments.IsSupportedProject(pHierarchy)) { return(LogIgnoringUnsupportedProjectType()); } Guid projectGuid = pHierarchy.GetGuid(); var isUloadProcess = ProjectStateMap.TryGetValue(projectGuid, out var state) && !state.IsLoaded; if (!isUloadProcess) { ProjectStateMap.Remove(projectGuid); } ProjectBeforeClose?.Invoke(this, new ProjectBeforeCloseEventArgs { Project = pHierarchy, IsUnloadProcess = isUloadProcess, IsSolutionCloseProcess = fRemoved == 0 }); return(S_OK); }
public ProjectDataJson ReadDataForProject(IVsHierarchy project) { ProjectDataJson result = null; if (!cmdPackage.IsUseSolutionDirEnabled) { string filePath = FullFilenameForProjectJsonFileFromProject(project); if (File.Exists(filePath)) { try { using (Stream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read)) { result = Logic.ProjectDataSerializer.Deserialize(fileStream); } Logger.Info($"Read {result?.Items?.Count} commands for project '{project.GetName()}' from json-file '{filePath}'."); } catch (Exception e) { Logger.Warn($"Failed to read file '{filePath}' with error '{e}'."); result = null; } } else { Logger.Info($"Json-file '{filePath}' doesn't exists."); } return(result); } else { Guid projectGui = project.GetGuid(); string slnFilename = vsHelper.GetSolutionFilename(); string jsonFilename = Path.ChangeExtension(slnFilename, "args.json"); if (File.Exists(jsonFilename)) { try { using (Stream fileStream = File.Open(jsonFilename, FileMode.Open, FileAccess.Read)) { SolutionDataJson slnData = SolutionDataSerializer.Deserialize(fileStream); result = slnData.ProjectArguments.FirstOrDefault(p => p.Id == projectGui); } Logger.Info($"Read {result?.Items?.Count} commands for project '{project.GetName()}' from json-file '{jsonFilename}'."); } catch (Exception e) { Logger.Warn($"Failed to read file '{jsonFilename}' with error '{e}'."); result = null; } } else { Logger.Info($"Json-file '{jsonFilename}' doesn't exists."); } return(result); } }
private void UpdateConfigurationForProject(IVsHierarchy project) { if (project == null) { return; } IEnumerable <CmdArgument> checkedArgs = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(project.GetGuid())?.CheckedArguments; if (checkedArgs == null) { return; } IEnumerable <string> enabledEntries; if (IsMacroEvaluationEnabled) { enabledEntries = checkedArgs.Select( e => msBuildPropertyRegex.Replace(e.Value, match => vsHelper.GetMSBuildPropertyValue(project, match.Groups["propertyName"].Value) ?? match.Value)); } else { enabledEntries = checkedArgs.Select(e => e.Value); } string prjCmdArgs = string.Join(" ", enabledEntries); ProjectArguments.SetArguments(project, prjCmdArgs); Logger.Info($"Updated Configuration for Project: {project.GetName()}"); }
private void UpdateCommandsForProject(IVsHierarchy project) { if (project == null) { throw new ArgumentNullException(nameof(project)); } Logger.Info($"Update commands for project '{project?.GetName()}'. IsVcsSupportEnabled={IsVcsSupportEnabled}. SolutionData.Count={toolWindowStateLoadedFromSolution?.ProjectArguments?.Count}."); var projectGuid = project.GetGuid(); if (projectGuid == Guid.Empty) { Logger.Info("Skipping project because guid euqals empty."); return; } var solutionData = toolWindowStateLoadedFromSolution ?? new SuoDataJson(); // joins data from solution and project // => overrides solution commands for a project if a project json file exists // => keeps all data from the suo file for projects without a json // => if we have data in our ViewModel we use this instad of the suo file // get project json data ProjectDataJson projectData = null; if (IsVcsSupportEnabled) { projectData = fileStorage.ReadDataForProject(project); } // project json overrides if it exists if (projectData != null) { Logger.Info($"Setting {projectData?.Items?.Count} commands for project '{project.GetName()}' from json-file."); var projectListViewModel = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(projectGuid); var projHasSuoData = solutionData.ProjectArguments.ContainsKey(projectGuid); // update enabled state of the project json data (source prio: ViewModel > suo file) if (projectData.Items != null) { var argumentDataFromProject = projectData.AllArguments; var argumentDataFromLVM = projectListViewModel?.AllArguments.ToDictionary(arg => arg.Id, arg => arg); foreach (var dataFromProject in argumentDataFromProject) { if (argumentDataFromLVM != null && argumentDataFromLVM.TryGetValue(dataFromProject.Id, out CmdArgument argFromVM)) { dataFromProject.Enabled = argFromVM.IsChecked; } else if (projHasSuoData) { dataFromProject.Enabled = solutionData.CheckedArguments.Contains(dataFromProject.Id); } else { dataFromProject.Enabled = dataFromProject.DefaultChecked; } } var containerDataFromProject = projectData.AllContainer; var containerDataFromLVM = projectListViewModel?.AllContainer.ToDictionary(con => con.Id, con => con); foreach (var dataFromProject in containerDataFromProject) { if (containerDataFromLVM != null && containerDataFromLVM.TryGetValue(dataFromProject.Id, out CmdContainer conFromVM)) { dataFromProject.Expanded = conFromVM.IsExpanded; } else { dataFromProject.Expanded = solutionData.ExpandedContainer.Contains(dataFromProject.Id); } } var itemDataFromProject = projectData.AllItems; var itemDataFromLVM = projectListViewModel?.ToDictionary(item => item.Id, item => item); foreach (var dataFromProject in itemDataFromProject) { if (itemDataFromLVM != null && itemDataFromLVM.TryGetValue(dataFromProject.Id, out CmdBase itemFromVM)) { dataFromProject.Selected = itemFromVM.IsSelected; } else { dataFromProject.Selected = solutionData.SelectedItems.Contains(dataFromProject.Id); } } if (projectListViewModel != null) { projectData.Expanded = projectListViewModel.IsExpanded; projectData.Selected = projectListViewModel.IsSelected; } else { projectData.Expanded = solutionData.ExpandedContainer.Contains(projectData.Id); projectData.Selected = solutionData.SelectedItems.Contains(projectData.Id); } } else { projectData = new ProjectDataJson(); Logger.Info($"DataCollection for project '{project.GetName()}' is null."); } } // if we have data in the ViewModel we keep it else if (ToolWindowViewModel.TreeViewModel.Projects.ContainsKey(projectGuid)) { return; } else if (IsVcsSupportEnabled) { projectData = new ProjectDataJson(); Logger.Info("Will clear all data because of missing json file and enabled VCS support."); } // we try to read the suo file data else if (solutionData.ProjectArguments.TryGetValue(projectGuid, out projectData)) { Logger.Info($"Will use commands from suo file for project '{project.GetName()}'."); var argumentDataFromProject = projectData.AllArguments; foreach (var arg in argumentDataFromProject) { arg.Enabled = solutionData.CheckedArguments.Contains(arg.Id); } var containerDataFromProject = projectData.AllContainer; foreach (var con in containerDataFromProject) { con.Expanded = solutionData.ExpandedContainer.Contains(con.Id); } var itemDataFromProject = projectData.AllItems; foreach (var item in itemDataFromProject) { item.Selected = solutionData.SelectedItems.Contains(item.Id); } projectData.Expanded = solutionData.ExpandedContainer.Contains(projectData.Id); projectData.Selected = solutionData.SelectedItems.Contains(projectData.Id); } else { Logger.Info($"Gathering commands from configurations for project '{project.GetName()}'."); // if we don't have suo file data we read cmd args from the project configs projectData = new ProjectDataJson(); projectData.Items.AddRange(ReadCommandlineArgumentsFromProject(project)); } // push projectData to the ViewModel ToolWindowViewModel.PopulateFromProjectData(project, projectData); Logger.Info($"Updated Commands for project '{project.GetName()}'."); }
private string CreateCommandLineArgsForProject(IVsHierarchy project) { if (project == null) { return(null); } var projectCmd = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(project.GetGuid()); if (projectCmd == null) { return(null); } string projConfig = project.GetProject()?.ConfigurationManager?.ActiveConfiguration?.ConfigurationName; string activeLaunchProfile = null; if (project.IsCpsProject()) { activeLaunchProfile = SmartCmdArgs15.CpsProjectSupport.GetActiveLaunchProfileName(project.GetProject()); } string MacroEvaluation(string arg) { if (!IsMacroEvaluationEnabled) { return(arg); } return(msBuildPropertyRegex.Replace(arg, match => vsHelper.GetMSBuildPropertyValueForActiveConfig(project, match.Groups["propertyName"].Value) ?? match.Value)); } string JoinContainer(CmdContainer con) { IEnumerable <CmdBase> items = con.Items.Where(x => x.IsChecked != false); if (projConfig != null) { items = items.Where(x => { var conf = x.UsedProjectConfig; return(conf == null || conf == projConfig); }); } if (activeLaunchProfile != null) { items = items.Where(x => { var prof = x.UsedLaunchProfile; return(prof == null || prof == activeLaunchProfile); }); } return(string.Join(con.Delimiter, items.Select(x => x is CmdContainer c ? JoinContainer(c) : MacroEvaluation(x.Value)))); } return(JoinContainer(projectCmd)); }
private string CreateCommandLineArgsForProject(IVsHierarchy project) { if (project == null) { return(null); } IEnumerable <CmdArgument> checkedArgs = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(project.GetGuid())?.CheckedArguments; if (checkedArgs == null) { return(null); } string projConfig = project.GetProject()?.ConfigurationManager?.ActiveConfiguration?.ConfigurationName; if (projConfig != null) { checkedArgs = checkedArgs.Where(x => { var conf = x.UsedProjectConfig; return(conf == null || conf == projConfig); }); } if (project.IsCpsProject()) { var activeLaunchProfile = SmartCmdArgs15.CpsProjectSupport.GetActiveLaunchProfileName(project.GetProject()); if (activeLaunchProfile != null) { checkedArgs = checkedArgs.Where(x => { var prof = x.UsedLaunchProfile; return(prof == null || prof == activeLaunchProfile); }); } } IEnumerable <string> enabledEntries; if (IsMacroEvaluationEnabled) { enabledEntries = checkedArgs.Select( e => msBuildPropertyRegex.Replace(e.Value, match => vsHelper.GetMSBuildPropertyValueForActiveConfig(project, match.Groups["propertyName"].Value) ?? match.Value)); } else { enabledEntries = checkedArgs.Select(e => e.Value); } return(string.Join(" ", enabledEntries)); }
private void UpdateCommandsForProject(IVsHierarchy project) { if (project == null) { throw new ArgumentNullException(nameof(project)); } Logger.Info($"Update commands for project '{project?.GetName()}'. IsVcsSupportEnabled={IsVcsSupportEnabled}. SolutionData.Count={toolWindowStateLoadedFromSolution?.ProjectArguments?.Count}."); var projectGuid = project.GetGuid(); if (projectGuid == Guid.Empty) { Logger.Info("Skipping project because guid euqals empty."); return; } var solutionData = toolWindowStateLoadedFromSolution ?? new ToolWindowStateSolutionData(); ToolWindowViewModel.TreeViewModel.ShowAllProjects = solutionData.ShowAllProjects; // joins data from solution and project // => overrides solution commands for a project if a project json file exists // => keeps all data from the suo file for projects without a json // => if we have data in our ViewModel we use this instad of the suo file // get project json data ToolWindowStateProjectData projectData = null; if (IsVcsSupportEnabled) { string filePath = FullFilenameForProjectJsonFileFromProject(project); if (File.Exists(filePath)) { try { using (Stream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read)) { projectData = Logic.ToolWindowProjectDataSerializer.Deserialize(fileStream); } Logger.Info($"Read {projectData?.Items?.Count} commands for project '{project.GetName()}' from json-file '{filePath}'."); } catch (Exception e) { Logger.Warn($"Failed to read file '{filePath}' with error '{e}'."); projectData = null; } } else { Logger.Info($"Json-file '{filePath}' doesn't exists."); } } // project json overrides if it exists if (projectData != null) { Logger.Info($"Setting {projectData?.Items?.Count} commands for project '{project.GetName()}' from json-file."); var projectListViewModel = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(projectGuid); // update enabled state of the project json data (source prio: ViewModel > suo file) if (projectData.Items != null) { var argumentDataFromProject = projectData.AllArguments; var argumentDataFromLVM = projectListViewModel?.AllArguments.ToDictionary(arg => arg.Id, arg => arg); foreach (var dataFromProject in argumentDataFromProject) { if (argumentDataFromLVM != null && argumentDataFromLVM.TryGetValue(dataFromProject.Id, out CmdArgument argFromVM)) { dataFromProject.Enabled = argFromVM.IsChecked; } else { dataFromProject.Enabled = solutionData.CheckedArguments.Contains(dataFromProject.Id); } } var containerDataFromProject = projectData.AllContainer; var containerDataFromLVM = projectListViewModel?.AllContainer.ToDictionary(con => con.Id, con => con); foreach (var dataFromProject in containerDataFromProject) { if (containerDataFromLVM != null && containerDataFromLVM.TryGetValue(dataFromProject.Id, out CmdContainer conFromVM)) { dataFromProject.Expanded = conFromVM.IsExpanded; } else { dataFromProject.Expanded = solutionData.ExpandedContainer.Contains(dataFromProject.Id); } } if (projectListViewModel != null) { projectData.Expanded = projectListViewModel.IsExpanded; } else { projectData.Expanded = solutionData.ExpandedContainer.Contains(projectData.Id); } } else { projectData = new ToolWindowStateProjectData(); Logger.Info($"DataCollection for project '{project.GetName()}' is null."); } } // if we have data in the ViewModel we keep it else if (ToolWindowViewModel.TreeViewModel.Projects.ContainsKey(projectGuid)) { return; } else if (IsVcsSupportEnabled) { projectData = new ToolWindowStateProjectData(); Logger.Info("Will clear all data because of missing json file and enabled VCS support."); } // we try to read the suo file data else if (solutionData.ProjectArguments.TryGetValue(projectGuid, out projectData)) { Logger.Info($"Will use commands from suo file for project '{project.GetName()}'."); var argumentDataFromProject = projectData.AllArguments; foreach (var arg in argumentDataFromProject) { arg.Enabled = solutionData.CheckedArguments.Contains(arg.Id); } var containerDataFromProject = projectData.AllContainer; foreach (var con in containerDataFromProject) { con.Expanded = solutionData.ExpandedContainer.Contains(con.Id); } projectData.Expanded = solutionData.ExpandedContainer.Contains(projectData.Id); } else { Logger.Info($"Gathering commands from configurations for project '{project.GetName()}'."); // if we don't have suo file data we read cmd args from the project configs projectData = new ToolWindowStateProjectData(); projectData.Items.AddRange( ReadCommandlineArgumentsFromProject(project) .Select(cmdLineArg => new ListEntryData { Command = cmdLineArg })); } // push projectData to the ViewModel ToolWindowViewModel.PopulateFromProjectData(project, projectData); Logger.Info($"Updated Commands for project '{project.GetName()}'."); }
private string GetWorkingDirForProject(IVsHierarchy project) { if (project == null) { return(null); } IEnumerable <CmdWorkingDir> checkedWorkingDirs = ToolWindowViewModel.TreeViewModel.Projects.GetValueOrDefault(project.GetGuid())?.CheckedWorkingDirs; if (checkedWorkingDirs == null) { return(null); } string projConfig = project.GetProject()?.ConfigurationManager?.ActiveConfiguration?.ConfigurationName; if (projConfig != null) { checkedWorkingDirs = checkedWorkingDirs.Where(x => { var conf = x.UsedProjectConfig; return(conf == null || conf == projConfig); }); } if (project.IsCpsProject()) { var activeLaunchProfile = SmartCmdArgs15.CpsProjectSupport.GetActiveLaunchProfileName(project.GetProject()); if (activeLaunchProfile != null) { checkedWorkingDirs = checkedWorkingDirs.Where(x => { var prof = x.UsedLaunchProfile; return(prof == null || prof == activeLaunchProfile); }); } } IEnumerable <string> enabledEntries; if (IsMacroEvaluationEnabled) { enabledEntries = checkedWorkingDirs.Select( e => msBuildPropertyRegex.Replace(e.Value, match => vsHelper.GetMSBuildPropertyValueForActiveConfig(project, match.Groups["propertyName"].Value) ?? match.Value)); } else { enabledEntries = checkedWorkingDirs.Select(e => e.Value); } var list = enabledEntries.ToList(); if (list.Count != 1) { Logger.Error("More than one working directory selected, fallback to default."); return(null); } return(list.First()); }