Изменение метаданных проекта в Visual Studio 2013 C#

У меня есть пакет Visual Studio 2013, написанный на C#, где мне нужно внести некоторые изменения в элементы и их атрибуты в файле проекта C++, когда Visual Studio 2013 работает и загружен проект. На самом деле, можно также сохранить файл проекта в тот момент, когда сохраняется все решение.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="Test">
    <MyItemToChange Include = "TestItem">
      <MyMetadata1ToChange>Value1</MyMetadata1ToChange>
      <MyMetadata2ToChange>Value2</MyMetadata2ToChange>
    </MyItemToChange>
  </ItemGroup>
  <!-- The rest of the file -->
</Project>

В предыдущих версиях Visual Studio я использовал класс Microsoft.Build.Evaluation.Project для изменения элементов и метаданных проекта. Когда у вас есть ссылка на проект, вы можете получить доступ к XML-структуре проекта напрямую через Project.Xml собственности или овладеть другим Microsoft.Build.Evaluation.ProjectItem и использовать найденные там интерфейсы.

Однако, поскольку Microsoft изменила структуру Visual Studio в своем выпуске 2013 года, хотя Microsoft.Build.Evaluation.Project не считается устаревшим, вы больше не можете получить доступ к проектам C++ через Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadedProjects, так как коллекция пуста. Однако это все еще работает, если вы хотите получить доступ к проектам C#. (На самом деле, просматривая объекты во время отладки, вы можете обнаружить, что они по-прежнему используют одно и то же Microsoft.Build.Evaluation пространство имен для внутреннего представления.)

Так как я не могу получить доступ к Microsoft.Build.Evaluation.Project больше мне нужна альтернатива

  1. получить доступ к проекту иначе, чем с помощью Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadedProjects
  2. записывать элементы проекта и метаданные во время работы Visual Studio 2013.

Если я не пропустил что-то, следующее не подходит для моих целей:

  1. Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetItemAttribute устанавливает только атрибуты для элементов, отображаемых в обозревателе решений. "MyItemToChange" не отображается в обозревателе решений
  2. Открытие файла и его ручное редактирование и сохранение. Если вы не знаете, как подавить предупреждение Visual Studio об измененном проекте и как автоматически перезагрузить его, это не тот путь.
    Примечание. Вы можете закрыть решение, открыть файл проекта вручную, отредактировать, сохранить его и снова открыть решение. Это будет работать нормально, данные есть, если файлы не находятся под контролем исходного кода. Теперь он открывает множество новых проблем (почему EnvDTE.DTE.SourceControl.CheckOutItem() не работает и т. Д.) Поэтому я все же думаю, что было бы лучше, если бы Visual Studio обрабатывал запись данных в файл проекта.
  3. Отражение. Да, как я упоминал ранее, я мог копаться во внутренних классах, чтобы овладеть "оригиналом" Microsoft.Build.Evaluation.Project, а также Microsoft.Build.Evaluation.ProjectItemНо, во-первых, это довольно небезопасно для использования в будущем, и, насколько я помню, вы не можете быть уверены, что если вы измените эти теперь внутренние классы, проект будет знать, что он грязный и должен быть сохранен.

Я рад получить какие-либо предложения, так как у меня действительно заканчиваются варианты.

Благодарю.

1 ответ

Ну, я разработал обходной путь, а не реальное решение проблемы.

Что я делаю сейчас, так это следующее:

  1. Спросите пользователя, все ли в порядке с закрытием всего решения и сохранением всего. Если нет, я отменяю всю процедуру: EnvDTE.DTE.ItemOperations.PromptToSave
  2. Попробуйте попросить Visual Studio 2013 проверить файл проекта для меня в системе контроля версий, используя EnvDTE.DTE.SourceControl.CheckOutItem() метод. Если это вызывает исключение (NotImplementedException), я использую bodge для проверки файла проекта. То есть я записываю пользовательское свойство в файл проекта, используя Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetProperty() метод.
  3. Закройте все решение. EnvDTE.DTE.Solution.Close()
  4. Откройте файл проекта, используя System.Xml.XmlDocument учебный класс. Редактировать. Сохранить. Да, и удалите мое глупое свойство, написанное в пункте 2. (тот, который заставлял Visual Studio 2013 проверять файл в системе контроля версий).
  5. Вновь откройте решение. EnvDTE.DTE.Solution.Open() В этот момент пользователю может быть снова предложено подтвердить некоторые параметры контроля источника.

Почему это просто обходной путь, а не правильное решение?

  • Это безобразно:)
  • Методы злоупотребляют вещами, которые они не предназначены для использования (запись случайного свойства в проект просто для принудительного извлечения контроля из исходного кода)
  • Это не будет работать, если закрытие решения / проекта не вариант. Например: если вам нужно что-то сохранить во время сборки или во время редактирования файлов решения / проекта / исходных файлов; или если вам приходится делать это часто, а не один раз за время существования проекта.

Я все еще ищу правильное решение проблемы. Но до тех пор, пока кто-нибудь не скажет мне, как это делается, я должен жить с этой текущей реализацией.

Другие вопросы по тегам