Как программно сделать автоматически созданный файл встроенным ресурсом в Visual Studio?
У меня запутанный рабочий процесс, подобный следующему: сборка одного из проектов в Visual Studio (2013) приводит к созданию файлов XML. Эти файлы используются другим проектом как часть фреймворка.
Тем не менее, для того, чтобы файлы XML могли быть использованы, они должны быть помечены как встроенные ресурсы - в настоящее время это делается через пользовательский интерфейс / форму VS через свойства файла. Это хорошо для добавленных вручную файлов.
Но как мне программно сделать автоматически сгенерированный XML-файл встроенным ресурсом, чтобы следующий проект мог просто его забрать (в некотором смысле) и включить файлы в соответствующую DLL?
Мое текущее предположение состоит в том, чтобы программно редактировать .csproj
добавьте и добавьте строки, аналогичные приведенным ниже:
<EmbeddedResource Include="Path\To\File\MyEmbeddedResource.meta.xml" />
Это оно?
1 ответ
Вы можете добиться этого, используя связанный элемент и - если они оба являются частью одного и того же решения - соответствующий набор зависимостей сборки.
Сначала создайте проект так, чтобы был создан файл XML, который вы хотите добавить в качестве ресурса.
Затем, в проекте, в который вы хотите встроить XML, щелкните правой кнопкой мыши проект в обозревателе решений, выберите "Добавить существующий" и найдите файл XML. Прежде чем нажать кнопку "Добавить" в браузере, нажмите на выпадающую кнопку справа от нее и выберите "Добавить как ссылку". Это гарантирует, что файл всегда будет текущим.
Выберите ссылку на добавленный файл и измените тип сборки на "Встроенный ресурс".
Предполагая, что ваш XML исходит из проекта в том же решении (игнорируйте этот бит, если нет), то в свойствах решения в разделе Зависимости проекта вы можете установить целевой проект (куда пойдет ресурс) в зависимости от исходного проекта, который создает XML-файл
Или, если вы предпочитаете, вы можете добавить ссылку самостоятельно:
<EmbeddedResource Include="Path\To\File\MyEmbeddedResource.meta.xml">
<Link>MyEmbeddedResource.meta.xml</Link>
</EmbeddedResource>
РЕДАКТИРОВАТЬ: после обсуждения...
Как упоминалось в комментариях ниже, если вы хотите сделать это путем прямого манипулирования файлом проекта, вам нужно будет сделать следующее:
Загрузите проект в виде XML-документа.
Найдите
ItemGroup
узел, содержащий список файлов проекта, который, как правило, будет единственным в проекте, который содержит хотя бы одинCompile
узлы.Для каждого файла вставьте новый
EmbedResource
узел с дополнительнымLink
узел.Link
узел не требуется, но это то, что вы получаете, когда вы вручную добавляете связанный файл.Сохраните файл.
Кажется довольно простым. Мой Xml немного ржавый, но этот код выдает точный результат, который я получил после:
// required 'using' directives: System.IO, System.Xml.Linq
public static void EmbedResourceFiles(string projectFilename, IEnumerable<string> fileList, bool makeLinks = true)
{
// This is the namespace used by the .csproj Xml file
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
// 1: Open the document
XDocument project = XDocument.Load(projectFilename);
// 2: Locate target ItemGroup
var itemGroup = project.Descendants(ns + "Compile").FirstOrDefault()?.Parent;
if (itemGroup == null)
throw new Exception("Failed to locate correct ItemGroup node in project file");
// 3: Insert EmbedResource nodes
foreach (var file in fileList)
{
var node = new XElement(ns + "EmbeddedResource", new XAttribute("Include", file));
if (makeLinks)
node.Add(new XElement(ns + "Link", Path.GetFileName(file)));
itemGroup.Add(node);
}
// 4: Save it, keeping a backup just in case.
File.Copy(projectFilename, projectFilename + ".bak", true);
project.Save(projectFilename);
}
Соберите список файлов так, как вы хотите, и передайте список вышеописанному методу. Если вы хотите подавить создание <Link>
узлы, дать ему "ложь" в третьем параметре. Я сделал несколько тестов, и это, похоже, не имеет никакого значения в любом случае.
Надеюсь, это решит ваш вопрос.