NLog.config Transformation - asp.net

I have an NLog.config file that I want transformed before publishing my site. Similar to how web.config is transformed. How do I accomplish this? I couldn't find any solid resources on how to do this.
I tried adding a transform to the csproj
<Target Name="BeforeBuild" Condition="exists('NLog.$(Configuration).config')">
<Message Text="Tranforming NLog..."/>
<TransformXml Source="NLog.config" Transform="NLog.$(Configuration).config" Destination="$(OutputPath)\NLog.config" />
</Target>
Also added the NLog to csproj:
<Content Include="NLog.config">
<SubType>Designer</SubType>
</Content>
<None Include="NLog.aws-prod.config">
<DependentUpon>NLog.config</DependentUpon>
</None>
<None Include="NLog.aws-test.config">
<DependentUpon>NLog.config</DependentUpon>
</None>
but this doesn't copy the transformed NLog.config to the package directory (or when deploying to AWS). The original NLog.config is copied and a copy in the /bin directory as well.

SlowCheetah seems to do what I want. I've tried it and I've made changes to my csproj to add:
<TransformOnBuild>true</TransformOnBuild>
and
<IsTransformFile>True</IsTransformFile>
so the final change looks like this:
<Content Include="NLog.config">
<TransformOnBuild>true</TransformOnBuild>
<SubType>Designer</SubType>
</Content>
<None Include="NLog.aws-prod.config">
<DependentUpon>NLog.config</DependentUpon>
<IsTransformFile>True</IsTransformFile>
<SubType>Designer</SubType>
</None>
<None Include="NLog.aws-test.config">
<DependentUpon>NLog.config</DependentUpon>
<IsTransformFile>True</IsTransformFile>
</None>
That's it and NLog.config is transformed!! This target below wasn't needed:
<Target Name="BeforeBuild" Condition="exists('NLog.$(Configuration).config')">
<Message Text="Tranforming NLog..."/>
<TransformXml Source="NLog.config" Transform="NLog.$(Configuration).config" Destination="$(OutputPath)\NLog.config" />
</Target>

Related

Xamarin.Forms SDK-Style multiplatform project with XAML

Have defined multitarget project:
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;xamarinios10;monoandroid9.0;</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.6.0.800" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3" />
<Compile Include="**\Shared\*.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('xamarinios')) ">
<Compile Include="**\iOS\*.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('monoandroid')) ">
<Compile Include="**\Android\*.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Shared\MyView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>
So, when i make my custom component only in code all compile and works well, but i would like to develop some custom controls using XAML.
But i got error of ambiguous call to method InitializeComponent() in MyView object.
How to make correct conditional configuration in .csproj for compiler to understand *.xaml and *.xaml.cs files ?
Adding these properties to common ItemGroup solved the problem:
<None Remove="**\Shared\*.xaml" />
<Compile Include="**\Shared\*.xaml.cs" DependentUpon="%(Filename)" />
<EmbeddedResource Include="**\Shared\*.xaml" Generator="MSBuild:UpdateDesignTimeXaml" />

Including a custom file in your build/publish for a .net core application

How do I include a custom file that is in the root of my project dir to be put into my build/publish folder?
If its a .json file it seems to come through automatically (probably because of .NET config being json)
I have a custom config file that is text based with a .txt extension.
I've tried:
<ItemGroup>
<DotnetPublishFiles Include="customfile.txt"></DotnetPublishFiles>
</ItemGroup>
And
<ItemGroup>
<Content Include="./*.txt" />
</ItemGroup>
As well as
<ItemGroup>
<Content Include="customfile.txt" />
</ItemGroup>
Also:
<_CustomFiles Include="$(MSBuildProjectDirectory)/customfile.txt" />
<DotNetPublishFiles Include="#(_CustomFiles)">
</DotNetPublishFiles>
</ItemGroup>
Nothing seems to work...
I'm using Visual Studio Code and .NET Core 3.1.
Any ideas?
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ItemGroup>
JSON (as well as other suitable) files are treated the same way by SDK style projects, so for your own custom files you need to ask MSBuild explicitly.
For publishing there is another tag: CopyToPublishDirectory
<ItemGroup>
<None Update="customfile.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<ItemGroup>

Repackage 3rd party libraries as NuGet package

I am using a 3rd party library which supports .NET Core, but not .NET Standard. They provide separate binary SDKs for each platform they support; win-x86, linux-x64, etc. For each platform there is a CoolSdkDotNetCore.dll, and a coolsdk.dll/so/dylib. The CoolSdkDotNetCore.dll files are indeed different for each platform - they're all exactly the same size, but have different SHA hashes.
For my own sanity I'd like to repackage all this as a single .nupkg using runtime identifiers to pull in the right stuff for a given platform, so that I can build for Windows, docker, etc without having to swap binaries around. I have a project file like so:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This produces a .nupkg that appears to have everything I need, but consuming projects don't actually get a reference to the CoolSdkDotNetCore assembly. In the bin folder, I see a runtimes folder with the native components, but no lib folders (the lib folders are definitely present in the actual nupkg).
What am I missing here? Do I need to go back and write a nuspec myself instead of trying to use a csproj to generate it all for me, or is there some other trick I can use?
edit:
Changing the library paths above from runtimes/<rid>/lib/netcore to runtimes/<rid>/netcoreapp allows the lib folders to be copied to the bin folder in a consuming project, but I'm still not able to actually reference the assembly. Manually adding a reference to CoolSdkDotNetCore like:
<Reference Include="CoolSdkDotNetCore">
<HintPath>CoolSdkDotNetCore.dll</HintPath>
</Reference>
Generates MSB3245 - Could not resolve this reference....
The answer is to include a single copy of the .NET Core assembly as a "ref". Which one doesn't really matter - this assembly will never be run, only loaded by the IDE and at compile time. At runtime, the correct assembly will be loaded from the runtimes folder. As a final gotcha, nuget will not pack the same file twice; if you have two or more items in the item group with the same value for the Update key, only the last one will actually get added to the final .nupkg. So, picking at random I made a copy of the windows/x64 dll in the root of my project, and updated my csproj thusly:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="ref/netcoreapp2.1/CoolSdkDotNetCore.dll" Update="CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

How to make Nop-Commerce 4.20 plugin ready for distribution

I am working with the new plugin of Nopcommerce 4.20. The plugin is almost completed but I need to make the plugin ready for distribution. But there are unnecessary folders created inside Nop.Web/Plugins/.
I made the Nop.Web and Nop.Web.Framework to "copy local=false" which are under Projects and deleted the plugin and build it again. But still, I am getting the unnecessary folders with two characters.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<Copyright>SOME_COPYRIGHT</Copyright>
<Company>YOUR_COMPANY</Company>
<Authors>SOME_AUTHORS</Authors>
<PackageLicenseUrl>PACKAGE_LICENSE_URL</PackageLicenseUrl>
<PackageProjectUrl>PACKAGE_PROJECT_URL</PackageProjectUrl>
<RepositoryUrl>REPOSITORY_URL</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<OutputPath>..\..\Presentation\Nop.Web\Plugins\Discount.ProductMix
</OutputPath>
<OutDir>$(OutputPath)</OutDir>
<!--Set this parameter to true to get the dlls copied from the NuGet
cache to the output of your project. You need to set this parameter to
true if your plugin has a nuget package to ensure that the dlls copied
from the NuGet cache to the output of your project-->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<None Remove="logo.jpeg" />
<None Remove="plugin.json" />
<None Remove="Views\Configure.cshtml" />
<None Remove="Views\DiscountProductAddPopup.cshtml" />
<None Remove="Views\_ViewImports.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="logo.jpeg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Views\DiscountProductAddPopup.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Views\Configure.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Views\_ViewImports.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Presentation\Nop.Web.Framework\Nop.Web.Framework.csproj">
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Presentation\Nop.Web\Nop.Web.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Update="Controllers\DiscountProductMixController.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Data\DiscountOfferMixMap.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Data\DiscountProductMixObjectContext.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="DiscountProductMixConfiguration.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Domain\DiscountOffers.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Infrastructure\DependencyRegistrar.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Infrastructure\PluginDBStartup.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Update="Models\ConfigurationModel.cs">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
</ItemGroup>
<!-- This target execute after "Build" target -->
<Target Name="NopTarget" AfterTargets="Build">
<!-- Delete unnecessary libraries from plugins path -->
<MSBuild Projects="#(ClearPluginAssemblies)" Properties="PluginPath=$(MSBuildProjectDirectory)\$(OutDir)" Targets="NopClear" />
</Target>
All things are perfect if you are not installing any Nuget Packages then please make false
<CopyLocalLockFileAssemblies>False</CopyLocalLockFileAssemblies>
and another thing
Add replace these lines
<ItemGroup>
<ProjectReference
Include="..\..\Presentation\Nop.Web.Framework\Nop.Web.Framework.csproj"/>
<ProjectReference Include="..\..\Presentation\Nop.Web\Nop.Web.csproj" />
<ClearPluginAssemblies Include="$(MSBuildProjectDirectory)\..\..\Build\ClearPluginAssemblies.proj" />
Try these changes can help you.
I also had a problem with unnecessary folders being created. This turned out to be caused by the .Net Core 3.0 SDK, which apparently builds plugins in a different way than the version 2.x SDK's did. To check for this, you can run dotnet --version from the command line from within your nopcommerce project folder. The version should not be higher than 2.x.
The fix was to just tell dotnet to use a specific SDK version for building the project. This was just a matter of adding a global.json file in my nopcommerce project folder containing these lines:
{
"sdk": {
"version": "2.2.402"
}
}
Running dotnet --version again now gives the output 2.2.402.

ASP.NET - Copying extra files on publish not working recursively

I have a web application project that I want to publish to a web server. There is a folder of files that are not included in the project, but need to be copied when it is published. I found a few posts on how to do this copying with MSBuild, but I cannot get it to copy all files/folders recursively in the main folder I want to copy.
The folder I want to copy is (proj)/Scripts. (This directory is excluded from the application project because I have all my JavaScript code in a separate project in the same solution, and this folder is copied from the JS project's output folder after it performs minification and other build tasks.)
Here is the section I have added to my *.csproj file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="Scripts\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>
<!-- whitespace and new line added for question readability -->
Scripts\%(RecursiveDir)%(Filename)%(Extension)
</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
This will copy any files in the top level of the /Scripts folder, but nothing in its subfolders.
How do I make it recursive?
Fixed my own problem:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="Scripts\**\*.*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Scripts\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<_CustomFiles Include="Scripts\*" /> had to be changed to
<_CustomFiles Include="Scripts\**\*.*" />
This worked for me:
<ItemGroup>
<Content Include="YourTargetDir\**\*.*">
<Link>YourTargetDir\%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

Resources