MSBuild: Как мне создать и использовать задачу для преобразования элементов контента во время сборки?

У меня есть проект Silverlight 3 с чем-то вроде этого:


  
  

В основном я добавил PNG-файл в свой проект и установил его действие по сборке. в «Контент». Это хорошо работает.

Теперь я хотел бы добавить в свой проект изображения в другом формате и преобразовать их в PNG во время сборки - чтобы конечный результат был таким, как если бы я сначала добавил изображение PNG в проект (в виде контента).

Другими словами - я хочу, чтобы изображение появилось в формате PNG в моем пакете XAP.

В идеале я хотел бы сделать это таким образом, чтобы он работал с Visual Web Developer 2008 Express (чтобы я мог добавлять файлы изображений в свой проект, перетаскивая их в IDE и, возможно, изменяя их действие сборки), и без внесения каких-либо общесистемных изменений.

Конкретный формат, который я хочу преобразовать, - это XCF - у меня уже есть код .NET для преобразования в PNG. Я предполагаю, что должен создать задачу MSBuild .

У меня нет особого опыта работы с MSBuild, и я хотел бы знать, как собрать такую ​​вещь вместе.


На основе мое грубое понимание того, как работает MSBuild, я думаю, что мне нужно знать:

  • Как создать коллекцию элементов путем (ре) перемещения их из коллекции @ (Content) (или какой-либо другой) на основании их расширения файла?
    • ИЛИ: создать пользовательское действие по сборке, которое можно использовать в Visual Web Developer 2008 Express
  • Как получить путь к элементам ввода в задаче ?
  • Где (.NET или MSBuild? ) и Как указать расположение выходных файлов, созданных задачей ?
  • Как обеспечить восстановление файла при изменении его входного файла?
  • Где (возможно, BeforeBuild ]?) и Как повторно преобразовать преобразованные элементы в @ (Content) ? (Или я должен использовать какую-то другую коллекцию?)
    • ИЛИ: Каким-то другим способом получить их в XAP?

И если это кажется разумным способом сделать что-то или я что-то пропустил?

7
задан Andrew Russell 10 August 2010 в 07:50
поделиться

3 ответа

Вы задали конкретные подвопросы для достижения вашей общей цели. Я полагаю, вы хотите узнать о MSBuild, а не получить механический ответ на вашу общую задачу (а это то, что вы собираются получить от многих других людей из-за вашей щедрости), поэтому я отвечу на ваши индивидуальные вопросы, а затем попытаюсь свести их все в решение.

Допустим, вы хотите преобразовать все файлы .jpg в .png.

Создать подсписок из списка элементов контента на основе расширения:

<ItemGroup>
    <Sublist Include="@(Content)" Condition=" '%(Extension)' == '.jpg' " />
</ItemGroup>

Получить путь элемента в задаче.

Два способа - зависит от ввода, который может принять ваша задача. Этот способ похож на «foreach» для каждого элемента в подсписке, и я бы предпочел использовать его с задачей Exec:

<Exec Command="convert.exe /Input:%(Sublist.FullPath)" />

Указание пути вывода также зависит от .exe или задачи, которой вы являетесь, и от того, какой путь вывода означает для конкретной задачи:

это каталог или просто имя файла с другим расширением. Но я предполагаю, что вы хотите вывести файлы с тем же именем, но с другим расширением:

<Exec Command="convert.exe &quot;%(Sublist.FullPath)&quot;  &quot;%(Sublist.RootDir)%(Sublist.Directory)%(Sublist.Filename).png&quot;" />    

Как восстановить png, если jpg изменяется (или очищается).

Что ж, здесь используется атрибут Inputs and Outputs содержащего целевого элемента, в котором выполняется наша команда преобразования. Входные данные определяют исходные файлы, а выходы определяют то, что будет производить цель. Затем MSBuild сравнивает datetime входов с datetime выходных данных, и если они устарели, выходы перестраиваются

<Target Name="ConvertJpg"  
        Inputs="@(Content)"
        Outputs="@(Content -> '%(RootDir)%(Directory)%(Filename).png' )"
        Condition=" '%(Extension)' == '.jpg' "
  • Входные данные говорят, что мы хотим использовать группу элементов «Content»
  • Атрибут Condition гарантирует, что мы работаем только с элементами контента, которые заканчиваются расширением .jpg
  • . Атрибут Outputs указывает, что из входных данных, с которыми мы работаем, мы будем создавать файлы, которые имеют одинаковый путь и имя файла, но оканчиваются на .png extension

Наконец, вы правильно заметили, что вам нужно повторно вставить сгенерированные файлы .png обратно в группу элементов @Content - ну, это просто, вы просто включаете их в элемент Content. Напомним, что Sublist содержит файлы .jpg - нам нужны эти файлы, но с окончанием .png. Мы также НЕ хотим.jpg в группе элементов содержимого после создания png

<Content Remove="@(Sublist)" />
<Content Include="@(Sublist -> '%(RootDir)%(Directory)%(Filename).png' )" />

Итак, резюмируя, ваша цель будет выглядеть примерно так, как я полагаю:

<Target Name="ConvertJpg"  
        Inputs="@(Content)"
        Outputs="@(Content -> '%(RootDir)%(Directory)%(Filename).png' )"
        Condition=" '%(Extension)' == '.jpg' "
    <ItemGroup>
        <Sublist Include="@(Content)" Condition=" '%(Extension)' == '.jpg' " />
    </ItemGroup>

    <Exec Command="convert.exe /Input:%(Sublist.FullPath) Output=%(Sublist.RootDir)%(Sublist.Directory)%(Sublist.Filename).png" />

    <Content Remove="@(Sublist)" />
    <Content Include="@(Sublist -> '%(RootDir)%(Directory)%(Filename).png' )" />
</Target>

Между прочим, ImageMagik имеет инструмент командной строки, который преобразует jpg в png. ..

13
ответ дан 6 December 2019 в 14:00
поделиться

Я думаю, вам нужно что-то вроде этого:

<ItemGroup>
  <JPGContent Include="foo.jpg" />
</ItemGroup>
<Target Name="BeforeBuild" 
        Inputs="@(JPGContent)" Outputs="%(JPGContent.Filename).png">
  <!-- replace this with call to jpg->png converter -->
  <Exec Command="copy %22%(JPGContent.FullPath)%22 %(JPGContent.Filename).png" />
  <ItemGroup>
    <Content Include="%(JPGContent.Filename).png" />
  </ItemGroup>
</Target>
<Target Name="AfterBuild">
  <!-- just demoing that 'Content' now has right value -->
  <Warning Text ="Content=@(Content)" />
</Target>

где вы указываете новый JPGContent BuildAction, который он преобразует.

(См. Также http://msdn.microsoft.com/en-us/library/ms164313.aspx и обратите внимание, что % 22 - это просто способ встроить кавычки в атрибуте.)

2
ответ дан 6 December 2019 в 14:00
поделиться

Вместо создания задачи MSBuild вы также можете создать настраиваемый инструмент и указать его в настраиваемом инструменте в свойствах файла изображения.

«специальный инструмент преобразует файл во время разработки и поместит результат преобразования в другой файл»

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

преимущество этого подхода в том, что вы может использовать сгенерированный файл при проектировании время тоже.

в качестве образца реализации можно найти на http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/

0
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: