<_CustomFiles> element not recognized in .pubxml - asp.net

I'm trying to include a file in an ASP.NET filesystem publish that's not included in the solution (it's autogenerated from a post-build script). According to these instructions, I should be able to add a reference to the file in my .pubxml definition using the <_CustomFiles> element. Here's what my .pubxml file looks like:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>(publish URL here)</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="scripts\app.min.js" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
The second <PropertyGroup> and the <Target> elements were added by me.
However, Visual Studio isn't recognizing the <_CustomFiles> element and the file isn't being included in the publish. Notice the green squiggly line underneath the element:
When I hover over it, the following error message is shown:
The element 'ItemGroup' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003' has invalid child element '_CustomFiles' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003'
Why is this element not recognized by Visual Studio? What do I need to change in order to include this file in my filesystem publish?

Figured it out. I misunderstood the purpose of the <_CustomFiles> element. It seems this is a custom element (i.e. not part of the XML schema, hence the VS warning) used to pass information to the <FilesForPackaginFromProject> element below it.
It turns out this method was working for me, I was simply using the relative paths incorrectly.

Related

How to get net-core projects to include auto generated code file?

I have a .net core project file (*.csproj) like this:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<!-- Create RS.cs -->
<ItemGroup>
<ResourceGeneratorInputs Include="strings.resx" />
<ResourceGeneratorOutputs Include="RS.cs" />
</ItemGroup>
<Target Name="GenerateTheResourceFile"
BeforeTargets="PrepareForBuild"
Inputs="#(ResourceGeneratorInputs)"
Outputs="#(ResourceGeneratorOutputs)">
<Exec Command="ResourceStringGenerator.exe strings.resx RS.cs " />
</Target>
</Project>
This projects has a target that generates a csharp code file called RS.cs, which also must be compiled.
The problem is the file is generated too late. The build engine has already read the list of files in the project directory, and the RS.cs file gets ignored.
I have tried changing the BeforeTargets attribute to various other Targets with no luck at all. (Described here: https://learn.microsoft.com/en-us/dotnet/core/tools/csproj#build-events)
I've tried turning off automatic inclusion of files too:
<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
and making my own list of files to compile. But that didn't work either. The RS.cs file was still generated too late.
The new project file format seems to be so eager to get the list of files, that it seems to leave no room for auto-generated files.
What is the work-around here?
The static portion of a project file is always evaluated before targets run.
However, you can also add items inside your target:
<Target Name="GenerateTheResourceFile"
BeforeTargets="PrepareForBuild"
Inputs="#(ResourceGeneratorInputs)"
Outputs="#(ResourceGeneratorOutputs)">
<Exec Command="ResourceStringGenerator.exe strings.resx RS.cs " />
<ItemGroup>
<EmbeddedResource Include="strings.resx" Exclude="#(EmbeddedResource)" />
<Compile Include="RS.cs" Exclude="#(Compile)" />
</ItemGroup>
</Target>
The "exclude" part ensures that the file isn't added twice if it was already picked up during static evaluation (i.e. additional builds)

Visual Studio always restoring because Directry.Build.props

I created a Directory.Build.props file, with VersionSuffix contain the current Hour and Minutes:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionSuffix>$([System.DateTime]::Now.ToString(yyyy-MM-dd-HHmm))-$(Configuration)</VersionSuffix>
</PropertyGroup>
</Project>
Now, because this file changed every minute, the Visual Studio complete it auto-restore, and start it again, because after a minute the properties are different.
So, I added a Target to update the properties only before the Build:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Version" BeforeTargets="Build">
<PropertyGroup>
<VersionSuffix>$([System.DateTime]::Now.ToString(yyyy-MM-dd-HHmm))-$(Configuration)</VersionSuffix>
</PropertyGroup>
</Target>
</Project>
Now the Visual Studio works fine, but from the command-line (msbuild MySln.sln /t:Build...) the properties don't apply.
(I tried with Directory.Build.targets and it acts the same (unless I missed something))
(You can try with more simple property, Company for example).
How can I use a time-based property, but apply it only when I creating the DLL?
Using InitialTargets solved my problem:
<Project InitialTargets="Version" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Version">
<PropertyGroup>
<VersionSuffix>$([System.DateTime]::Now.ToString(yyyy-MM-dd-HHmm))-$(Configuration)</VersionSuffix>
</PropertyGroup>
</Target>
</Project>

.wpp.targets file is ignored during build

I'm trying to apply custom ACLs using webdeploy (set Write permission to a folder - the folder is empty but added to the project and correctly deployed).
I'm building a VS solution on my CI server with the following command line:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
/consoleloggerparameters:ErrorsOnly
/maxcpucount
/nologo
/property:Configuration=Release
/p:Platform=x86
/verbosity:quiet
MySolution.sln
/p:DeployOnBuild=True
/p:PublishProfile="ci"
/p:ProfileTransformWebConfigEnabled=False
/p:WebPublishPipelineCustomizeTargetFile="MyProject\MyProject.wpp.targets"
It builds correctly but it completely ignores the content of my MyProject.wpp.targets. I tried to write wrong XML but it gets silently ignored, the build is successful but clearly without my wpp.targets applied. The /p:WebPublishPipelineCustomizeTargetFile parameter doesn't have any effect.
This is the content of MyProject.wpp.targets:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="SetupCustomAcls" AfterTargets="AddIisSettingAndFileContentsToSourceManifest">
<ItemGroup>
<MsDeploySourceManifest Include="setAcl">
<Path>$(_MSDeployDirPath_FullPath)\Content\cache</Path>
<setAclAccess>Read,Write</setAclAccess>
<setAclResourceType>Directory</setAclResourceType>
<AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
</Target>
<Target Name="DeclareCustomParameters" AfterTargets="AddIisAndContentDeclareParametersItems">
<ItemGroup>
<MsDeployDeclareParameters Include="ContentCacheSetAclParam">
<Kind>ProviderPath</Kind>
<Scope>setAcl</Scope>
<Match>^$(_EscapeRegEx_MSDeployDirPath)\\Content\\cache$</Match>
<Description>Add write permission to the Content/cache folder.</Description>
<DefaultValue>{$(_MsDeployParameterNameForContentPath)}/Content/cache</DefaultValue>
<Value>$(_DestinationContentPath)/Content/cache</Value>
<Tags>Hidden</Tags>
<Priority>$(VsSetAclPriority)</Priority>
<ExcludeFromSetParameter>True</ExcludeFromSetParameter>
</MsDeployDeclareParameters>
</ItemGroup>
</Target>
</Project>
The project is a net641 csproj <Project Sdk="Microsoft.NET.Sdk.Web">.
What's wrong with my configuration? Thank you for your help.

Include folder not referenced by project?

I'm trying to figure out how to upload a folder that i do not want to reference in the project file. The folder "build" is and output step that is generated from webpack. I've found other threads with the same problem and this is what i've tried (added to the end of my pubxml file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\build\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>build\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
which did not work
Try "CopyAllFilesToSingleFolderForMSDeployDependsOn" instead of "CopyAllFilesToSingleFolderForPackageDependsOn".
<PropertyGroup>
<CopyAllFilesToSingleFolderForMSDeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForMSDeployDependsOn);
</CopyAllFilesToSingleFolderForMSDeployDependsOn>
</PropertyGroup>
Based on my review of the latest MSDeployAddFilesOutsideOfProject.wpp.targets file (distributed with VS2015), "ForPackage" may be deprecated. The target is still there but I can't find where its referenced.
Update - Wrote a quick blog post with more details:
http://www.dotnetcatch.com/2016/07/20/include-extra-files-in-webdeploy-package/

MsDeploySkipRules in wpp.targets not working with PublishProfiles

I am publishing my MVC project with the PublishProfile through visual studio, (through UI, right click project, publish) and ticking the option to clear the destination folder.
But I do not want a specific folder "Downloads" to be cleared
I have spent countless hours trying to make this work, I think I have the exact same code as the person explained here but it still deletes the Downloads folder
Also as example in the below I have the ExcludeFromPackageFiles of "favicon" which works if I deselect the deletion of the destination folder (just to show that my wpp targets is in fact running).
Below is my projectname.wpp.targets file
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- this doesnt work -->
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<PropertyGroup>
<UseMsDeployExe>true</UseMsDeployExe>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipErrorLogFolder1">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>ErrorLog</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
<!-- this works! -->
<ItemGroup>
<ExcludeFromPackageFiles Include="favicon.ico">
<FromTarget>ContactManager.Mvc.wpp.targets</FromTarget>
</ExcludeFromPackageFiles>
</ItemGroup>
</Project>
Any Ideas?
(1) The AbsolutePath value in your example is copy/pasted from my skip rule example. You need to change that value to the path of your Downloads folder.
<Target Name="AddCustomSkipRules">
<Message Text="Adding Custom Skip Rules" />
<ItemGroup>
<MsDeploySkipRules Include="SkipDownloadsFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>Downloads</AbsolutePath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
(2) You cannot use a custom skip rule when publishing from within Visual Studio. You must publish using MSBuild from a command prompt. The nature of my question was about combining the convenience of the publishing profile managed within VS, with the utility of a custom skip rule (which requires the command line), because as of VS 2012 Update 3, the limitation of the command line has not been lifted.
My MSBuild command looks like this:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe My.Website.sln /p:Configuration=Release;DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"
If I attempt to publish from within VS 2012, I get the following error, even though "-verb:sync" is clearly visible in the output:
2>Start Web Deploy Publish the Application/package to http://my.website.example.com/MSDEPLOYAGENTSERVICE ...
2>C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe
-source:manifest='C:\inetpub\wwwroot\My.Website\obj\Release\Package\My.Website.SourceManifest.xml'
-dest:auto,ComputerName='http://my.website.example.com/MSDEPLOYAGENTSERVICE',UserName='...',Password="...",IncludeAcls='False',AuthType='NTLM'
-verb:sync
-disableLink:AppPoolExtension
-disableLink:ContentExtension
-disableLink:CertificateExtension
-skip:skipaction='Delete',objectname='filePath',absolutepath='ErrorLog'
-skip:objectname='dirPath',absolutepath='obj\\Release\\Package\\PackageTmp\\App_Data$'
-skip:objectname='dirPath',absolutepath='MyWebsite/\\App_Data$'
-setParamFile:"C:\inetpub\wwwroot\My.Website\obj\Release\Package\My.Website.Publish.Parameters.xml"
-retryAttempts=2
2>MSDEPLOY(0,0): Error : The verb must be specified by using the -verb argument.
2>MSDEPLOY(0,0): Error count: 1.

Resources