Visual Studio and Imported MSBuild properties in vcxproj files - visual-studio

I was trying to factor out some properties in some C++ projects in a Visual Studio 2013 Update 4 solution into separate property files which I then Import into the vcxproj files. After doing so I noticed that the properties no longer seem to be reflected in the properties editor GUI. For instance if I Import this from some file
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
rather than have it defined directly in the vcxproj file the "Character Set" item in the properties GUI appears as blank. However the C++ Command Line in the properties GUI does contain '/D "_UNICODE" /D "UNICODE"' so it would appear that the property is being noticed and taking effect.
So is this just a GUI thing or will doing something like this cause stuff to not to build correctly? My guess is that Visual Studio looks for elements like '' but only does so directly in the vcxproj file but not in anything it Imports.

Visual Studio 2010, 2012, 2013, 2015, 2017 and 2019 creates list of visualized and editable options only from items in project file itself.
Items from included files are used only as default values for configuration options. Values from included files are processed and used, even if they are not visualized in GUI.
To see something in GUI, you have to add at least empty corresponding item in .vcxproj file.
For example, to see main configuration, you need to add empty "PropertyGroup"
with label "Configuration" (for each project configuration) to .vcxproj file:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
</PropertyGroup>
To see name, location of output files and other general properties, add empty "PropertyGroup" without label:
<PropertyGroup />
To see C/C++ compiler, linker and lib settings, add "ItemDefinitionGroup" with "ClCompile", "Link" and "Lib" items to .vcxproj file:
<ItemDefinitionGroup>
<ClCompile />
<Link />
<Lib />
</ItemDefinitionGroup>
If you add everything, mentioned here, to your .vcxproj file, you will see all C/C++ settings in GUI and you will be able to change them.

If you are using 'propertysheets' properly you can see them in the Property Manager window in VS, nicely and hierarchically ordered, including the options contained in them. Which is really very convenient.
I guess you now manually modified the vcxproj and added an Import. While that works as well (as you can see is reflected in the commandline), it doesn't play together well with VS. So, don't do that but revert your change and head over to the property manager and add some property files there. VS will create the Import statements for you in the correct place, and should display all properties as usual.

Related

T4 templates not generating output in new VS2017 csproj projects

I migrated a project.json/.xproj project to the newer CS2017 .csproj format.
The project contains a T4 (.tt) template file.
It doesn't regenerate its output on save or build. The output .cs file isn't nested below the .tt file either.
Is there something I have to do to get this working?
.tt files are only auto-run by VS on save. You can install AutoT4 to have them run before/after build. (Be aware that at the moment there is a limitation with the new .csproj files - the options don't show up for them in the properties window.)
If you've converted from the old project.json/.xproj format, you may need to add the template to the project explicitly:
<ItemGroup>
<None Update="Foo.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Foo.cs</LastGenOutput>
</None>
<Compile Update="Foo.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Foo.tt</DependentUpon>
</Compile>
</ItemGroup>
Related GitHub issue
Edit
As mentioned in the comments below, you can do this quickly & easily by excluding, then including the template in your project.
I realise this is 2+ years old but for those bumping into this issue years on like me, the method listed below works for me without installing anything. I had the exact same issue, after upgrading a project from Visual Studio 2010 to Visual Studio 2017. YMMV. Make a backup copy of your .csproj file before you start.
Forcing rebuild of all .tt files when you build your project can be achieved without installing anything, by editing the .csproj project file. Editing the .csproj file seems clunky, but is is the approved way https://learn.microsoft.com/en-gb/visualstudio/modeling/code-generation-in-a-build-process?view=vs-2015
Within your .csproj file, you will find lots of PropertyGroup nodes. At the end of the list of PropertyGroup nodes (position not critical), add another PropertyGroup node with this content:
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
Now look near the end of the .proj file, and you will see a line like this:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
(For interest, on my computer with VS2017 on it that resolves to C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.CSharp.targets)
Beneath that line, add a line like this:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\TextTemplating\Microsoft.TextTemplating.targets" />
(For interest, on my computer that resolves to C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\VisualStudio\v15.0\TextTemplating\Microsoft.TextTemplating.targets)
YMMV. If yours is a web project, there is probably a line nearby that is similar but to do with Microsoft.WebApplication.targets, from which you can draw inspiration.
That, possibly with a restart of Visual Studio, should do it. If you delete the transformed file that your .tt file emits, and then do a rebuild of your project, you should see that the emitted file reappears.

Visual Studio 2013 and MSBuild command line switches

Is there a way to specify msbuild switches like /p:option=value within Visual Studio 2013?
Formalizing my comment from above.
A possible solution may be to have a targets file (e.g. VisualStudioOverrides.targets) that defines the properties to be overridden and their values. Then, if this file exists then the csproj file will import it, thus override the relevant properties.
Such an import statement should be placed at the bottom of the csproj file (after the properties to be overridden were defined) and would look something like:
<Import Project="$(MSBuildProjectDirectory)\VisualStudioOverrides.targets" Condition="Exists('$(MSBuildProjectDirectory)\VisualStudioOverrides.targets')" />

Override One Property in a .targets file

Background: I have several solutions with roughly 300 C++ projects across them, most of them shared. We are using Visual Studio 2013 and have a build script that compiles all of the projects in the correct order, ensuring dependencies are resolved ahead of time. Our development/engineering team builds all of the code through the build script and then attempts to debug using Visual Studio 2013.
Issue: The "build then debug" process results in Visual Studio telling us that the Projects are out of date. This stems from the ProjectEvaluationFingerprint property (in Line 39 Microsoft.CppBuild.targets) including a $(SolutionDir) in the output file. The recommended fix from Microsoft suggests removing the $(SolutionDir) from the file. As our developers tends to transition back and forth between projects, I do not want to manually change this .targets file on every developer's machine (and remember to change it back when they leave the project). I would like to override the property in the .vcxproj by using a .targets file explicitly for this.
The property in Microsoft.CppBuild.targets looks like:
<!-- Global up-to-date check support -->
<PropertyGroup>
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|$(SolutionDir)|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
</PropertyGroup>
Generally, I have been following Microsoft's How to: Use the Same Target in Multiple Project Files. I have created a .targets file (test.targets) that contains the following code (note the TEST text was to test evaluation of the property in both the build script and building the project in Visual Studio):
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
</PropertyGroup>
I then import it using the following line in the .vcxproj
<Import Project="..\..\Config\VSPropertySheets\test.targets" />
The project.lastbuildstate file now reads:
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120_xp:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Debug|Win32|D:\views\devbranch\Products\SLN\|Debug|Win32|TEST|
It is appending the new ProjectEvaluationFingerprint to the existing one, so it is not overriding (I can understand this to a degree, but I'm no MSBuild expert).
Question: How can I override this one property using a .targets file? Do I need to use a replaceregexp task or do I have an easier option?
You can override this property, but you have to be careful about two things:
the new setting you want is this:
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST/ProjectEvaluationFingerprint>
Note the removal of $(ProjectEvaluationFingerprint), which would contain the previous value of this tag
the location where you put the import is important: you will want to put it at the very end of your project (i.e. after the Microsoft.CppBuild.targets import).
Concretely:
use_custom_fingerprint.targets
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)</ProjectEvaluationFingerprint>
</PropertyGroup>
</Project>
project.vcxproj
<Project ...>
...
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Import Project="use_custom_fingerprint.targets" />
</Project>
Note that I also tried the extension .props and this worked just the same.
Note: The new import after importing Microsoft.CppBuild.targets.$(Platform).user.props is not sufficient, it must be after Microsoft.CppBuild.targets.
Disclaimer: tried in Visual Studio 2015
I have the same problem. I was able to progress a step further than you, but I still haven't a full solution.
The reason why you have now the old fingerprint appended to the new one without solution dir is your line
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
The
$(ProjectEvaluationFingerprint)
Holds the old fingerprint, so just remove this part from the value for ProjectEvaluationFingerprint and your lastbuildstate will have the desired value.
Sadly now (at least for me) Visual Studio always thinks the fingerprint is wrong and will re-link the project with every compile, not only when switching sln file.
I removed the line from the props sheet and the up-to-date check works again as expected as long as solution directory doesn't change. I then modified the Microsoft.CppBuild.targets directly and this works: No more "not up-to-date" projects, even when switching solution directory.

MSBuild Inheriting Platform Toolset

I am attempting to overhaul my project's build processes. We have ~330 Visual C++ projects that we have upgraded in the last year from Visual Studio 2005 to Visual Studio 2013. I would like to take advantage of MSBuild to improve our build time over our very serial build scripts that we have now. I have completed a rough first pass and dropped the build times for a Release build from ~2 hours to ~20 minutes. In the process of doing this, I am consolidating a lot of common project settings into a .props file . In doing so, I have hit a stumbling block.
I wish to inherit the Platform Toolset from one VSProps file to all of the projects that include it. At the top of the new .props file I created, I put the following:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="Configuration">
<PlatformToolSet>v120</PlatformToolSet>
</PropertyGroup>
<PropertyGroup Label="UserMacros" />
I then removed the corresponding <PlatformToolSet>v120</PlatformToolset> from the individual project files.
Alas, things have started to go downhill. The projects (in Visual Studio 2013) now say in the Solution Explorer something like CoreGeometry (Visual Studio 2010) and the projects themselves seem to want to reference the v100 platform toolset. When I build, it then complains at me:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(362,5): warning MSB8003: Could not find WindowsSDKDir variable from the registry. TargetFrameworkVersion or PlatformToolset may be set to an invalid version number.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(341,5): error MSB6006: "CL.exe" exited with code -1073741515.
The only way I have been able to work around this is to manually set the PlatformToolset on the .vcxproj themselves, which is not terrible, I just am a bit annoyed that every other property seems to inherit, but the PlatformToolset does not.
My question is thus:
Can I use a .props file to inherit a common PlatformToolSet into a .vcxproj that does not specify a platform toolset?
A second question: Should I even be messing with the Platform ToolSet in this manner or am I setting myself up at risk for a maintenance nightmare later?
It is very good practice to extract common settings to a separate .props file and <Import> that from all projects. I am doing the same with my projects, including configuring PlatformToolset property in .props file, and I have no problems building it this way.
Few points related to this:
There is nothing special about PlatformToolset property, or any other property for that matter. Configuring properties inside .props file is identical to setting it inside .vcxproj file directly (however see my point below about ordering). Of course, there are some built-in properties, which you cannot configure at all, but those are always read-only properties.
The only case where you would not be able to override a property, if it the property value is passed directly from command line for the build (e.g. msbuild mysolution.sln /p:Platform=x86 will have everything built with Platform property set to x86 and overrides in projects won't take effect).
There is a difference between msbuild engine interpreting your projects and Visual Studio showing settings for the project. In some cases you might find that after refactoring .vcxproj files some standard project configuration dialogs not showing information you configured in .props file. To alleviate this, make sure that your <Import> command for .props file is always able to locate the .props file, by setting absolute path to .props file. Second, ensure you specify Label attribute for the <PropertyGroup> element in your configuration file like it was specified in your .vcxproj file.
Finally, make sure your <Import> element is in the right place. Usually you want it to be the very first Import, before you import standard .targets and .props, like Microsoft.Cpp.defaults.props, etc. The reason is msbuild works by performing sequential scans through the statements, so order of instructions matter.
To make #3 and #4 easier, here is a trick to specify absolute path to the .props file. Assume that your solution name is MySolution.sln and custom props file is MyCustomProps.props, placed in the same directory where solution is:
<PropertyGroup>
<RootFolder>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),MySolution.sln))</RootFolder>
</PropertyGroup>
<Import Project="$(RootFolder)\MyCustomProps.props" />

Exclude files from web site publish in Visual Studio

Can I exclude a folder or files when I publish a web site in Visual Studio 2005? I have various resources that I want to keep at hand in the Solution Explorer, such as alternate config files for various environments, but I don't really want to publish them to the server. Is there some way to exclude them? When using other project types, such as a .dll assembly, I can set a file's Build Action property to "None" and its Copy to Output Directory property to "Do not copy". I cannot find any similar settings for files in a web site.
If the IDE does not offer this feature, does anyone have good technique for handling such files?
Exclude files and folders by adding ExcludeFilesFromDeployment and ExcludeFoldersFromDeployment elements to your project file (.csproj, .vbproj, etc). You will need to edit the file in a text editor, or in Visual Studio by unloading the project and then editing it.
Add the tags anywhere within the appropriate PropertyGroup (Debug, Release, etc) as shown below:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<ExcludeFilesFromDeployment>File1.aspx;Folder2\File2.aspx</ExcludeFilesFromDeployment>
<ExcludeFilesFromDeployment>**\.svn\**\*.*</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>Folder1;Folder2\Folder2a</ExcludeFoldersFromDeployment>
</PropertyGroup>
Wildcards are supported.
To explain the example above:
The 1st ExcludeFilesFromDeployment excludes File1.aspx (in root of project) and Folder2\File2.aspx (Folder2 is in the root of the project)
The 2nd ExcludeFilesFromDeployment excludes all files within any folder named .svn and any of its subfolders
The ExcludeFoldersFromDeployment excludes folders named Folder1 (in root of project) and Folder2\Folder2a (Folder2 is in the root of the project)
For more info see MSDN blog post Web Deployment: Excluding Files and Folders via the Web Application’s Project File
Amazingly the answer for Visual Studio 2012 is not here:
The answer with green checkmark is not the answer.
The highest "upped" answer references an article from 2010 and says you have to edit your csproj project file which is now incorrect. I added the ExcludeFoldersFromDeployment XML element to my Visual Studio 2012 csproj file and it did nothing, the element was considered invalid, this is because ExcludeFoldersFromDeployment has been moved to the .pubxml file it looks like.
For Web Applications and Websites you edit the .pubxml file!
You can follow my answer or try this guide which I found later:
http://www.leniel.net/2014/05/using-msdeploy-publish-profile-pubxml-to-create-an-empty-folder-structure-on-iis-and-skip-deleting-it-with-msdeployskiprules.html#sthash.MSsQD8U1.dpbs
Yes, you can do this not just for Website Projects but Websites too. I spent a long time on the internet looking for this elusive exclude ability with a Visual Studio Website (NOT Website project) and had previously concluded it was not possible but it looks like it is:
In your [mypublishwebsitename].pubxml file, found in ~/Properties/PublishProfiles for Web Application Projects and ~/App_Data/PublishProfiles for Websites, simply add:
<ExcludeFilesFromDeployment>File1.aspx;Folder2\File2.aspx</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>Folder1;Folder2\Folder2a</ExcludeFoldersFromDeployment>
as children to the main <PropertyGroup> element in your .pubxml file. No need to add a new element not unless you are keying a specific build type, like release or debug.
BUT WAIT!!!
If you are removing files from your destination/target server with the following setting in your Publish configuration:
Then the Web Publish process will delete on your source/target server anything excluded, like an item you have delineated in your <ExcludeFoldersFromDeployment> and <ExcludeFilesFromDeployment>!
MsDeploy Skip Rules to the rescue:
First, Web Publish uses something other than MSBuild to publish (called Task IO or something like that) but it has a bug and will not recognize skip rules, so you must add to your .pubxml:
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
</PropertyGroup>
I would keep <WebPublishMethod> in its own <PropertyGroup>, you would think you could just have one <PropertyGroup> element in your .pubxml but my Skip Rules were not being called until I moved <WebPublishMethod> to its own <PropertyGroup> element. Yes, crazy, but the fact you need to do all this for Web Publish to exclude and also not delete a folder/file on your server is crazy.
Now my actual SkipRules, ExcludeFolders and ExcludeFiles declarations in my .pubxml:
<ExcludeFoldersFromDeployment>Config</ExcludeFoldersFromDeployment>
<ExcludeFoldersFromDeployment>Photos</ExcludeFoldersFromDeployment>
<ExcludeFoldersFromDeployment>Temp</ExcludeFoldersFromDeployment>
<ExcludeFilesFromDeployment>Web.config</ExcludeFilesFromDeployment>
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
And now a the Skip Rules (<Target> is a child of <Project> in your .pubxml):
(You may be able to leave <SkipAction> empty to Skip for all actions but I didn't test that and am not sure.
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipConfigFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Config</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipPhotosFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Photos</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipWebConfig">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Web\.config</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipWebConfig">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_DestinationContentPath)\\Temp</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
And please, do not to forget to escape the . in a filePath Skip rule with a backslash.
If you can identify the files based on extension, you can configure this using the buildproviders tag in the web.config. Add the extension and map it to the ForceCopyBuildProvider. For example, to configure .xml files to be copied with a publish action, you would do the following:
<configuration>...
<system.web>...
<compilation>...
<buildProviders>
<remove extension=".xml" />
<add extension=".xml" type="System.Web.Compilation.ForceCopyBuildProvider" />
</buildProviders>
To keep a given file from being copied, you'd do the same thing but use System.Web.Compilation.IgnoreFileBuildProvider as the type.
I struggled with the same issue and finally pulled the trigger on converting the web site to a web application. Once I did this, I got all of the IDE benefits such as build action, and it compiled faster to boot (no more validating web site...).
Step 1: Convert your 'web site' to a 'web application'. To convert it I just created a new "web application", blew away all the files it created automatically, and copied and pasted my web site in. This worked fine. Note that report files will need to have their Build Action set to "Content" instead of "none".
Step 2: Now you can set any files "Build Action" property.
Hope this helps.
In Visual Studio 2013 I found Keith's answer, adding the ExcludeFoldersFromDeployment element to the project file, didn't work (I hadn't read Brian Ogden's answer which says this). However, I found I could exclude a text file when publishing in Visual Studio 2013 by just setting the following properties on the text file itself:
1) Build Action: None
2) Copy to Output Directory: Do not copy
Initially I tried setting the Copy to Output Directory property by itself but that didn't work when the Build Action was set to the default value, Content. When I then set the Build Action to None the text file was no longer copied to the destination folder when I published.
To view these properties in the Visual Studio GUI, in the Solution Explorer right-click on the file you want to exclude and select Properties from the context menu.
I think you only have two options here:
Use the 'Exclude From Project'
feature. This isn't ideal because the
project item will be excluded from
any integrated IDE source control operations.
You would need to click the 'Show All
Files' button on the Solution window
if you need to see the files in
Solution Explorer, but that also
shows files and folders you're not
interested in.
Use a post-build event script to
remove any project items you don't
want to be published (assuming you're
publishing to a local folder then
uploading to the server).
I've been through this before and couldn't come up with anything really elegant.
For Visual Studio 2017, WebApp Publish, first create a standard file system publish profile.
Go to the App_Data\PublishProfiles\ folder and edit the [profilename].pubxml file.
Add
<ExcludeFilesFromDeployment>[file1.ext];[file2.ext];[file(n).ext]</ExcludeFilesFromDeployment>
under the tag<PropertyGroup>
You can only specify this tag once, otherwise it will only take the last one's values.
Example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>True</ExcludeApp_Data>
<publishUrl>C:\inetput\mysite</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
<ExcludeFilesFromDeployment>web.config;mysite.sln;App_Code\DevClass.cs;</ExcludeFilesFromDeployment>
</PropertyGroup>
</Project>
Make sure that the tag DeleteExistingFiles is set to False
As a contemporary answer, in Visual Studio 2017 with a .net core site:
You can exclude from publish like so in the csproj, where CopyToPublishDirectory is never.
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="appsettings.Local.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
</ItemGroup>
This is discussed in more detail here: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-2.2
<PropertyGroup>
<ExcludeFilesFromDeployment>appsettings.Local.json</ExcludeFilesFromDeployment>
</PropertyGroup>
The earlier suggestions did not work for me, I'm guessing because visual studio is now using a different publishing mechanism underneath, I presume via the "dotnet publish" cli tool or equivalent underneath.
The feature you are looking exists if your project is created as a "Web Application". Web Site "projects" are just a collection of files that are thought of as 1:1 with what gets deployed to a web server.
In terms of functionality both are the same, however a web application compiles all source code to a DLL, instead of the naked source code files being copied to the web server and compiled as needed.
This is just an addendum to the other helpful answers here and something I've found useful...
Using wpp.targets to excluded files and folders
When you have multiple deployments for different environments then it's helpful to have just one common file where you can set all the excluded files and folders. You can do this by creating a *.wpp.targets file in the root of the project like the example below.
For more information see this Microsoft guide:
How to: Edit Deployment Settings in Publish Profile (.pubxml) Files and the .wpp.targets File in Visual Studio Web Projects
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<EnableMSDeployAppOffline>True</EnableMSDeployAppOffline>
<ExcludeFilesFromDeployment>
*.config;
*.targets;
*.default;
</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>
images;
videos;
uploads;
</ExcludeFoldersFromDeployment>
</PropertyGroup>
</Project>
In Visual Studio 2017 (15.9.3 in my case) the manipulation of the .csproj-File works fine indeed! No need to modify the pubxml.
You can then construct pretty nice settings in the .csproj-File using the PropertyGroup condition, e.g.:
<PropertyGroup Condition="$(Configuration.StartsWith('Pub_'))">
<ExcludeFoldersFromDeployment>Samples</ExcludeFoldersFromDeployment>
</PropertyGroup>
excludes the "Samples" folder from all deployments with configurations starting with "Pub_"...
In Visual Studio 2022 I have successfully used this settings:
Go and edit the
[ProjectName] \ Properties \ PublishProfiles \ FolderProfile.pubxml file
in solution explorer.
Add these lines inside PropertyGroup
element:
<ItemGroup>
<Content Remove="Data\*.json" />
<None Include="Data\*.json" />
</ItemGroup>
Then save the .pubxml file and try to publish the project.
"Content Remove" will remove the file from the content to deploy.
"None Include" will keep the file in the solution explorer.
It's possible to set it up in the solution explorer for single files as well: right click the file in the solution explorer -> Properties and change the Build Action to None.

Resources