MSBuild: Include a custom resource file as embedded resource - visual-studio

I am dynamically generating a resource-file at build time with MSBuild, but in order to be able to read from this resource file at run-time, I need it to be an embedded resource.
I have looked everywhere at how to mark a file in a .csproj as embedded resource, I have even tried this to no avail.
<ItemGroup>
<Content Include="Infrastructure\Content\Store\content_store_en.json" />
<EmbeddedResource Include="Infrastructure\Content\Store\content_store_en.json">
</EmbeddedResource>
</ItemGroup>
Is there any way I can achieve this ?

Here is how you do it:
<Target Name="BeforeBuild">
<CreateItem Include="Infrastructure\**\*.json">
<Output ItemName="EmbeddedResource" TaskParameter="Include" />
</CreateItem>
</Target>
Source: http://ayende.com/blog/4446/how-to-setup-dynamic-groups-in-msbuild-without-visual-studio-ruining-them
I changed the CreateItem attribute so it will reflect your question.
I hope it helps...

Related

How do I prevent text template generator from running on every VS build?

I have a VS 2019 solution with several projects. There is one project that every other project depends on and I have some T4 templates in that project. The templates are regenerated every time I invoke the Build command (no changes) and therefore all the dependent projects are also rebuilt.
How can I fix this so that the templates are only regenerated when necessary? My project file has the following:
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<TransformOutOfDateOnly>true</TransformOutOfDateOnly>
</PropertyGroup>
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />
<ItemGroup>
<None Update="Messages\Messages.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Messages.generated.cs</LastGenOutput>
</None>
<EmbeddedResource Update="Messages\Messages.de.resx" />
<EmbeddedResource Update="Messages\Messages.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Messages.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Target Name="CallTransformOnBuild" BeforeTargets="CoreCompile">
<CallTarget Targets="TransformDuringBuild" />
</Target>
I only want the transform to run on build if:
Messages.Generated.cs doesn't exist
Messages.tt changed
Messages.resx changed
You need to make sure the following XML Tags' are set to false.
<TransformOnBuild>False</TransformOnBuild>
<OverwriteReadOnlyOutputFiles>False</OverwriteReadOnlyOutputFiles>

How to mark files of a folder as embedded resource with wildcards with the new project format?

My scenario is simple.
I have test project where i want all files within a folder to be marked as embedded resource by default. To prevent someone from doing mistakes here i want this to be automatic through wildcards
I looked at this question, which looked very promising.
MSBuild: Include a custom resource file as embedded resource
However that does not seem to work with the new csproj format. Does anyone know what i should be doing different for it to work with the new format?
My current code is this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.2.1" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.2.1" />
</ItemGroup>
<Target Name="BeforeBuild">
<CreateItem Include="TestContent\*.cs">
<Output ItemName="EmbeddedResource" TaskParameter="Include" />
</CreateItem>
</Target>
</Project>
You can try this script:
<Target Name="MyCustomStep" BeforeTargets="BeforeBuild">
<CreateItem Include="TestContent\*.cs">
<Output ItemName="EmbeddedResource" TaskParameter="Include" />
</CreateItem>
</Target>
There exists difference between the BeforeBuild Target in old and new csproj format. (Or maybe the difference between .net core and .net framewrok, not sure about this point)
Some discoveries when I set the msbuild verbosity to Detailed:
1.For projects that target .net framework using the old csproj format:
The BeforeBuild target will exactly execute the CreateItem Task. So it works for old-format project files.
2.For projects that target .net core using new sdk format:
The BeforeBuild target seems not to execute the task as what we expected.
After defining the Custom target which executes before the BeforeBuild target, it works in my machine:

Need help in understanding CustomFilesToInclude property in MSbuild

I have a issue in copying html files to deploy location using MSBuild.
Please help me in understanding the following:
<Target Name="CustomCollectFiles">
<ItemGroup>
<FilesForPackagingFromProject Include="#(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="CustomCollectFiles">
<ItemGroup>
<FilesForPackagingFromProject Include="#(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="#(CustomFilesToIncludeSkipExistingCheck)">
<DestinationRelativePath>%(CustomFilesToIncludeSkipExistingCheck.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
<Error Text="Custom file exists in project files already: %(CustomFilesToInclude.FullPath)"
Condition="Exists('$(MainProjectRootDir)\%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
DefineCustomFiles;
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
I've never used MSDeploy.
But I'd say it just adds DestinationRelativePath metadata to item and injects targets DefineCustomFiles and CustomCollectFiles to be called before existing CopyAllFilesToSingleFolderForPackageDependsOn targets.
I see it can be used by Microsoft.Web.Publishing.targets.
The code sample you've provided is not complete to say what's going on.
It looks like this: http://sedodream.com/2010/03/10/WebDeploymentToolIncludingOtherFiles.aspx

Visual Studio 2010 custom output path for references

I have VS2010 project with several third-party references. Is there any way to automatically output these references to $(OutputPath)\Libraries instead of just $(OutputPath)?
Right now I have a custom AfterBuild target which looks like this,
<Target Name="AfterBuild">
<ItemGroup>
<LibFiles Include="$(SolutionDir)\lib\dotnetzip-1.9\Release\Ionic.Zip.dll" />
<LibFiles Include="$(SolutionDir)\lib\ninject-2.2.0.0\Ninject.dll" />
<LibFiles Include="$(SolutionDir)\lib\nlog-2.0.0.2000\NLog.dll" />
<LibFiles Include="$(SolutionDir)\lib\nlog-2.0.0.2000\NLog.Extended.dll" />
</ItemGroup>
<Copy SourceFiles="#(LibFiles)" DestinationFolder="$(OutputPath)\Libraries" />
</Target>
However this gets tiring since I have to manually add references to #(LibFiles) when adding a reference in VS.
Is there an easier way?
Try to do it this way:
<ItemGroup>
<LibFiles Include="$(SolutionDir)\lib\**\*.dll" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="#(LibFiles)">
<Copy SourceFiles="#(LibFiles)" DestinationFolder="$(OutputPath)\Libraries" />
</Target>
Pros:
you don't have to modify AfterBuild target everytime you add new
reference into your projects
libraries are copied only once or if datetime of any of files in
#(LibFiles) is changed (after update)
Cons:
you will have more dlls in Libraries folder, I guess. But you can filter them using Exclude="$(SolutionDir)\lib\**\Debug\*.dll" for example

Wildcard for content in an XNA content project?

I have an XNA 3.1 content project (.contentproj) with the following:
<ItemGroup>
<Compile Include="tiles\B000N800.BMP">
<Name>B000N800</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
<Compile Include="tiles\B000N801.BMP">
<Name>B000N801</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
(... and so on ...)
</ItemGroup>
What I'd like to do is be able to specify a wildcard so that tiles\*.bmp gets compiled instead - so that I don't have to keep re-synchronising the content project when I add and remove textures from the "tiles" directory.
Does anyone know a way to do this?
Ideally the solution would ignore the hidden ".svn" directory, under "tiles". And also the content project would continue to work in Visual Studio.
You'll have to use wildcard in your item definition :
<ItemGroup>
<Compile Include="tiles\**\*.BMP"
Exclude="tiles\.svn\*">
<Name>%(Compile.Filename)</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
I found a blog post by Shawn Hargreaves that describes how to do this for XNA 1.0:
Wildcard content using MSBuild
Based on that, here is what I did which works with XNA 3.1 (and doesn't cause those weird _0 to appear):
Create a separate "tiles.proj" file with the following content:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<ItemGroup>
<WildcardContent Include="tiles\**\*.BMP" Exclude="tiles\.svn\*">
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</WildcardContent>
</ItemGroup>
<Target Name="BeforeBuild">
<CreateItem Include="#(WildcardContent)" AdditionalMetadata="Name=%(FileName)">
<Output TaskParameter="Include" ItemName="Compile" />
</CreateItem>
</Target>
</Project>
And in the original ".contentproj" file, right before </Project>, add:
<Import Project="tiles.proj" />

Resources