У меня есть проект Silverlight 3 с чем-то вроде этого:
В основном я добавил PNG-файл в свой проект и установил его действие по сборке. в «Контент». Это хорошо работает.
Теперь я хотел бы добавить в свой проект изображения в другом формате и преобразовать их в PNG во время сборки - чтобы конечный результат был таким, как если бы я сначала добавил изображение PNG в проект (в виде контента).
Другими словами - я хочу, чтобы изображение появилось в формате PNG в моем пакете XAP.
В идеале я хотел бы сделать это таким образом, чтобы он работал с Visual Web Developer 2008 Express (чтобы я мог добавлять файлы изображений в свой проект, перетаскивая их в IDE и, возможно, изменяя их действие сборки), и без внесения каких-либо общесистемных изменений.
Конкретный формат, который я хочу преобразовать, - это XCF - у меня уже есть код .NET для преобразования в PNG. Я предполагаю, что должен создать задачу MSBuild .
У меня нет особого опыта работы с MSBuild, и я хотел бы знать, как собрать такую вещь вместе.
На основе мое грубое понимание того, как работает MSBuild, я думаю, что мне нужно знать:
@ (Content)
(или какой-либо другой) на основании их расширения файла?
?
? BeforeBuild
]?) и Как повторно преобразовать преобразованные элементы в @ (Content)
? (Или я должен использовать какую-то другую коллекцию?)
И если это кажется разумным способом сделать что-то или я что-то пропустил?
Вы задали конкретные подвопросы для достижения вашей общей цели. Я полагаю, вы хотите узнать о 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 "%(Sublist.FullPath)" "%(Sublist.RootDir)%(Sublist.Directory)%(Sublist.Filename).png"" />
Как восстановить png, если jpg изменяется (или очищается).
Что ж, здесь используется атрибут Inputs and Outputs содержащего целевого элемента, в котором выполняется наша команда преобразования. Входные данные определяют исходные файлы, а выходы определяют то, что будет производить цель. Затем MSBuild сравнивает datetime входов с datetime выходных данных, и если они устарели, выходы перестраиваются
<Target Name="ConvertJpg"
Inputs="@(Content)"
Outputs="@(Content -> '%(RootDir)%(Directory)%(Filename).png' )"
Condition=" '%(Extension)' == '.jpg' "
Наконец, вы правильно заметили, что вам нужно повторно вставить сгенерированные файлы .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. ..
Я думаю, вам нужно что-то вроде этого:
<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
- это просто способ встроить кавычки в атрибуте.)
Вместо создания задачи MSBuild вы также можете создать настраиваемый инструмент и указать его в настраиваемом инструменте в свойствах файла изображения.
«специальный инструмент преобразует файл во время разработки и поместит результат преобразования в другой файл»
например. DataSet. у него есть собственный инструмент преобразования, с помощью которого мы получаем класс для использования в нашем приложении.
преимущество этого подхода в том, что вы может использовать сгенерированный файл при проектировании время тоже.
в качестве образца реализации можно найти на http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/