Изменение метаданных проекта в 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
больше мне нужна альтернатива
- получить доступ к проекту иначе, чем с помощью
Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.LoadedProjects
- записывать элементы проекта и метаданные во время работы Visual Studio 2013.
Если я не пропустил что-то, следующее не подходит для моих целей:
Microsoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetItemAttribute
устанавливает только атрибуты для элементов, отображаемых в обозревателе решений. "MyItemToChange" не отображается в обозревателе решений- Открытие файла и его ручное редактирование и сохранение. Если вы не знаете, как подавить предупреждение Visual Studio об измененном проекте и как автоматически перезагрузить его, это не тот путь.
Примечание. Вы можете закрыть решение, открыть файл проекта вручную, отредактировать, сохранить его и снова открыть решение. Это будет работать нормально, данные есть, если файлы не находятся под контролем исходного кода. Теперь он открывает множество новых проблем (почему EnvDTE.DTE.SourceControl.CheckOutItem() не работает и т. Д.) Поэтому я все же думаю, что было бы лучше, если бы Visual Studio обрабатывал запись данных в файл проекта. - Отражение. Да, как я упоминал ранее, я мог копаться во внутренних классах, чтобы овладеть "оригиналом"
Microsoft.Build.Evaluation.Project
, а такжеMicrosoft.Build.Evaluation.ProjectItem
Но, во-первых, это довольно небезопасно для использования в будущем, и, насколько я помню, вы не можете быть уверены, что если вы измените эти теперь внутренние классы, проект будет знать, что он грязный и должен быть сохранен.
Я рад получить какие-либо предложения, так как у меня действительно заканчиваются варианты.
Благодарю.
1 ответ
Ну, я разработал обходной путь, а не реальное решение проблемы.
Что я делаю сейчас, так это следующее:
- Спросите пользователя, все ли в порядке с закрытием всего решения и сохранением всего. Если нет, я отменяю всю процедуру:
EnvDTE.DTE.ItemOperations.PromptToSave
- Попробуйте попросить Visual Studio 2013 проверить файл проекта для меня в системе контроля версий, используя
EnvDTE.DTE.SourceControl.CheckOutItem()
метод. Если это вызывает исключение (NotImplementedException), я использую bodge для проверки файла проекта. То есть я записываю пользовательское свойство в файл проекта, используяMicrosoft.VisualStudio.Shell.Interop.IVsBuildPropertyStorage.SetProperty()
метод. - Закройте все решение.
EnvDTE.DTE.Solution.Close()
- Откройте файл проекта, используя
System.Xml.XmlDocument
учебный класс. Редактировать. Сохранить. Да, и удалите мое глупое свойство, написанное в пункте 2. (тот, который заставлял Visual Studio 2013 проверять файл в системе контроля версий). - Вновь откройте решение.
EnvDTE.DTE.Solution.Open()
В этот момент пользователю может быть снова предложено подтвердить некоторые параметры контроля источника.
Почему это просто обходной путь, а не правильное решение?
- Это безобразно:)
- Методы злоупотребляют вещами, которые они не предназначены для использования (запись случайного свойства в проект просто для принудительного извлечения контроля из исходного кода)
- Это не будет работать, если закрытие решения / проекта не вариант. Например: если вам нужно что-то сохранить во время сборки или во время редактирования файлов решения / проекта / исходных файлов; или если вам приходится делать это часто, а не один раз за время существования проекта.
Я все еще ищу правильное решение проблемы. Но до тех пор, пока кто-нибудь не скажет мне, как это делается, я должен жить с этой текущей реализацией.