/// <summary> /// Считываес (с помощью API MSBuild) содержимое файла проекта /// и заполняет GUI-элементы соотвествующими значениями. /// </summary> /// <param name="configuration"> /// Имя конфигурации которую нужно считать. Если пустая строка или null /// </param> private void OpenProject(string prjPath, string configuration) { if (string.IsNullOrEmpty(prjPath) || !File.Exists(prjPath)) { MessageBox.Show(this, "Error", "Wrong project path '" + prjPath + "'"); return; } _propertyGrid.SelectedObject = null; MsBuildProjectHelper msBuildHelper = new MsBuildProjectHelper(prjPath); _msBuildHelper = msBuildHelper; // Если configuration не пуста устанавливаем значение свойства // Configuration. Это позволит считать соотвествующую конфигурацию // проекта. if (!string.IsNullOrEmpty(configuration)) { msBuildHelper.Project.SetProperty(ConfigPropName, configuration); } this.Text = "MSBuild Profect Viewer - " + Path.GetFullPath(prjPath); FillItemsView(msBuildHelper); FillPropertiesView(msBuildHelper); FillConfiguration(msBuildHelper); _lastOpenedProject = prjPath; }
/// <summary> /// Считывает список MSBuild-элементов и группирует их п типам /// (помещая в мап (имя типа/список элеметов этого типа)). /// </summary> /// <param name="msBuildHelper">MsBuildProjectHelper</param> /// <returns>мап (имя типа/список элеметов этого типа)</returns> private static ItemTypesMap InitItemTypesMap(MsBuildProjectHelper msBuildHelper) { ItemTypesMap itemTypesMap = new ItemTypesMap(); foreach (ProjectItem item in msBuildHelper.GetProjectItems()) { string itemType = item.ItemType; List <TreeNode> items = GetItemsByType(itemTypesMap, itemType); string nodeName = item.GetMetadataValue("Link"); // Если у элемента нет атрибута "Link", то используем для // имени ветки путь к элементу. if (string.IsNullOrEmpty(nodeName)) { nodeName = item.EvaluatedInclude; } TreeNode node = new TreeNode(nodeName); node.Tag = item; items.Add(node); if (items.Count == 1) { itemTypesMap[itemType] = items; } } return(itemTypesMap); }
/// <summary> /// Считывет список конфигураций и заполняет ими выпадающий список /// в панеле инструментов. /// </summary> /// <param name="msBuildHelper"></param> private void FillConfiguration(MsBuildProjectHelper msBuildHelper) { try { _isConfigurationLoading = true; Project prj = msBuildHelper.Project; var sonfigurations = prj.ConditionedProperties.Count == 0 ? null : prj.ConditionedProperties[ConfigPropName]; _projectConfigurationToolStripComboBox.Items.Clear(); if (sonfigurations != null) { _projectConfigurationToolStripComboBox.Items.AddRange(sonfigurations.ToArray()); } var property = msBuildHelper.Project.GetProperty(ConfigPropName); if (property != null) { _projectConfigurationToolStripComboBox.Text = property.EvaluatedValue; } } finally { _isConfigurationLoading = false; } }
/// <summary> /// Считывает описание свойств MSBuild и заполняет ими ListView. /// </summary> /// <param name="msBuildHelper">MsBuildProjectHelper</param> /// <summary> private void FillPropertiesView(MsBuildProjectHelper msBuildHelper) { // EvaluatedProperties содержит список свойств получаемый // после всех подстановок и проверок. foreach (ProjectProperty prop in msBuildHelper.Project.AllEvaluatedProperties) { ListViewItem lvItem = new ListViewItem(prop.Name); lvItem.SubItems.Add(prop.UnevaluatedValue); var evaluatedValue = prop.EvaluatedValue; var envVarValue = Environment.GetEnvironmentVariable(prop.Name); if (evaluatedValue == envVarValue) { lvItem.ForeColor = Color.DarkGray; } else if (_commonMSBuildProperties.Contains(prop.Name)) { lvItem.ForeColor = Color.Blue; } lvItem.SubItems.Add(evaluatedValue); lvItem.Tag = prop; lvItem.ImageIndex = 2; _propertiesListView.Items.Add(lvItem); } }
/// <summary> /// Считывает описание свойств MSBuild и заполняет ими ListView. /// </summary> /// <param name="msBuildHelper">MsBuildProjectHelper</param> /// <summary> private void FillPropertiesView(MsBuildProjectHelper msBuildHelper) { var propPrefixFilter = _propertyNamePrefixFilterTextBox.Text; var hasPropPrefixFilter = propPrefixFilter.Length > 0; var propPrefixFilterOptions = propPrefixFilter.All(char.IsLower) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; var valueContentFilter = _valueContentFilterTextBox.Text; var hasValueContentFilter = valueContentFilter.Length > 0; _propertiesListView.BeginUpdate(); try { _propertiesListView.Items.Clear(); // EvaluatedProperties содержит список свойств получаемый // после всех подстановок и проверок. foreach (ProjectProperty prop in msBuildHelper.Project.AllEvaluatedProperties) { var evaluatedValue = prop.EvaluatedValue ?? ""; var unevaluatedValue = prop.UnevaluatedValue ?? ""; if (hasPropPrefixFilter && !prop.Name.StartsWith(propPrefixFilter, propPrefixFilterOptions)) { continue; } if (hasValueContentFilter && !(evaluatedValue.Contains(valueContentFilter) || unevaluatedValue.Contains(valueContentFilter))) { continue; } var envVarValue = Environment.GetEnvironmentVariable(prop.Name); ListViewItem lvItem = new ListViewItem(prop.Name); lvItem.SubItems.Add(prop.UnevaluatedValue); if (evaluatedValue == envVarValue) { lvItem.ForeColor = Color.DarkGray; } else if (_commonMSBuildProperties.Contains(prop.Name)) { lvItem.ForeColor = Color.Blue; } lvItem.SubItems.Add(evaluatedValue); lvItem.Tag = prop; lvItem.ImageIndex = 2; _propertiesListView.Items.Add(lvItem); } } finally { _propertiesListView.EndUpdate(); } }
/// <summary> /// Чтение свойств MSBuild. /// </summary> /// <param name="msbuild">MsBuildProjectHelper</param> /// <param name="propertyName">Имя свойства</param> /// <returns></returns> private static string GetMSBuildPropertyValue(MsBuildProjectHelper msbuild, string propertyName) { ProjectProperty prop = msbuild.Project.GetProperty(propertyName); if (prop == null) { return(""); } return(prop.UnevaluatedValue); }
/// <summary> /// Считывает описание элеметов MSBuild и заполняет ими TreeView. /// </summary> /// <param name="msBuildHelper">MsBuildProjectHelper</param> private void FillItemsView(MsBuildProjectHelper msBuildHelper) { _projectTreeView.BeginUpdate(); try { // Первый проходом считываем элементы группируя их по типам. // itemTypesMap содержит ассоциативный массив имен типов элементов // и списков элементов. ItemTypesMap itemTypesMap = InitItemTypesMap(msBuildHelper); // Сортировка в TreeView делается очень медленно. По этому запрещаем // ее и выполняем ее потом вручную. _projectTreeView.TreeViewNodeSorter = null; _projectTreeView.Sorted = false; // Очищаем TreeView. _projectTreeView.Nodes.Clear(); // Эта переменная будет содержать список корневых веток TreeView. TreeNodeCollection rootNodes = _projectTreeView.Nodes; // Для каждого типа элементов... foreach (StrTreeNodePair elem in itemTypesMap) { // ... создаем корневую TreeView-ветку... TreeNode typeNode = new TreeNode(elem.Key); rootNodes.Add(typeNode); // Эта переменная будет содержать мап путь/TreeView-веток // для этого пути. TreeMap treeMap = new TreeMap(); // Для каждого элемента данного типа... foreach (TreeNode node in elem.Value) { // ... получаем путь к фалу. string dir = Path.GetDirectoryName(node.Text); // Находим соотвествующий фолдер (TreeView-ветку его описывающую). TreeNode folder = GetParentFolder(typeNode, treeMap, dir); // Получаем имя файла... string file = Path.GetFileName(node.Text); // ... которое используем в качестве имени элемента. node.Text = file; // Назначаем иконки файлов и добавляем ветку. const int FileImageIndex = 1; node.ImageIndex = FileImageIndex; node.SelectedImageIndex = FileImageIndex; folder.Nodes.Add(node); } } // Закат солнца вручную. :) Ручная сортировка требуется в виду // диких тормозов встроенной в TreeView сортировки. // Возможно к релизу эту проблему стронят, но пока... SortTreeNodes(rootNodes, new MSBuildTreeViewNodeSorter()); } finally { // Что бы не случилось нужно разрешить отрисовку. Иначе любой глюк // приведет к непотребному виду TreeView. _projectTreeView.EndUpdate(); } }