Visual Studio 2017 v15.3 doesn't copy nlog.config - visual-studio-2017

I just updated to Visual Studio 2017 v15.3 and Core 2.0 SDK.
I'm working with Igans Sakalauskas' Net Core Knockout project, it was built with Core 1.1 in VS 2017.
https://ignas.me/tech/net-core-knockoutjs-web-application/
I've left EnableDefaultContentItemsto the default of true and removed the Content Include statements from the .csproj file in the WebApplication1.Web project.
He is using nlog and there is a nlog.config in the root of the project. The project builds successfully but throws a file not found error when ran. It is looking for the nlog.config in the WebApplication1.Web\bin\Debug\netcoreapp1.1 folder. If I manually copy the file the project runs and all the tests pass.
What I cannot get to work is for VS to copy the nlog.config when the project builds.
If I add
<ItemGroup>
<Content Include="nlog.*" />
</ItemGroup>
to the .csproj I get the Duplicate 'Content' items ... The duplicate items were: 'nlog.config' error. https://aka.ms/sdkimplicititems
If I comment out the Contnet Include and set the EnableDefaultContentItems to false
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
I get a
Suppression State Error CS5001 Program does not contain a static 'Main' method suitable for an entry point
If I then restore the `Content Inculde' statements it gives this error:
Duplicate 'Content' items ... The duplicate items were: 'list of files' error
The Default Content Items is working with .js and .cs files in the wwwroot sub-folders.
If VS throws the Duplicate Content error when I Content Include an item why does it not copy the file without the Content Include?
In VS 2017 15.3 how do you configure the copying of a file nlog.config from the project's root to a bin sub-directory?

This is nothing to do with duplicate content items.
Revert to the recommended approach to handling duplicate content errors in Visual Studio 2017; this is what you started with:
I've left EnableDefaultContentItems to the default of true and removed
the Content Include statements from the .csproj file in the
WebApplication1.Web project.
Now add this to your .csproj file:
<ItemGroup>
<Content Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
This tells Visual Studio to update the existing content rule (the automatically generated one) to make it copy the file into the output directory on build.

Related

Project fails to build with error "does not reference '". NETFramework,Version=v4.7.2" framework'" after restore

I am trying to create a nuget package using MSBuild and am running into problems after I restore.
This error occurs after I do msbuild <solution> "/t:<project>" /t:restore /p:Configuration=Release. To be clear, that command executes successfully, no errors; however, if I try to clean, build, restore or pack following that command is when I get the following error. (note that <path-to-repo>, <solution> and <project> are substitutions)
Build FAILED.
"C:\Users\<path-to-repo>\build\win32\<solution>.sln" (<project>;restore target) (1) ->
"C:\Users\<path-to-repo>\extras\<project>\<project>.vcxproj.metaproj" (default target) (2) ->
"C:\Users\<path-to-repo>\extras\<project>\<project>.vcxproj" (default target) (4) ->
(ResolveNuGetPackageAssets target) ->
C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\NuGet\17.0\Microsoft.NuGet.targets(198,5): error : Your project does not reference ".NETFramework,Version=v4.7.2" framework. Add a reference to ".NETFramework,Version=v4.7.2" in the "TargetFrameworks" property of your project file and then re-run NuGet restore. [C:\Users\<path-to-repo>\extras\<project>\<project>.vcxproj]
The project restores and builds correctly before I add the following section to the .vcxproj file (which I believe is necessary in order to pack the project as a nuget package).
<ItemGroup>
<PackageReference Include="NuGet.Build.Tasks.Pack">
<Version>6.4.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
Simply adding that, and running restore and then clean/restore/build/pack afterwards all fail with the error.
This section is present in the project file which seems to correctly reference the target framework.
<PropertyGroup Label="Globals">
...
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
...
</PropertyGroup>
I've cleaned out all the bin/obj and other untracked files at the root of the repo with git clean -xdf as that was a very popular suggestion (the only change in the repo is the package reference above added to the project file); I am unaware of any files I would need to clean outside of the repo?
Thanks in advance for any help! Questions about this error seem to be asked a lot for different scenarios, seems like they might need better error messages.

Problem with using common .editorconfig file (imported in csproj) in Visual Studio 2019 Preview 4

I want to streamling code analysis and the respetive rules accross multiple projects and teams.
We used to do that by having a NuGet package that imported analyzers to projects (Microsoft.CodeAnalysis.FxCopAnalyzers and StyleCop.Analyzers) and defined a ruleset to define how each rule was handled by VS (error, warning, etc.).
I have been trying to setup this using a common .editorconfig file instead of the ruleset. The problem is that settings like the following just seem to be ignored when the .editorconfig file is imported from a shared folder.
dotnet_diagnostic.CA1062.severity = error
For the purpose of testing this, I have a very simple scenario that illustrates the problem.
The .editorconfig file is as follows:
[*.cs]
dotnet_diagnostic.CA1062.severity = error
#dotnet_code_quality.null_check_validation_methods = NotNull
Now this file is imported in a csproj like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Import Project="..\..\_Shared\Build.props" />
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
Build.props is like this:
<Project>
<PropertyGroup>
<SkipDefaultEditorConfigAsAdditionalFile>true</SkipDefaultEditorConfigAsAdditionalFile>
</PropertyGroup>
<ItemGroup Condition="Exists('$(MSBuildThisFileDirectory)\.editorconfig')" >
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\.editorconfig" />
</ItemGroup>
</Project>
The following code is supposed to trigger an error on CA1062:
public int Calculate(InputData input)
{
SmartGuard.NotNull(nameof(input), input);
if (this.Multiply)
{
return input.Value * 2;
}
else
{
return input.Value + 2;
}
}
But the result is a warning:
Now, if I change .editorconfig and uncomment the second line:
[*.cs]
dotnet_diagnostic.CA1062.severity = error
dotnet_code_quality.null_check_validation_methods = NotNull
The error goes way which means that null_check_validation_methods is being considered.
Why is that dotnet_diagnostic.CA1062.severity = error is being ignored?
This and other issues with the .editorconfig mechanics were reported in the following issues:
https://github.com/dotnet/roslyn/issues/38782
https://github.com/dotnet/roslyn/issues/43080
These have been solved and the original question is answered by implementing the recommendations referenced in those issues.
The problem you have comes from the fact, that the ".editorconfig" file mechanics (which is not defined by Visual Studio or Microsoft - it's pre-existing standard) is based on where the files are located in the folder structure. It has nothing to do with the mechanics of the Visual Studio projects.
See here on Microsoft's mention of this:
When you add an .editorconfig file to a folder in your file hierarchy, its settings apply to all applicable files at that level and below. You can also override EditorConfig settings for a particular project, codebase, or part of a codebase, such that it uses different conventions than other parts of the codebase. This can be useful when you incorporate code from somewhere else, and don’t want to change its conventions.
To override some or all of the EditorConfig settings, add an .editorconfig file at the level of the file hierarchy you want those overridden settings to apply. The new EditorConfig file settings apply to files at the same level and any subdirectories.
[ hierarchy image here ]
If you want to override some but not all of the settings, specify just those settings in the .editorconfig file. Only those properties that you explicitly list in the lower-level file are overridden. Other settings from higher-level .editorconfig files continue to apply. If you want to ensure that no settings from any higher-level .editorconfig files are applied to this part of the codebase, add the root=true property to the lower-level .editorconfig file:
# top-most EditorConfig file
root = true
EditorConfig files are read top to bottom. If there are multiple properties with the same name, the most recently found property with that name takes precedence.
Or here for the EditorConfig project.
Or here for the EditorConfig specification:
File Processing
When a filename is given to EditorConfig a search is performed in the directory of the given file and all parent directories for an EditorConfig file (named “.editorconfig” by default). Non-existing directories are treated as if they exist and are empty. All found EditorConfig files are searched for sections with section names matching the given filename. The search shall stop if an EditorConfig file is found with the root key set to true in the preamble or when reaching the root filesystem directory.
Files are read top to bottom and the most recent rules found take precedence. If multiple EditorConfig files have matching sections, the rules from the closer EditorConfig file are read last, so pairs in closer files take precedence.
I use Visual Studio version 16.11.2 and my experience is that the problem you describe appears, as a bug, when editing a project file in Visual Studio AFTER you have added a link to it to a it as a solution item. After such an action StyleCop does not any longer listen to the .editorconfig-file of the project.
To re-trigger StyleCop errors as build errors I then have to:
Remove the link to the .editorconfig for the project.
Add a copy of .editorconfig to the project.
Remove the copy of the .editorconfig to the project.
Re-add the link to the .editorconfig.
Quite akward yes, but the above DOES trigger the errors to appear as build errors again.
Moreover, in the version of Visual Studio above, I need to have the line below in the .csproj-file:
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
For previous versions of Visual Studio I had to have the lines below instead:
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors></WarningsAsErrors>
</PropertyGroup>

SSDT Project ille warning on Invalid Child Element IncludeCompositeObjects

I'm working on an SSDT project. The publish script looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IncludeCompositeObjects>True</IncludeCompositeObjects>
<TargetDatabaseName>VisionStaging</TargetDatabaseName>
<DeployScriptFileName>VisionStaging.sql</DeployScriptFileName>
<TargetConnectionString>xxxx</TargetConnectionString>
<BlockOnPossibleDataLoss>True</BlockOnPossibleDataLoss>
<CreateNewDatabase>True</CreateNewDatabase>
<ProfileVersionNumber>1</ProfileVersionNumber>
<IgnoreColumnOrder>True</IgnoreColumnOrder>
<IgnorePartitionSchemes>True</IgnorePartitionSchemes>
</PropertyGroup>
<ItemGroup>
<SqlCmdVariable Include="master">
<Value>master</Value>
</SqlCmdVariable>
</ItemGroup>
</Project>
When I open this file in Visual Studio, a few warnings appear:
The element 'PropertyGroup' in namespace
'http://schemas.microsoft.com/developer/msbuild/2003' has invalid
child element 'IncludeCompositeObjects' in namespace
'http://schemas.microsoft.com/developer/msbuild/2003'
The element 'ItemGroup' in namespace
'http://schemas.microsoft.com/developer/msbuild/2003' has invalid
child element 'SqlCmdVariable' in namespace
'http://schemas.microsoft.com/developer/msbuild/2003'.
The element 'Project' in namespace
'http://schemas.microsoft.com/developer/msbuild/2003' has incomplete
content.
I suppose the last one is caused by the first two. Any idea how to get rid of these warnings? Note that these files were built by the SSDT plugin which is 15.1.61902.21100 and VS does not show that any updates are available for it. In other words, the SSDT plugin put these elements in the file, not me.
PropertyGroup Contains a set of user-defined Property elements.
Validation of the schema in this case MSBuild schema in the Visual Studio IDE does not correctly handle custom properties, So if you have your publish.xml file open, you will always get a warning on the first custom item under PropertyGroup such as IncludeCompositeObjects
It shouldn't cause any problems, since you can define your own properties, They should only appear when you open the publish.xml file for editing in the IDE.
If you make your edits and close the file, they should go away.

How do I get a console project to group my appsettings.json files?

If I start a new web api project, the appsettings files are grouped together. However, I'm creating a working project from the console app template and when I create the appsettings files manually, the do not group together. I think back in older versions, there was something I'd put in the csproj file, but I don't know how to do it in .net core and I'm not seeing anything in properties or configurations
In the project file of your solution you can edit or add an <ItemGroup> element within the <Project> element. This worked for me:
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="appsettings.*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<DependentUpon>appsettings.json</DependentUpon>
</Content>
</ItemGroup>
Please Note that my console project targets .Net Core 2.0 and is running in Visual Studio Pro 2017 Version 15.7.5.
Also, if your Solution Explorer doesn't immediately refresh try unloading and reloading the project.
Using an <ItemGroup> with <Content> as suggested gave me an error (in Visual Studio 2019) about "Duplicate 'Content' items included". It turns out the .NET SDK includes 'Content' items from your project directory by default. Setting the EnableDefaultContentItems property to false seems a bit rigid, so now I include the items as <None>.
<ItemGroup>
<!-- Group AppSettings in Console project. Use None to prevent "Duplicate 'Content' items were included" when using (default) EnableDefaultContentItems=true -->
<None Include="appsettings.*.json">
<DependentUpon>appsettings.json</DependentUpon>
</None>
</ItemGroup>
This does show the files grouped, but shows their properties with Build Action 'None' and 'Do Not Copy' in the Solution-explorer, so I guess that's the price for wanting them to group?
FWIW: a file-nesting rule as suggested in appsettings-json-not-in-hierarchy
will not show the files as grouped/nested, but it will make it collapse if the solution-explorer collapse-button is pressed.
You just need to click the File Nesting icon, and choose "Web"

Automatic copy files to output during application building

There is Copy to Output Directory property for files in C# projects. But in VC++ projects it is absent. I know, that I can use Build events in VC++ and write there something like
xcopy /y /d %(FullPath) $(OutDir)
Is there a way to avoid the use of CMD (and other scripting methods)? Can msbuild do something to help in this case?
Can MSBuild do something to help in this case?
Using MSVC 2012, this worked for me:
Assumed you have a file "Data/ThisIsData.txt" in your c++ Project.
Unload the project (right click --> Unload Project).
Edit project XML (right click --> Edit .vcxproj)
Now you see the projects MSBuild file as XML in your editor.
Find "ThisIsData.txt". It should look something like:
<ItemGroup>
<None Include="Data\ThisIsData.txt" />
...
</ItemGroup>
Now add an other item group like this:
<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
...
</ItemGroup>
Reload the project and build.
Your file "ThisIsData.txt" should get copied to $(OutDir)\Data\ThisIsData.txt.
Why duplicating the ItemGroup?
Well if you simply change the None include to a content include, the IDE does not seem to like it any more, and will not display it. So to keep a quick edit option for my data files, I decided to keep the duplicated entries.
In VS 2015 it is possible to give C projects the functionality that is in C#.
(Idea from building off of jochen's answer.)
Instead of adding another ItemGroup, modify the given itemgroup adding a CopyTo element. I.E, using his example, simply enhance the original entry to:
<ItemGroup>
<None Include="Data\ThisIsData.txt" />
<DeploymentContent>true</DeploymentContent>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
...
</ItemGroup>
No other ItemGroup required. By adding the CopyTo element, you add an "Included In Project" property.
In Visual Studio 2017 you can do this in the IDE. I am not sure about earlier versions.
Simply add the file as an included project file so it shows in the Solution Explorer. Then right click on the file and select the Properties menu.
Change the Content to "Yes" and change the Item Type to "Copy file"
If you look at the changes it made to the project file you can see it added this:
<ItemGroup>
<CopyFileToFolders Include="Filename.txt">
<DeploymentContent>true</DeploymentContent>
<FileType>Document</FileType>
</CopyFileToFolders>
</ItemGroup>
It depends on what version of Visual Studio you are using. Format of VC++ project file in Visual Studio 2008 is not MSBuild and so using xcopy in PostBuildStep is a good choice.
VC++ project in Visual Studio 2010 has MSBuild format. Thus, there is functionality of MSBuild Copy task.
Below is a sample:
<Copy
SourceFiles="%(FullPath)"
DestinationFolder="$(OutDir)"
/>
If the destination directory does not exist, it is created automatically
An MSDN Copy task reference is here
Following henri-socha's answer about VS2015 (and probably VS2013 and VS2012, or anything using MSBuild style projects), the ItemGroup item type is important.
Specifically <Text> items do not seem to be copied, whereas <Content> items do.
So, for a project directory Data containing a text file ThisIsData.txt, this will create a subdirectory Data under the $(OutDir) directory and copy the file ThisIsData.txt from the project into it if it's newer:
<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
This won't, although it is what the Visual Studio IDE will insert if you add the text file to your project, and set the Content property to True.
<ItemGroup>
<Text Include="Data\ThisIsData.txt">
<DeploymentContent>true</DeploymentContent>
</Text>
</ItemGroup>
So in other words you need to add the file via the IDE to make it realise the file is included in the project (which adds <Text> tag ItemGroup), and then open the project in a text editor and add the <Content> tag ItemGroup to get it to do what you want.
I'm not sure what the <DeploymentContent> tag actually does. It may be a remnant since the only MSDN reference I could find considers it archived: https://msdn.microsoft.com/en-us/library/aa712517.aspx
In visual studio 2019 after setting the file as "Include in project" you can edit the properties an select as Item Type "Copy file" (as shown in https://i.stack.imgur.com/vac2b.png)
This avoids the manual vcxproj file edition.
You can specify copying in the project file as Jeff G answered in another question:
In the *.vcxproj file, change:
<Text Include="Filename.txt" />
to:
<Content Include="Filename.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Then in the *.vcxproj.filters file, change:
<Text Include="Filename.txt">
<Filter>Resource Files</Filter>
</Text>
to:
<Content Include="Filename.txt">
<Filter>Resource Files</Filter>
</Content>
where the <Text ...> tag is for specified text files (it'll be <Image ...> for image files etc.)
If it's a COM dll, you can add it to the root of your project, mark it as 'Content' and set copy to output directory to 'Always'. I had to do this for signature capture COM assembly.