msbuild task that works from publish profile to remove specific file - visual-studio

Have 3 json files in my project. For a specific publish profile, using a FileSystem publish and I'm trying to find a way to have a specific file NOT be published to the target folder. This is for a .net core console app.
This is my publish profile, but the file Im trying to restrict from being published is still published to the target folder.
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Debug</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp3.0</TargetFramework>
<PublishDir>D:\projects\test_publish</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<DeleteExistingFiles>false</DeleteExistingFiles>
<ExcludeFilesFromDeployment>appsettings.Test.json</ExcludeFilesFromDeployment>
</PropertyGroup>
</Project>
Note: project file includes these files so they will be in the build output. Might this prevent the appsettings.Test.json from being deleted and hence still get copied over to the publish dir?
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="appsettings.Local.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="appsettings.Test.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

The work-around solution I have come up with is similar to another project I have. It involves taping into the build system and add some extra bits into the csproj file.
So the csproj file would now look like this. It eliminates the file you dont need, and you only need to add a corresponding build config entry and this uses the VS build system to determine which of these json file(s) get output.
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="appsettings.Local.json" Condition=" '$(Configuration)' == 'Debug' " >
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="appsettings.Test.json" Condition=" '$(Configuration)' == 'Test' " >
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

This is my publish profile, but the file Im trying to restrict from
being published is still published to the target folder.
I test it in my local machine and reproduce same issue. Also I find if I use this element in web application like asp.net, it always works. So I assume this element is not supported for publishing .net core console application.
What role does that file play in your project?
1.If your application don't need it in build output directory and publish directory, you can set the Copy to Output Directory to Do not copy.
And then clean your publish folder and publish again to check if it helps.
2.And if you have specific reason that you need the file in build, but need to exclude it from publish folder, trying adding this script into your xx.csproj(Delete Task):
<Target Name="CustomTarget" AfterTargets="_PublishNoBuildAlternative">
<Delete Files="$(PublishDir)\appsettings.Test.json"/>
<!--<Delete Files="$(PublishDir)\appsettings.xxx.json"/>-->
</Target>
You can add MSbuild Conditions like Condition="$(Configuration)=='xxx'" to the targets to make it more flexible.

Related

Change LibSassBuilder output directory

I'm using LibSassBuilder in a Blazor project. I have read the docs and it's unclear to me if the package's config allows you to specify an output directory. I'd prefer to keep my .scss files outside of wwwroot and just place the compiled .css files there-- but I don't see if there's a way to do this. If not, is there a way to specify a file move to wwwroot in the Visual Studio build pipeline?
I'm also developing a Blazor project using LibSassBuilder. This is how I got it to work in my .csproj file:
<PropertyGroup>
<LibSassOutputStyle>compressed</LibSassOutputStyle>
<LibSassOutputStyle Condition="'$(Configuration)' == 'Debug'">expanded</LibSassOutputStyle>
</PropertyGroup>
<ItemGroup>
<CSSFiles Include="**/*.css" />
</ItemGroup>
<Target Name="MoveCSS" AfterTargets="Build">
<Move SourceFiles="#(CSSFiles)" DestinationFolder="wwwroot/css" />
</Target>

.net core wwwroot data folder - Do Not Copy being ignored

So I have a simple .net core application that I am deploying to Azure from VS2019. I have some json files in the wwwroot\data folder and I have set them to content=none and copy="Do Not Copy".
However when I publish the still publish every time.
I have also edited the .csproj file and ensure this is there
<ItemGroup>
<None Include="wwwroot\data\file.json" CopyToPublishDirectory="Never"/>
</ItemGroup>
and yet it still publishes.
Any ideas
You can try following code:
<ItemGroup>
<Content Update="wwwroot\data\file.json">
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>

Is it possible to add path to .dll in Visual Studio 2010 property sheet?

I have a Visual Studio 2010 and a project that uses third-party library. This third-party librarys consists of header files, library files and .dll files. So, in order for my project to include header files and link with library files i created and added following property sheet to it:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>
C:\sdk\superlib\include;
%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>
C:\sdk\superlib\lib;
%(AdditionalLibraryDirectories)
</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
</Project>
My project succesfully compiles and links with library. But it is a problem: in order for my executable to run it needs a library .dll that is inside sdk bin folder. So if i hit F5 in Visual Studio it will complain that superlib.dll not found :(. Of course i can manually copy it to output folder of my project - but is it possible to somehow set path to .dll in .vsprops file so it is automatically used upon run and debug?
You can specify this by adding the .dll file to the #(None) item array, and setting a metadata value so that it is automatically copied to the output. Add the following to your props file.
<ItemGroup>
<None Include="C:\sdk\superlib\bin\superlib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
If you don't want this to show up in the solution explorer, add the Visible=false metadata as well,
<ItemGroup>
<None Include="C:\sdk\superlib\bin\superlib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Visible>false</Visible>
</None>
</ItemGroup>

Copy DLL files to bin directory after one-click publishing in VS2010

I have a web application in VS2010 which has a number of DLLs that need to be copied into the bin directory after doing a publish in VS2010.
I've tried putting the following into my .csproj file (which sits in the root folder of the web applications) but it doesn't seem to work:
<Target Name="AfterBuild">
<ItemGroup>
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<Copy
SourceFiles="#(_CircularDependencies)"
DestinationFiles="#(_CircularDependencies->'bin\%(Filename)%(Extension)')"
SkipUnchangedFiles="true" />
</Target>
For bonus points, I have another set of DLLs copied to be copied post-publish, but I want to use one set when doing a debug publish (for Win32) and a different set when doing a release publish (x86).
Thanks!
OK, I've managed to get this working fully. Thanks to the answers provided above, I've been able to add some MS Build commands to the .csproj file to copy the appropriate DLLs from various folders into the bin folder based on the current build configuration. However as these are unmanaged DLLs (i.e. not .NET) I can't create normal references to them and they fail to be copied during the publish. I got around this by dynamically adding the files to the project as 'content'.
The solution came in three parts. Firstly, create an item group for the files near the top of the .csproj file (I've tried to use generic filenames here to make it clearer), with conditions based on the current build configuration:
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_UnmanagedDLLs Include="Win32DLLs\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_UnmanagedDLLs Include="x64DLLs\*.dll" />
</ItemGroup>
Then add another item group to include these DLLs (as content, not references) in the build:
<ItemGroup>
<Content Include="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" />
</ItemGroup>
Finally, at the bottom of the .csproj file, I do the copy on the AfterBuild target:
<Target Name="AfterBuild">
<Copy SourceFiles="#(_UnmanagedDLLs)" DestinationFiles="#(_UnmanagedDLLs->'bin\%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
It means I can do a debug publish for my windows 32 staging box and a release publish for my x64 production box while keeping my bin folder out of SVN.
Once you get the copy working, separate sets for debug/release is easy with a condition:
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<_CircularDependencies Include="DLLs\Circular\Dependencies\*.dll" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.dll" />
<_CircularDependencies Include="DebugDLLs\Circular\Dependencies\*.pdb" />
</ItemGroup>
If you want your copy to happen after publish, not after build you need to change your target from:
<Target Name="AfterBuild">
to
<Target Name="AfterPublish">

Is there such a thing as a "content/data only project" in visual studio

I have a bunch of ancillary XML and XSLT files that I want to edit and manage in visual studio.
The files do not logically belong under any code project in my solution and so in order to group them neatly, I have created a "dummy" C# dll project in visual studio and disabled it from building in Debug / release builds).
I wondered if there was a nicer way of achieving the same result (i.e. having all the files visible in solution explorer). What I think really want is a visual studio project type of "content only" but such a thing does not exist (or have I not looked hard enough?).
I have toyed with the idea of adding the files as solution items but then they seem harder to manage because creating a new "solution item folder" does not actually create a folder on disk.
Any one have any ideas?
Visual Studio 2015 has a project type called "Shared Project" which is essentially a content only project with no targets. It's listed under Visual C# but it can be used for any files.
A work colleague has come up with a solution.
He has suggested hand editing the project to remove the DefaultTargets from the Project (and delete a load of now unused properties).
MSBuild complains if there are no targets in the project so he has added three empty targets.
The final project looks something like this
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{541463A7-7CFA-4F62-B839-6367178B16BD}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
... files ...
</ItemGroup>
<ItemGroup>
... files ...
</ItemGroup>
<Target Name="Build"/>
<Target Name="Rebuild"/>
<Target Name="Clean"/>
</Project>
Admittedly, this solution requires more fiddling that I would have liked but seems to achieve what I was after: namely a project that does not aattempt to produce any build output.
Andy posted a link with a solution that's mostly worked for me; basically delete the following line from the project file:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and add the following lines:
<Target Name="Build">
<Copy
SourceFiles="#(Content)"
DestinationFiles="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutputPath)" Condition="Exists($(OutputPath))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
I also found that disabling the project Debug property "Enable the Visual Studio hosting process" (for each configuration) prevented the MyProject.vshost.exe file from being generated.
As David I. McIntosh pointed out in a comment on this answer, if your project is part of a solution with multiple projects and any other projects use the same output path as the content-only project, the above Clean target will delete all of the files in the output path, i.e. the build output of other projects, and would thus only be correct if the content-only project is the first project built (among those sharing the same build output path). The following is a safer and friendlier Clean target for this scenario:
<Target Name="Clean">
<Delete Files="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(E‌​xtension)')"/>
</Target>
Then, try creating a Blank solution. Create Empty project. Have your files in respective folders with in the solution folder. From property window, use the Show all files, include those folders into the project. There is no better solution other then this. I hope.
This answer is just a convenient consolidation of the answers above given by Chris Fewtrell and Kenny Evitt, along with the slight modification in my comments above, and a bit more detail on what the declaration of the content items should/could look like:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{541463A7-7CFA-4F62-B839-6367178B16BD}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == '64-bit|AnyCPU'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\builds\$(Configuration)\</OutputPath>
<IntermediateOutputPath>..\builds\$(Configuration)\Intermediate\YourProjectName\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="fileInProjectFolder.csv" />
<Content Include="SubDir\fileInSubdir.txt" />
<Content Include="..\actualSourceDirectoryOfFile\app.log.basic.config">
<Link>targetSubdirInOutputDir\app.log.basic.config</Link>
</Content>
<Content Include="..\actualSourceDirectoryOfFile\yetAnotherFile.config">
<Link>yetAnotherFile.config</Link>
</Content>
... more files ...
</ItemGroup>
<Target Name="Build">
<Copy
SourceFiles="#(Content)"
DestinationFiles="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Delete Files="#(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(E‌​xtension)')"/>
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
</Project>
Note that this always copies all the "content" files to the output directory - the options "Copy If Newer", "Copy Always" and "Do Not Copy", as presented in the visual studio GUI ( appears as, for example, <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> in the .csproj file) are ignored.
In my situation, I needed to have a set of configuration files that would be common to many projects. To simply achieve this, I performed the following steps:
Create a Class Library project named "Configuration"
Delete all *.cs files from Configuration project
Put configuration files in a "Configuration" folder in the Configuration project
Copy configuration files to required projects in the post-build event. In Configuration project's Properties > Build Events > Post-build event:
xcopy "$(TargetDir)Configuration\*" "$(SolutionDir)TARGET_PROJECT\$(OutDir)" /i /v /q /s /y
In the above, replace TARGET_PROJECT with your actual project
This will copy all the files in the Configurations folder to the output directory of the project that needs the configuration files (eg. MyProject/bin/Debug, etc).

Resources