Smarter File nesting inside csproj wildcard - c#

I need better file nesting.
I have Index.razor, Index.razor.cs, Index.Model.cs, Index.Interface.cs inside the Pages folder.
In csproj
I have
<ItemGroup>
<Compile Update="Pages\Index.razor.cs" DependentUpon="Pages\Index.razor" />
<Compile Update="Pages\Index.Model.cs" DependentUpon="Pages\Index.razor" />
<Compile Update="Pages\Index.Interface.cs" DependentUpon="Pages\Index.razor" />
</ItemGroup>
I created this functionality into Wildcard
<ItemGroup>
<Compile Update="**\*.Interface.cs" DependentUpon="$([System.String]::Copy('%(FileName)').Replace('.Interface', '.razor'))" />
<Compile Update="**\*.Model.cs" DependentUpon="$([System.String]::Copy('%(FileName)').Replace('.Model', '.razor'))" />
</ItemGroup>
What I want is better version of this
<ItemGroup>
<Compile Update="**\*.Interface.cs" Condition="Exists('Check Razor')" >
<DependentUpon>"$([System.String]::Copy('%(FileName)').Replace('.Interface', '.razor'))"</DependentUpon>
</Compile>
<Compile Update="**\*.Model.cs" Condition="Exists('Check Razor')" >
<DependentUpon>"$([System.String]::Copy('%(FileName)').Replace('.Model', '.razor'))"</DependentUpon>
</Compile>
<Compile Update="**\*.Interface.cs" Condition="Exists('Check cshtml')" >
<DependentUpon>"$([System.String]::Copy('%(FileName)').Replace('.Interface', '.cshtml'))"</DependentUpon>
</Compile>
<Compile Update="**\*.Model.cs" Condition="Exists('Check cshtml')" >
<DependentUpon>"$([System.String]::Copy('%(FileName)').Replace('.Model', '.cshtml'))"</DependentUpon>
</Compile>
Need to check here also
<Compile Update="**\*.Interface.cs" DependentUpon="$([System.String]::Copy('%(FileName)').Replace('.Interface', '.cs'))" />
<Compile Update="**\*.Model.cs" DependentUpon="$([System.String]::Copy('%(FileName)').Replace('.Model', '.cs'))" />
</ItemGroup>
So that I can use Isolation in cshtml and razor project without hasle.

For example to work in xaml, you can use MSBuild15's static update syntax.
<Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
MSbuild splits paths into ( => ) and ( => ), so it can be used to reference xaml files.
Filenamefoo.xaml.csfoo.xamlExtensionfoo.xaml.cs.cs%(Filename)

Related

.NET Azure Functions - Dependency Injection Issue

On Startup.cs in my Azure Function v2 project:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using MyCompany.MyLib.Contracts; //namespace from external library
[assembly: FunctionsStartup(typeof(Startup))]
namespace Test
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient(typeof(Logging.ILogger<>), typeof(Logging.Logger<>));
builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<IBillingLogic, BillingLogic>(); //---> loads up from above referenced "MyCompany.MyLib.Contracts" namespace and this namespace is from externally referenced class library but with in same solution
}
}
}
The above code with my own custom classes within function app project like "EmailLogic", "Logger" works fine.
But the moment I added up custom classes to services container like "BillingLogic" from external C# library project which is added as reference project from the existing visual studio solution it throws up below issue:
"A host error has occurred during startup operation '945918c0-af3a-4d50-ab1d-ac405d4f1c7b'. [2/3/2020 2:11:02 PM] MyFunction.FunctionApp: Could not load file or assembly 'MyCompany.MyLib.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly ''MyCompany.MyLib.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
If these lines from "referenced external projects" are removed,
using MyCompany.MyLib.Contracts;
builder.Services.AddTransient<IBillingLogic, BillingLogic>();
startup.cs works as expected but referring this external class from referenced project is must for my solution.
My Azure function csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Storage.Queue" Version="11.1.2" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.8" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
<PackageReference Include="NLog" Version="4.6.8" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog.Extensions.AzureStorage" Version="1.1.4" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.9.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyCSharpLib.DataStore\MyCSharpLib.DataStore.csproj">
<Private>true</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
<None Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
MyCSharpLib.DataStore.csproj file:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.6" />
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.9.2" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.1.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.1" />
<PackageReference Include="Polly" Version="5.3.1" />
<PackageReference Include="StackExchange.Redis" Version="1.2.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyContractLib.Contracts\MyContractLib.Contracts.csproj" />
</ItemGroup>
</Project>
MyCSharpLib.DataStore
.\MyContractLib.Contracts\MyContractLib.Contracts.csproj
My Azure function csproj file:
<ProjectReference Include="..\MyCSharpLib.DataStore\MyCSharpLib.DataStore.csproj">
so
using MyCompany.MyLib.Contracts;
is coming through the ref to DataStore which then has ref to MyContractLib.Contracts
But it is not coping the dll as its silly, so either get Azure function csproj to ref MyLib.Contracts
or do this
How to set dependencies when I use .NET Standard 2.0 DLL libraries with a .NET Framework console application?
which is on all your std libs add
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
so on both your standard libs
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
if this does not work i will delete

Invalid framework identifier Dotnet restore, docker build

i'm having this error when i try to run docker build in my dotnet core API:
Invalid framework identifier ''
Here is my dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY Backend/AppManagerAPI/AppManagerAPI.csproj Backend/AppManagerAPI/
COPY Backend/DTO/DTO.csproj Backend/DTO/
COPY nuget.config ./
COPY Build/dependencies.props ./Build
COPY Backend/Database/Database.csproj Backend/Database/
COPY Backend/Service/Service.csproj Backend/Service/
COPY Utilities/Utilities.csproj Utilities/
RUN dotnet restore "Backend/AppManagerAPI/AppManagerAPI.csproj"
COPY . .
WORKDIR "/src/Backend/AppManagerAPI"
RUN dotnet build "AppManagerAPI.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "AppManagerAPI.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "AppManagerAPI.dll"]
and the full error stack:
$ docker build -t appmanager .
Sending build context to Docker daemon 560.6kB
Step 1/23 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
---> 34973cab5999
Step 2/23 : WORKDIR /app
---> Using cache
---> c402eb945a47
Step 3/23 : EXPOSE 80
---> Using cache
---> 8ac4a84a040e
Step 4/23 : EXPOSE 443
---> Using cache
---> 3c5014f9b6d5
Step 5/23 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
---> 08657316a4cd
Step 6/23 : WORKDIR /src
---> Using cache
---> e851dfaa1225
Step 7/23 : COPY Backend/AppManagerAPI/AppManagerAPI.csproj Backend/AppManagerAPI/
---> Using cache
---> 1eaa1d28c559
Step 8/23 : COPY Backend/DTO/DTO.csproj Backend/DTO/
---> Using cache
---> 81f9260e48a0
Step 9/23 : COPY nuget.config ./
---> Using cache
---> 3901e5ab8090
Step 10/23 : COPY Build/dependencies.props ./Build
---> Using cache
---> 35128353acde
Step 11/23 : COPY Backend/Database/Database.csproj Backend/Database/
---> Using cache
---> 25686efb1af9
Step 12/23 : COPY Backend/Service/Service.csproj Backend/Service/
---> Using cache
---> 3287a7a78971
Step 13/23 : COPY Utilities/Utilities.csproj Utilities/
---> Using cache
---> fe57c187d929
Step 14/23 : RUN dotnet restore "Backend/AppManagerAPI/AppManagerAPI.csproj"
---> Running in 33780f69aa7d
/usr/share/dotnet/sdk/2.2.401/NuGet.targets(123,5): error : Invalid framework identifier ''. [/src/Backend/AppManagerAPI/AppManagerAPI.csproj]
The command '/bin/sh -c dotnet restore "Backend/AppManagerAPI/AppManagerAPI.csproj"' returned a non-zero code: 1
I've already tried everything that i could think of, i was wondering if it has anything to do with my properties.props file, but copying it to the container didn't work. Any help would be appreciated.
UPDATE
Here's is my AppManagerAPI.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>$(NetCoreTargetVersion)</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<UserSecretsId>d37c9296-55fb-4c04-ad4e-3d1f5451dc28</UserSecretsId>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<NoWarn></NoWarn>
<AllowUnsafeBlocks></AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Remove="API.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Alpha.WebUtils.Core" Version="$(AlphaWebUtilsCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.App">
<PrivateAssets Condition="'%(PackageReference.Version)' == ''">all</PrivateAssets>
<Publish Condition="'%(PackageReference.Version)' == ''">true</Publish>
</PackageReference>
<PackageReference Include="Alpha.Utils.Core" Version="$(AlphaUtilsCorePackageVersion)" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="$(AutomapperDIPackageVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.4.10" />
<PackageReference Include="Scrutor" Version="$(ScrutorPackageVersion)" />
<PackageReference Include="Alpha.Backend.Core" Version="$(AlphaBackendCorePackageVersion)" />
<PackageReference Include="Alpha.Backend.EFCore" Version="$(AlphaBackendEFCorePackageVersion)" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbuckleAspNetCorePackageVersion)" />
<PackageReference Include="NetEscapades.Extensions.Logging.RollingFile" Version="$(LoggingRollingFilePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Api.Analyzers" Version="$(ApiAnalyzersPackageVersion)" />
<PackageReference Include="EfCore.GenericBizRunner" Version="$(EfCoreGenericBizRunnerPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DTO\DTO.csproj" />
<ProjectReference Include="..\Service\Service.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
<Folder Include="wwwroot\Upload\" />
<Folder Include="logs\" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Controllers\Administracion\RutasController.cs" />
<Compile Remove="Controllers\Administracion\SectoresController.cs" />
<Compile Remove="Controllers\Administracion\ConsultaRutasController.cs" />
<Compile Remove="Controllers\Administracion\ComercioEntidadTipoClienteController.cs" />
<Compile Remove="Controllers\Administracion\LugaresController.cs" />
<Compile Remove="Controllers\Genericos\CentrosController.cs" />
<Compile Remove="Controllers\Genericos\MenuController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\AlisysController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\OrdenesIntervencionesController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\SauController.cs" />
<Compile Remove="Controllers\Genericos\SystemController.cs" />
<Compile Remove="Controllers\Mantenimiento\AccesoriosController.cs" />
<Compile Remove="Controllers\Mantenimiento\DiasFestivosController.cs" />
<Compile Remove="Controllers\Mantenimiento\EemmsController.cs" />
<Compile Remove="Controllers\Mantenimiento\EntidadesMantenedorasController.cs" />
<Compile Remove="Controllers\Mantenimiento\EtiquetasSatController.cs" />
<Compile Remove="Controllers\Mantenimiento\GruposCualificadoresController.cs" />
<Compile Remove="Controllers\Mantenimiento\HorariosController.cs" />
<Compile Remove="Controllers\Mantenimiento\IncidenciasController.cs" />
<Compile Remove="Controllers\Mantenimiento\MarcasController.cs" />
<Compile Remove="Controllers\Mantenimiento\ModelosController.cs" />
<Compile Remove="Controllers\Mantenimiento\ModelosIndicadosController.cs" />
<Compile Remove="Controllers\Mantenimiento\MotivoCierreController.cs" />
<Compile Remove="Controllers\Mantenimiento\MotivosParadaController.cs" />
<Compile Remove="Controllers\Mantenimiento\PatronesCentroController.cs" />
<Compile Remove="Controllers\Mantenimiento\PerfilesUsuarioController.cs" />
<Compile Remove="Controllers\Mantenimiento\PermisosController.cs" />
<Compile Remove="Controllers\Mantenimiento\PiezaAlmacenPrecioController.cs" />
<Compile Remove="Controllers\Mantenimiento\PiezasController.cs" />
<Compile Remove="Controllers\Mantenimiento\SoftwaresController.cs" />
<Compile Remove="Controllers\Mantenimiento\TecnologiasController.cs" />
<Compile Remove="Controllers\Mantenimiento\TipoActualizacionController.cs" />
<Compile Remove="Controllers\Mantenimiento\TipoIncidenciaController.cs" />
<Compile Remove="Controllers\Mantenimiento\TipoIntervencionController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposClientesController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposCoberturasController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposLugarController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposMantenimientoController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposModoTerminalController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposSeguridadTerminalController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposTecnologiaController.cs" />
<Compile Remove="Controllers\Mantenimiento\TiposTerminalController.cs" />
<Compile Remove="Controllers\Administracion\DelegacionesController.cs" />
<Compile Remove="Controllers\Administracion\ListasCorreoController.cs" />
<Compile Remove="Controllers\Genericos\CodigosPostalesController.cs" />
<Compile Remove="Controllers\Genericos\MotivoTipoEntidadController.cs" />
<Compile Remove="Controllers\Genericos\PrioridadesController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\BloqueosController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\EstadosIntervencionController.cs" />
<Compile Remove="Controllers\GestionIntervenciones\EstadosOdinController.cs" />
<Compile Remove="Controllers\Mantenimiento\Configuracion\CalendarioLaboralesController.cs" />
<Compile Remove="Controllers\Mantenimiento\Configuracion\NotificacionesEmailController.cs" />
<Compile Remove="Controllers\Mantenimiento\AccionesController.cs" />
</ItemGroup>
</Project>
The problem was that i needed to copy my Directory.Build.props file and now is working. Just added this line to my dockerfile
COPY Directory.Build.props ./

MSBuild. Create EmbeddedResource before build

I want to embed local references in the assembly before compiling the main unit. But the written target does not work.
<Target Name="EmbedLocal" BeforeTargets="CoreCompile">
<Message Text="Run EmbedLocal for $(MSBuildProjectFullPath)..." Importance="high"/>
<ItemGroup>
<EmbeddedResource Include="#( ReferencePath->WithMetadataValue( 'CopyLocal', 'true' )->Metadata( 'FullPath' ) )"/>
</ItemGroup>
<Message Text="Embed local references complete for $(OutputPath)$(TargetFileName)." Importance="high" />
</Target>
#(EmbeddedResource) at this moment contains valid list of paths.
Update:
Now my import file contains:
<Project ToolsVersion="$(MSBuildToolsVersion)" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<EmbedLocalReferences Condition=" '$(EmbedLocalReferences)' == '' ">True</EmbedLocalReferences>
</PropertyGroup>
<Target Name="EmbedLocal" BeforeTargets="ResolveReferences" Condition=" '$(EmbedLocalReferences)' == 'True' ">
<Message Text="Run EmbedLocal for $(MSBuildProjectFullPath)..." Importance="high"/>
<ItemGroup>
<EmbeddedResource Include="#(ReferenceCopyLocalPaths->WithMetadataValue( 'Extension', '.dll' )->Metadata( 'FullPath' ))">
<LogicalName>%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
<Message Text="Embed local references complete for $(OutputPath)$(TargetFileName)." Importance="high" />
</Target>
</Project>
It works fine. Output assembly contains all .dll references as EmbeddedResource.
MSBuild. Create EmbeddedResource before build
You can try to use BeforeBuild action to the csproj file to include the embedded resources:
<Target Name="BeforeBuild">
...
<ItemGroup>
<EmbeddedResource Include="..."/>
</ItemGroup>
...
</Target>
Now MSBuild will add this file as embedded resource into your assembly.
Update:
Thanks #Martin Ullrich. He pointed out the correct direction, we could use <Target Name="EmbedLocal" BeforeTargets="PrepareForBuild"> in the Directory.Build.props to resolve this issue. You can check if it works for you.
<Target Name="EmbedLocal" BeforeTargets="PrepareForBuild">
...
<ItemGroup>
<EmbeddedResource Include="..."/>
</ItemGroup>
...
</Target>

ms build dynamic resource naming

I want to add some files to embedded resourses at compile time with special naming. For this I wrote in .csproj
<Target Name="BeforeBuild" >
<ItemGroup>
<EmbeddedResource Include="..\Bin\$(Configuration)\*.*">
</EmbeddedResource>
</ItemGroup>
</Target>
But it always set <LogicalName> to default.
How can I do this?
I found solution. This renaming works:
<Target Name="BeforeBuild">
<ItemGroup>
<Frameworks Include="..\Bin\$(Configuration)\Frameworks\*.*" />
<Steps Include="..\Bin\$(Configuration)\Steps\*.*" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="#(Frameworks)">
<LogicalName>Frameworks.%(Filename)%(Extension)</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="#(Steps)">
<LogicalName>Steps.%(Filename)%(Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
<Message Text="EmbeddedResource - #(EmbeddedResource)" />
</Target>

How to add a linked file to a csproj file with MSBuild. (3.5 Framework)

I'm trying to us MSBuild to add a linked file to my .csproj file.
This is .Net Framework 3.5 (and not 4.0). I mention that because I'm seen some 4.0 specific stuff trying to manipulate the XML.
Here is what I'm starting with:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MySuperCoolClass.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
This is what I'm trying to get:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MySuperCoolClass.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\SomeFunFolder\MyLinkFile.ext">
<Link>MyLinkFile.ext</Link>
</Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
I have:
MSBuild.Community.Tasks.dll
and
MSBuild.ExtensionPack.dll
available.
Any concrete help?
One liner comments like use 'MSBuild.ExtensionPack.Xml.XmlFile' won't be helpful.
But I appreciate any pointers or coded examples immensely.
Well, I opened up the code for "MSBuild.ExtensionPack.Xml.XmlFile(.cs)" and looked around.
Thank goodness for open source.
I figured out..you gotta "build it up".
And I had to add a little voodoo trick (with the "MyUniqueKeyHelper123" seen below).
I'll post here.
If you're having trouble with "MSBuild.ExtensionPack.Xml.XmlFile(.cs)", get the source code and look at it. You can figure out how to set the properties by looking at the method.
It was a little tricky at first, but figure-out-able.
<PropertyGroup>
<MSBuildExtensionPackPath Condition="'$(MSBuildExtensionPackPath)' == ''">.\ExtensionPackFiles</MSBuildExtensionPackPath>
<MSBuildExtensionPackLib>$(MSBuildExtensionPackPath)\MSBuild.ExtensionPack.dll</MSBuildExtensionPackLib>
</PropertyGroup>
<UsingTask AssemblyFile="$(MSBuildExtensionPackLib)" TaskName="MSBuild.ExtensionPack.Xml.XmlFile" />
<Target Name="XmlTest01Target">
<Message Text="MSBuildExtensionPackLib = $(MSBuildExtensionPackLib)" />
<!--
The goal is:
<ItemGroup>
<Content Include="..\..\SomeFunFolder\MyLinkFile.ext">
<Link>MyLinkFile.ext</Link>
</Content>
</ItemGroup>
-->
<!-- Define a custom namespace. I used "peanut" just to show it is any name you give it -->
<ItemGroup>
<Namespaces Include="Mynamespace">
<Prefix>peanut</Prefix>
<Uri>http://schemas.microsoft.com/developer/msbuild/2003</Uri>
</Namespaces>
</ItemGroup>
<!--
Add the <ItemGroup> (new) Element. HOWEVER, since there will probably be multiple <ItemGroup> nodes, tag it with some unique identifier. Will Clean up later.
-->
<XmlFile
TaskAction="AddElement"
Namespaces="#(Namespaces)"
File=".\MyCSharpProjectFile.csproj"
Element="ItemGroup"
Key="MyUniqueKeyHelper123"
Value ="MyUniqueValueHelper123"
XPath="//peanut:Project"
/>
<!--
Add the <Content> (new) Element. With Attribute Value.
-->
<XmlFile
TaskAction="AddElement"
File=".\MyCSharpProjectFile.csproj"
Element="Content"
Key="Include"
Value ="..\..\SomeFunFolder\MyLinkFile.ext"
Namespaces="#(Namespaces)"
XPath="//peanut:Project/peanut:ItemGroup[#MyUniqueKeyHelper123='MyUniqueValueHelper123']"
/>
<!--
Add the <Content> (new) Element. With Element Value Value.
-->
<XmlFile
TaskAction="AddElement"
File=".\MyCSharpProjectFile.csproj"
Element="Link"
InnerText ="MyLinkFile.ext"
Namespaces="#(Namespaces)"
XPath="//peanut:Project/peanut:ItemGroup[#MyUniqueKeyHelper123='MyUniqueValueHelper123']"
/>
<!--
Clean up the "unique" attribute to leave clean xml.
-->
<XmlFile
TaskAction="RemoveAttribute"
File=".\MyCSharpProjectFile.csproj"
Element="Link"
Key="MyUniqueKeyHelper123"
Namespaces="#(Namespaces)"
XPath="//peanut:Project/peanut:ItemGroup[#MyUniqueKeyHelper123='MyUniqueValueHelper123']"
/>
</Target>
Is it feasible for you to use the following?
using System;
using System.Text;
using Microsoft.Build.BuildEngine;
namespace ConsoleApplication11
{
class Program
{
static void Main(string[] args)
{
var fullPathName = #"PathToProjectFile\Project.csproj";
Project project = new Project();
project.Load(fullPathName);
var itemGroup = project.AddNewItemGroup();
var buildItem = itemGroup.AddNewItem("Content", #"..\..\SomeFunFolder\MyLinkFile.ext");
buildItem.SetMetadata("Link", "MyLinkFile.ext");
project.Save(fullPathName, Encoding.UTF8);
}
}
}

Categories