MSBuild:如何创建并使用任务在构建时转换内容项?
我有一个 Silverlight 3 项目,其内容如下:
<ItemGroup>
<Content Include="Content\image1.png">
</Content>
</ItemGroup>
基本上,我已将一个 PNG 文件添加到我的项目中,并将其构建操作设置为“内容”。这很好用。
现在我想做的是能够将不同格式的图像添加到我的项目中,并在构建时将它们转换为PNG - 这样最终结果就像我首先将 PNG 图像添加到项目中(作为内容)一样。
换句话说 - 我希望图像以 PNG 格式出现在我的 XAP 包中。
理想情况下,我希望能够与 Visual Web Developer 2008 Express 一起使用(这样我可以通过将图像文件拖到 IDE 中并可能更改其构建操作来将图像文件添加到我的项目中),并且无需创建任何系统全范围的变化。
我想要转换的具体格式是 XCF - 我已经有了 .NET 代码来转换为 PNG。我假设我必须创建 MSBuild 任务。
我真的没有太多的 MSBuild 经验,我想知道如何将这样的东西放在一起。
基于我对 MSBuild 工作原理的粗略理解,我认为我需要知道:
- 如何通过从
@(Content)
(或其他)集合中(重新)移动项目来创建项目集合,基于他们的文件扩展名?- 或者:创建一个可以在 Visual Web Developer 2008 Express 中使用的自定义构建操作
- 如何接收
Task
中输入项的路径? - 在哪里(.NET 或 MSBuild?)以及如何指定
Task
生成的输出文件的位置? - 如果输入文件发生更改,如何确保文件被重建?
- 在哪里(可能是
BeforeBuild
?)以及如何将转换后的项目重新注入@(Content)
? (或者我应该使用其他集合?)- 或者:还有其他方法让他们进入 XAP 吗?
如果这看起来是一种合理的做事方式,或者我是否错过了什么?
I have a Silverlight 3 project with something like this:
<ItemGroup>
<Content Include="Content\image1.png">
</Content>
</ItemGroup>
Basically I've added a PNG file to my project and set its build action to "Content". This works nicely.
Now what I'd like to do is be able to add images in a different format to my project, and have them converted to PNG at build time - so that the end result is as if I had added a PNG image to the project (as Content) in the first place.
In other words - I want the image to appear, in PNG format, in my XAP package.
Ideally I would like to do this in such a way that it will work with Visual Web Developer 2008 Express (so I can add image files to my project by dragging them into the IDE and maybe changing their build action), and without making any system-wide changes.
The specific format I want to convert is XCF - I already have the .NET code to do the conversion to PNG. I am assuming that I must create a MSBuild Task.
I don't really have much MSBuild experience, and I'd like to know how to put such a thing together.
Based on my rough understanding of how MSBuild works, I think that I need to know:
- How to create a collection of items by (re)moving them from the
@(Content)
(or some other) collection, based on their file extension?- OR: Create a custom Build Action I can use in Visual Web Developer 2008 Express
- How to recieve the path of input items in a
Task
? - Where (.NET or MSBuild?) and How to specify the location of output files generated by a
Task
? - How to ensure that a file is rebuilt if its input file changes?
- Where (probably
BeforeBuild
?) and How to reinject the converted items into@(Content)
? (Or should I use some other collection?)- OR: Some other way of getting them into the XAP?
And if this seems like a reasonable way to do things or if I've missed anything?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了实现您的总体目标,您提出了具体的子问题,我想您想了解 MSBuild,而不是获得总体任务的死记硬背答案(这是您将从许多其他人那里得到的答案,因为您的赏金),所以我将回答您的个人问题,然后尝试将它们全部汇总成一个解决方案。
假设您要将所有 .jpg 文件转换为 .png。
根据扩展名从内容项列表创建子列表:
两种方式 - 取决于您的任务可以接受的输入。这种方式就像对子列表中每个项目的“foreach”,我倾向于将它与 Exec 任务一起使用:
是目录,还是只是具有不同扩展名的文件名。但我假设您想要输出具有相同名称但扩展名不同的文件:
嗯,这是使用执行转换命令的包含目标元素的输入和输出属性。输入指定源文件是什么,输出指定目标将生成什么。然后,MSBuild 将输入的日期时间与输出的日期时间进行比较,如果它们已过时,则重新构建
最后,您正确地发现了您需要将生成的 .png 文件重新注入到 @Content 项目组中 - 嗯,这很简单,您只需将它们包含到内容项目中即可。回想一下,子列表包含 .jpg 文件 - 我们需要这些文件,但以 .png 结尾。一旦生成了 png,我们也不希望内容项组中的 .jpg 文件
所以总而言之,您的目标看起来像这样,我相信:
顺便说一句,ImageMagik 有一个命令行工具,可以将 jpg 转换为 png ...
You have asked specific sub-questions with a view to achieving your overall goal, I presume you want to learn about MSBuild, rather than get a rote answer to your overall task (which is what you are gonna get from many other people due to your bounty), so I will answer your individual questions and then attempt to roll them all up into a solution.
So let's say you want to convert all .jpg files to .png.
Create a sub-list from the content item list based on extension:
Two ways - depends on the input that your task can accept. This way is like a "foreach" over each item in Sublist, and I would tend to use it with an Exec task:
is it a directory, or just a filename with a different extension. But I'll assume you want to output files with the same name, but a different extension:
Well, this is using the Inputs and Outputs attribute of the containing target element where our convert command is executed. Inputs specifies what the source files are, and outputs specifies what the target will produce. MSBuild then compares the datetime of the Inputs with the datetime of the output and if they are out of date, then the outputs get rebuilt
Lastly, you correctly have spotted that you need to re-inject the generated .png files back into the @Content item group - well, that's easy, you just Include them into the Content item. Recall that Sublist contains .jpg files - we want those files but with a .png ending. We also do NOT want the .jpg files in the Content item group once a png has been generated
So summing up, your target would looks something like this I believe:
By the way, ImageMagik has a command line tool that will convert jpg to png...
我相信您想要这样的东西:
您指定一个新的
JPGContent
BuildAction 来转换。(也可能参见http://msdn.microsoft.com/en-us/ library/ms164313.aspx 并注意
%22
只是在属性中嵌入引号的一种方法。)I believe you want something like this:
where you specify a new
JPGContent
BuildAction that it converts.(Possibly see also http://msdn.microsoft.com/en-us/library/ms164313.aspx and note that
%22
is just a way to embed a quotation mark in an attribute.)您还可以创建自定义工具,并在图像文件属性的自定义工具中指定它,而不是创建 MSBuild 任务。
“自定义工具将在设计时转换文件,并将转换的输出放入另一个文件中”,
例如 DataSet。它有自己的转换工具,通过它我们可以获得一个在我们的应用程序中使用的类。
示例实现可以在以下位置找到
http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/
Instead of creating a MSBuild task you can also create a Custom tool and specify this in Custom Tool in properties of your image file.
"a custom tool will transform a file at design time and will place the output of the transformation into another file"
e.g. DataSet. it has its own transformation tool through which we get a class to use in our application.
as sample implementation can be found at
http://www.drewnoakes.com/snippets/WritingACustomCodeGeneratorToolForVisualStudio/