I had a difficult time getting the <Solution> task to work. I had tried to use it in my early NAnt days with similar results. I then tried using <Slingshot>. Both approaches seam to require that the web application is actually mapped to a web path. I must ask, "why?" Additionally, embedded resources do not work correctly when trying to embed images or other usually static files.
Previously, I had set up some generic build scripts that basically assume that all .cs should be built and anything aspx, ascx, or image related should be copied. Additionally, any specifics lke stylesheets or javascript were included explicitly in the copy section of the script. References were added either explicitly when they were provided by a 3rd party or generically when they were internal (all our assembly names begin with our enterprise namespace). This worked great until we migrated to a new, improved framework complete with a myriad of embedded resources.
I found Gordon Weakliem's .Net CSProj to NAnt build xsl transform in this article about NAnt. Before venturing down this path, I tried to resolve my problem on my own. I am not quite ready to depend on the project file, particularly since I was the only developer who ever bothered to update the project file up till now. This is something we intend to start doing as a group, however.
I created a simple xsl transfor to extract the File nodes that have "EmbeddedResource" as their BuildAction. (select="//File[@BuildAction='EmbeddedResource']"). I applied two templates to this, one to generate <ResGen> tasks and another to generate <Resources><Includes> tasks.
<resgen> <xsl:attribute name="input"><xsl:value-of select="@RelPath" /></xsl:attribute> <xsl:attribute name="output"><xsl:value-of select="substring-before(@RelPath,'.resx')" />.resources</xsl:attribute> </resgen> <includes> <xsl:attribute name="name"><xsl:value-of select="@RelPath" ></xsl:value-of>.resources</xsl:attribute> </includes>
When I tried to execute this build, I got a strange error: resgen "unknown file extention" . I executed NAnt with the -verbose argument. The error occured calling the resgen task and was raised by the resgen.exe in the .net framework. Hmm. A little research showed that resgen.exe is for resx and txt files convertion. I found nothing googling the problem (hence this post) and thought I may have found a serious issue. "No way!," as my two-year-old likes to proclaim. This was just a lack of understanding of what resgen was for.
It is only necessary to <resgen> a resx or text (.txt) file for use as an embedded resource. You simply embed other resources directly.
First, it is important to have the dynamicpprefix attribute set to true in nant.
<resources prefix="Root.NameSpace" dynamicprefix="true">
This will create the appropriate resource path (namespace) to the resource based on the directory structure.
Second, you have to remove .resx or .txt from a resgen-ed resource.
So, in a nant build script, you will perform two steps to embed the resx file:
<resgen input="SomeDirectory\SomeResource.resx" output="SomeDirectory\SomeResource.resources" /> ...and <csc target= "libr...> <sources.../> <references> <incl...> </references> <resources prefix="Root.NameSpace" dynamicprefix="true"> <includes name="SomeDirectory\SomeResource.resources" /> </resources> </csc>
But for a javascript or image file, omit the resgen task and include the resource like so...
<csc target= "libr...> <sources.../> <references> <incl...> </references> <resources prefix="Root.NameSpace" dynamicprefix="true"> <includes name="SomeDirectory\SomeResource.js" /> </resources> </csc>
At this point, you are well on your way to a successful compile. NAnt continues to be one of the most useful tools in the global arsenal of user-contributed utilities. Together with NUnit, NCover and reflector, life is getting easier and easier (and more repeatable).