Visual Studio / msbuild CopyToOutputDirectory - how does it work? - visual-studio

I am using Visual Studio Community:
Microsoft Visual Studio Community 2019
Version 16.4.5
VisualStudio.16.Release/16.4.5+29806.167
Microsoft .NET Framework
Version 4.8.03752
I have a very simple ASP.Net Core website / app project, with the following directory structure:
website
/bin
/www
/about
/images
NOTE: The webroot directory is NOT wwwroot, but instead just www
The project file (.csproj) contains the following (to copy all sub-directories/files to the output directory):
<ItemGroup>
<Content Update="www\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
Using Visual Studio (Config = Debug)
BUILD -> Rebuild Solution
Result:
/bin
/Debug
/netcoreapp3.0
/Properties
/runtimes
(missing /www and all sub-directories and files!) - WHY???
The same results are obtained if I use msbuild.exe from the developer command prompt; makes no difference with regard to configuration (Debug vs Release).
I assumed that the www directory (and all sub-directories) and files would be copied to the output directory -- but clearly, this is not happening. I do not understand why the CopyToOutputDirectory is being ignored; I am missing something, but a search of the documentation did not yield any answers.
Any ideas / advice would be appreciated.
Thanks in advance.

Update:
Just changed the following in the project (.csproj) file:
<ItemGroup>
<Content Update="www\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
To:
<ItemGroup>
<None Update="www\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
Using Visual Studio: BUILD -> Rebuild Solution (success)
Also tried with msbuild.exe (success)
Now the www directory and all sub-directories / files are present in the output -- why? I suspect because I am not using the default "wwwroot" as the content directory, using <Content> does not work whereas <None> does; but that is only a theory; all I know is it works.
Also found this SO link useful in describing the differences between <Content> and <None>, for those who are curious:
What are the various "Build action" settings in Visual Studio project properties and what do they do?

Related

Include file in NuGet package to be copied on installed project folder (no output folder) using Visual Studio

Can a file be packed inside a NuGet package, using Visual Studio, in way that it will be copied inside the target project folder?
I added this code in NuGet .csproj
<ItemGroup>
<Content Include="MyFolder/**/*.*" copyToOutput="true">
<Pack>true</Pack>
<PackagePath>contentFiles/any/any/MyFolder;content/any/any/MyFolder</PackagePath>
<IncludeInPackage>true</IncludeInPackage>
<CopyToOutput>true</CopyToOutput>
<BuildAction>Content</BuildAction>
<copyToOutput>true</copyToOutput>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
</ItemGroup>
and when I install the package the content of the MyFolder appears as linked and it will be copied only into the output directory. Instead of a link, is there a way to have the copy of the files?
Thanks.

VS 2019 Solution Explorer references files from old Nuget packages

I'm using Visual Studio 2019 for a .NET Core 3.1 MVC application. I have installed several Nuget packages that I also created. Some of the packages contain their own settings files which need to be copied to the output directory in order for the application to work properly. These settings files are put into their own folder and everything is mostly fine. Sample .csproj file of one of these packages:
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>[redacted</Authors>
<Company>[redacted</Company>
<Description>[redacted]</Description>
<Version>1.0.2.2-alpha</Version>
</PropertyGroup>
<ItemGroup>
<None Remove="settings\mySettings.Development.json" />
<None Remove="settings\mySettings.Production.json" />
<None Remove="settings\mySettings.Staging.json" />
</ItemGroup>
<ItemGroup>
<Content Include="settings\mySettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Pack>true</Pack>
</Content>
<Content Include="settings\mySettings.Production.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Pack>true</Pack>
</Content>
<Content Include="settings\mySettings.Staging.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Pack>true</Pack>
</Content>
</ItemGroup>
What's strange is when I update one of these packages, sometimes Visual Studio doesn't link to the settings file in the updated package. So for example, this is my .csproj file for the web application.
<Content Update="..\..\..\..\..\.nuget\packages\mypackage\1.0.2.2-alpha\contentFiles\any\netstandard2.0\settings\mySettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="..\..\..\..\..\.nuget\packages\mypackage\1.0.2.2-alpha\contentFiles\any\netstandard2.0\settings\mySettings.Production.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="..\..\..\..\..\.nuget\packages\mypackage\1.0.2.2-alpha\contentFiles\any\netstandard2.0\settings\mySettings.Staging.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
This part looks fine, even if I had to manually change the paths from absolute to relative.
But in the Solution Explorer, when I view the properties for these files, it shows the build action as None and the path is to an older package version. If I then change the build action to Copy always, VS will add instructions for copying the older file to the .csproj.
This is potentially a problem in that if another developer takes over this project, they may not notice the version differences and if they change the build action, they could overwrite the correct settings file with the older one.
I don't see any reference to the older version in the .csproj file, so where is that coming from? Note that the older version of the package is not installed anywhere the solution, either. Does anyone know what the deal is?
Thanks.
You have to clean the nuget cache first or just delete all files under C:\Users\Administrator\.nuget\packages.
Not sure that if your old package version is the same as the new one. In other words, you still make a same package version and did not assign a new one for it which makes VS always install that old one from the nuget cache. So you have to clean the nuget cache folder to remove all the old packages.
So my suggestion is that when you install the new release version of the nuget package, you have to clean nuget caches first, also delete bin and obj folder.
Besides, if you want to make the conent files of the nuget package be copied into the main project's output folder. Please use
<PackageCopyToOutput>true</PackageCopyToOutput>
Check this similar issue.

Visual Studio 2019 not picking up CS generated files

I have created dot net core dll project. CS files for this project will be files generated by tool (Apache Thrift compiler) but output dll is not picking up generated file. I have added the pre build set to generate the file.
Repro Steps:
Build solution
Open the ThriftSample.dll with object brower. (Delete the generated cs files and bin, com and obj folder.)
Actual: Nothing is there in ThriftSample.dll
Expected: Generated CS code should be there.
Note: I have checked CS file is generated. Attached is the sample project.(
https://onedrive.live.com/?cid=aef000afffca3540&id=AEF000AFFFCA3540%21144&authkey=!AAlMaW2IqIt6l1k
)
Refer: Is there a .NET Core CLI pre before build task?
The "default items" as the .NET SDK calls it are part of the static evaluation of the project file - before any target is run. So you'll need a target that is run before the #(Compile) items are needed.
The trick is to include files added to the filesystem after the custom tool is run. This can be done by re-scanning all files and excluding those already part of the project inside a target that is run before the build:
<Target Name="GenerateSomeFiles" BeforeTargets="BeforeBuild">
<Exec Command="dotnet my-tool" />
<ItemGroup>
<Compile Include="**/*$(DefaultLanguageSourceExtension)"
Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(BaseIntermediateOutputPath)**;$(BaseOutputPath)**;#(Compile)" />
</ItemGroup>
</Target>

Link Additional Files in Visual Studio

I am trying to include stylecop.json in my C# project on Visual Studio 2017. I have figured out how to do this by modifying the .csproj in any text editor:
<AdditionalFiles Include="stylecop.json">
<Link>stylecop.json</Link>
</AdditionalFiles>
I am wondering if there is a way to do this without making any text edits. I understand I can always add it like any other files but that would make a copy of the file within project folder and not link it externally.
You can add a Directory.Build.targets file somewhere in your solution directory (will apply to all projects at or below that directory) with the following contents:
<Project>
<ItemGroup>
<AdditionalFiles Update="#(AdditionalFiles)">
<Link Condition="'%(Link)' == ''">%(Identity)</Link>
</AdditionalFiles>
</ItemGroup>
</Project>
Note that using %(Identity) here isn't optimal for items outside the "project cone" - e.g. when you have <AdditionalFiles Include="..\..\foo.bar" />. For this you can use a mechanism similar to what SDK-based projects will do in VS 2017 15.3 / .net core 2.0 tooling:
<Project>
<ItemGroup>
<AdditionalFiles Update="#(AdditionalFiles)">
<LinkBase Condition="'%(LinkBase)' != ''">$([MSBuild]::EnsureTrailingSlash(%(LinkBase)))</LinkBase>
<Link Condition="'%(Link)' == '' And !$([MSBuild]::ValueOrDefault('%(FullPath)', '').StartsWith($([MSBuild]::EnsureTrailingSlash($(MSBuildProjectDirectory)))))">%(LinkBase)%(RecursiveDir)%(Filename)%(Extension)</Link>
</AdditionalFiles>
</ItemGroup>
</Project>
This will even preserve directory hierarchies of items matched with e.g. ..\shared\**\*.json and the target folder could be set using the LinkBase metadata:
<AdditionalFiles Include="..\shared\**\*">
<LinkBase>SharedFiles</LinkBase>
</AdditionalFiles>
Note that you may need to close and re-open the solution after making changes to Directory.Build.targets. In the upcoming VS 2017 15.3 update, changes will be monitored by VS automatically. In previous versions, the file will be cached by VS until the solution is closed.

Visual Studio 2012 and Web Essentials 2012 crashes on builds

I've installed Web Essentials 2.5.1 and typescript 0.8.3; however, now Visual Studio 2012 Ultimate immediately crashes upon builds. The crashes stop if I uninstall Web Essentials. Does anyone have any suggestions to remedy the crashes? Thanks.
It could be the error we just encountered when pulling in Wordpress/PHP project. If BOTH the .css and .less files are Include in project, the build will crash. If this happens
Right-click the .css file and Exclude from project
Delete the .css file from Explorer
Save the project
Double click the .less file to open in an editor
Change something and save the .less file.
Save the project
At this point the .css file and .min.css files will be generated and added to the project as dependent files like they would have been in a normal project.
If you're looking at the project's .csproj file, it goes from looking like this:
<ItemGroup>
<Content Include="test.less" />
<Content Include="test.css" />
</ItemGroup>
to this:
<ItemGroup>
<Content Include="test.less" />
<Content Include="test.css">
<DependentUpon>test.less</DependentUpon>
</Content>
<Content Include="test.min.css">
<DependentUpon>test.less</DependentUpon>
</Content>
</ItemGroup>

Resources