我有一个类似这样的Silverlight 3项目:
<ItemGroup>
<Content Include="Content\image1.png">
</Content>
</ItemGroup>
基本上我已经将PNG文件添加到我的项目中,并将其构建操作设置为“Content”。这很好用。
现在我想做的是能够以不同的格式将图像添加到我的项目中,并让它们在构建时转换为PNG - 所以结果就好像我首先将PNG图像添加到项目中(作为内容)。
换句话说 - 我希望图像以PNG格式显示在我的XAP包中。
理想情况下,我希望以这样的方式实现这一点,即它可以与Visual Web Developer 2008 Express一起使用(因此我可以通过将图像文件拖入IDE并可能更改其构建操作来将图像文件添加到我的项目中)进行任何系统范围的更改。
我想要转换的特定格式是XCF - 我已经有.NET代码来转换为PNG。我假设我必须create a MSBuild Task。
我没有太多的MSBuild经验,我想知道如何把这样的东西放在一起。
基于我对MSBuild如何运作的粗略理解,我认为我需要知道:
@(Content)
(或其他一些)集合移动它们来创建项目集合?
Task
?Task
生成的输出文件的位置?BeforeBuild
?)以及如何将已转换的项目重新投入@(Content)
? (或者我应该使用其他一些系列?)
如果这似乎是一种合理的做事方式,或者我错过了什么?
答案 0 :(得分:13)
您已经询问了具体的子问题以实现您的总体目标,我认为您想要了解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"" />
如果jpg改变(或清理),如何重建png。
好吧,这是使用包含目标元素的Inputs and Outputs属性执行convert命令的地方。输入指定源文件是什么,输出指定目标将生成的内容。然后,MSBuild将输入的日期时间与输出的日期时间进行比较,如果它们已过期,则输出将重建
<Target Name="ConvertJpg"
Inputs="@(Content)"
Outputs="@(Content -> '%(RootDir)%(Directory)%(Filename).png' )"
Condition=" '%(Extension)' == '.jpg' "
最后,您正确地发现需要将生成的.png文件重新注入@Content项目组 - 好吧,这很简单,您只需将它们包含在Content项目中即可。回想一下,Sublist包含.jpg文件 - 我们想要这些文件但是.png结尾。一旦生成了png,我们也不希望内容项组中的.jpg文件
<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 ...
答案 1 :(得分:2)
我相信你想要这样的东西:
<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 :(得分:0)
您也可以创建自定义工具,而不是创建MSBuild任务,并在图像文件的属性中的自定义工具中指定它。
“自定义工具将在设计时转换文件,并将转换的输出放入另一个文件中”
e.g。数据集。它有自己的转换工具,通过它我们可以在我们的应用程序中使用它。
这种方法的优点是你 可以在设计时使用生成的文件 时间也是如此。
可以在以下位置找到示例实现 http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/