How to use YUI Compressor.Net MSBuild Task 2.3.0.0 - msbuild

I have tried searching the web for a solution to this problem but it seems very unclear. It sounds like people are seeing this but the solutions don't seem to work for me.
I have downloaded and installed YUICompressor.NET.MSBuild 2.3.0.0 from NuGet into my project.
I have created an MSBuild target file that closely resembles the example file included and exists as part of my .csproj file so I can run it in the AfterBuild step.
I am getting the following error everytime I try to build my VS project:
The "JavaScriptCompressorTask" task could not be loaded from the assembly SolutionDir\packages\YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll.
Could not load file or assembly 'Yahoo.Yui.Compressor, Version=2.3.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
My folder structure is as follows:
\Solution
\packages
YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\
\build
ProjectFile.csproj
In the csproj I have:
<UsingTask TaskName="CssCompressorTask" AssemblyFile="packages\YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll" />
<UsingTask TaskName="JavaScriptCompressorTask" AssemblyFile="packages\YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll" />
<Target Name="AfterBuild">
<ItemGroup>
<JavaScriptFiles Include="someFile.js" />
</ItemGroup>
<JavaScriptCompressorTask SourceFiles="#(JavaScriptFiles)" OutputFile="build\combined.js" DeleteSourceFiles="false" CompressionType="None" ObfuscateJavaScript="false" PreserveAllSemicolons="true" />
<JavaScriptCompressorTask SourceFiles="#(JavaScriptFiles)" OutputFile="build\combined.min.js" DeleteSourceFiles="false" CompressionType="Standard" />
</Target>
Am I missing something? Can anyone help me? Thank you.

Did you try to download version 2.3.0.0 directly from codeplex? Then make sure that the Yahoo.Yui.Compressor.Build.MsBuild.dll and Yahoo.Yui.Compressor.dll reside in the same directory. Like this I was able to make it work.

It's been a while since i've played around with the AfterBuild .. but how this works is that the the msbuild program is ran from some directory .. and therefore looks for those assembly files RELATIVE to where the msbuild is being executed from.
I'm not sure if this means the msbuild is being run from C:\program files(x86)\Microsoft Visual Studio\<whatever...>
TAKE NOTE: it's the folder/path (aka execution path) where visual studio is running the msbuild command from ... NOT where msbuild exists.
So therefore, it can't find the assemblies.
Try putting in the full path to the assemblies (just to see if that works).
eg. C:\Projects\Solution\packages\YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll
If it's running it from the \solution\bin directory, then you're in luck! cause then you can do ..\packages\YUICompressor.NET.MSBuild.2.3.0.0\lib\NET20\Yahoo.Yui.Compressor.Build.MsBuild.dll' (the..means: from thisbindirectory, go up one level tosolutionthen down intopackagesand then down intoYUIComp`... etc.
So the answer to your question is this: Find the location Visual Studio is running the msbuild command from, during an AfterBuild. Maybe put in some code in there to say 'write to file => current path i'm in :P'

Related

MSBuild unable to find metadata file for PresentationCore

I am writing a MSBuild file for one of my .NET projects. I do not want to use the Visual Studio generated .sln and .csproj files for certain reasons. I am also aiming to get some experience writing my own build files.
One of my source files is referencing the System.Windows.Media namespace and the build failed with the below message
error CS0234: The type or namespace name 'Media' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
So I added the following snippet in my build file...
<ItemGroup>
<Reference Include="PresentationCore">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
I made changes in the CSC task as follows...
<Target Name="ReleaseBuild">
<MakeDir Directories="$(ReleaseDir)"/>
<Csc Sources="#(SrcFile)"
OutputAssembly="$(ReleaseDir)\$(OutputAssemblyName)"
TargetType="Library"
References="#(Reference);
$(LibDir)\MyOwnLib.DLL"
Platform="$(ProcessorPlatform)">
</Csc>
</Target>
only to get the following error - CSC : error CS0006: Metadata file 'PresentationCore' could not be found
Why is MSBuild not able to find the PresentationCore assembly in the GAC? Is there some additional version information that I should give? I searched in many forums but seem to be going around in circles and I would be glad for any useful pointers as to what the problem could be.
I am using MSBuild 4.0 on an x64 machine and building for an x86 target. My build files which referenced only the MS core libraries worked fine. My VS2008 projects also build fine.
Some Progress
I was able to progress in this issue by making the following changes...
1) I added a property to specify the path of the presentation core library - <PresentationCoreLibDir>C:\Windows\Microsoft.NET\assembly\GAC_32\PresentationCore\v4.0_4.0.0.0__31bf3856ad364e35</PresentationCoreLibDir>
2) Added an additional parameter to the CSC task like this - AdditionalLibPaths="$(PresentationCoreLibDir)"
3) Finally appended the .DLL suffix to the reference tag -
<ItemGroup>
<Reference Include="PresentationCore.DLL">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
I am relieved that I was able to get around this, but is there a neater way of doing this? I thought that the MSBuild engine would be able to figure this out in a more seamless way. Can anyone throw more light on this?
For x86 make sure you use the correct MSBuild which should be at:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
Rather than the x64 MSBuild that is located at:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe

Zip using msbuild task

I try to create msbuild that will zip the build package
i have those line in the msbuild file:
<UsingTask AssemblyFile="MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.Zip" />
<Zip Files="$(OutputFiles)" ZipFileName="output\SomeService.v$(BuildNumber).zip" />
And when I run this msbuild I get exception:
error MSB4018:
The "Zip" task failed unexpectedly.\r
C:\Projects\Services\SomeService\DeployClassificationService.build(92,5):
error MSB4018: System.IO.FileNotFoundException: Could not load file or
assembly 'ICSharpCode.SharpZipLib, Version=0.84.0.0, Culture=neutral,
PublicKeyToken=1b03e6acf1164f73' or one of its dependencies. The
system cannot find the file specified.\r
What is ICSharpCode? I tried to include it within the msbuild fir and it did not help.
Thanks,
Alon
When you install MSBuild Community Tasks, you should find ICSharpCode library in the installation folder %ProgramFiles%\MsBuild\MSBuildCommunityTasks.
You should use Community tasks like Anibas mentioned.
OR
Put ICSharpCode library into the same folder with with MSBuild.Community.Tasks.dll.
Looks like a dependency issue... i think the zip-task needs an assembly (namely ICSharpCode.SharpZipLib) to zip your files. Take a look here: http://www.icsharpcode.net/opensource/sharpziplib/Download.aspx or google for the assembly name by yourself and add that to your solution.. if you already did that try adding it via nuget to get the dependencies of that assembly resolved
Got it,
Just needed to include:
<Import Project="MSBuild.Community.Tasks.Targets" />
ICSharpCode here
Did you have a look at this post, if it answers your question.
More recent version of Community Tasks requires Ionic.Zip.Reduced.dll now. Put that in my .build directory and all's well for me.

Using NuGet PackageRestore with msbuild

I have a simple class library project (with Class1) and have enabled NuGet Package Restore for the solution.
That imports the restorepackages task into the .csproj file.
I can compile the project with
C:>msbuild myproj.csproj /t:compile
And I can call the restorepackages task successfully before adding packages with
C:>msbuild myproj.csproj /t:restorepackages
However, adding any package will cause the restorepackages task to fail with an error 3.
It seems that the NuGet task is called with a wrong working directory, and you may actually fix the behavior by removing the workingdir attribut in the NuGet.targets file, that was added to the solution.
Edit the task like this:
<Exec Command="$(RestoreCommand)"
LogStandardErrorAsError="true"
Condition="Exists('$(PackagesConfig)')"
WorkingDirectory="$(NuGetToolsPath)" />
and remove the working dir:
<Exec Command="$(RestoreCommand)"
LogStandardErrorAsError="true"
Condition="Exists('$(PackagesConfig)')"
/>
It seems to work as expected both from commandline msbuild and within VS2010.
Does anyone know if this change might break any tooling?
Can it be related to the issue "Package Restore's $(SolutionDir) goes too far"?
Did you check the injected SolutionDir property in your project file? It might be that the generated relative path won't point to the actual solution dir.

How do I add an MSBuild .proj file to my solution?

Does anyone know how to add a an MSBuild .proj file to my solution?
I was just given existing code from a vendor with a solution that references an MSBuild .proj file as one of its projects. When I open the solution, the project shows as (unavailable). It appears that I need to install some sort of project template to get this project to open correctly. I installed the Codeplex MSBuild Template, but this doesn't appear to be it.
Any ideas?
If you don't need IDE support, it's possible to do this using MSBuild solution extension targets.
Create a file named "before.SolutionName.sln.targets" with the following code:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ProjectReference Include="CustomProject\CustomProject.proj">
<AdditionalProperties>Configuration=$(Configuration); Platform=AnyCPU</AdditionalProperties>
<Configuration>$(Configuration)</Configuration>
<Platform>AnyCPU</Platform>
</ProjectReference>
</ItemGroup>
</Project>
When your solution is built at command line by MSBuild (ie/ build server) the custom MSBuild project will be pulled into the temporary in-memory project file that MSBuild converts the solution into.
I actually got it to work! I re-started Visual Studio and still saw that the projects were unavailable after installing the MSBuild Template mentioned above. I had to manually reload the projects. That fixed the issue.

MSBuild doesn't pick up references of the referenced project

I bumped into a strange situation with MSBuild just now. There's a solution which has three projects: LibX, LibY and Exe. Exe references LibX. LibX in its turn references LibY, has some content files, and also references to a third-party library (several pre-built assemblies installed in both GAC and local lib folder). The third-party library is marked as "Copy Local" ("private") and appears in the output of the LibX project, as the LibY's output and LibX's content files do. Now, Exe project's output has LibX project output, content files of the LibX project, LibY project output (coming from LibX), but NO third-party library's assemblies.
Now I worked this around by referencing the third-party library directly in Exe project, but I don't feel this is a "right" solution.
Anyone had this problem before?
There is a difference in behavior when building with MSBuild (i.e. command line, TFS Build and other tools) compared to building with Visual Studio. The secondary references are not included in the references variable sent into MSBuild compile tasks.
There are several extension points provided by MSBuild to change how references are to be resolved. I have successfully used AfterResolveReference to fix this issue for some of my projects - I have posted more info about the background on my blog.
The workaround is to add the following code into you vbproj or csproj files
<Target Name="AfterResolveReferences">
<!-- Redefine referencepath to add dependencyies-->
<ItemGroup>
<ReferencePath Include="#(ReferenceDependencyPaths)">
</ReferencePath>
</ItemGroup>
</Target>
Microsoft has stated that this is a won't fix on Connect
You can actually go into the Microsoft.CSharp.targets or Microsoft.VisualBasic.targets file (located in the framework directory, usually C:\Windows\Microsoft.NET\Framework\v3.5) and modify the csc or vbc task parameters to include additional reference dependencies. In the file (VB targets, line 166; C# targets, line 164) change:\
References="#(ReferencePath)"
to
References="#(ReferencePath);#(ReferenceDependencyPaths)"
This might cause other issues depending on how complicated things are and it may play tricks with the Visual Studio inproc compiler, but it's the only way to do it in MSBuild that I've found.
josant's answer almost worked for me; I kept getting an error in Visual Studio when I tried that:
A problem occurred while trying to set the "References" parameter for the IDE's in-process compiler. Error HRESULT E_FAIL has been returned from a call to a COM component
The solution to my problem was to put a condition on the ItemGroup, like this:
<Target Name="AfterResolveReferences">
<!-- Redefine referencepath to add dependencies-->
<ItemGroup Condition=" '$(BuildingInsideVisualStudio)' != 'true' ">
<ReferencePath Include="#(ReferenceDependencyPaths)"></ReferencePath>
</ItemGroup>
</Target>
That caused Visual Studio to ignore the reference change completely, and the build works fine locally and on the build server.
Yes, I've had that problem, too. Though I'd love to say otherwise, I believe you must include all transitive dependencies as references in your build file.
I've combined Alex Yakunin's solution with one that will also copy native dll's.
The AfterResolveReferences method fails if you've got a directed graph not a tree with a "trying to deploy different copies of the dll" error. (cf. How to configure msbuild/MSVC to deploy dependent files of dependent assemblies)