Generated *.SourceManifest doesn't include additional runCommand WebDeploy settings - asp.net

I'm trying to configure a runCommand to wait more than the default value of 1 second to finish.
This is a sample pubxml code:
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<waitInterval>60000</waitInterval>
<path>"C:\Company\install-services.cmd"</path>
</MsDeploySourceManifest>
</ItemGroup>
When I start a deployment, it successfully creates a *.SourceManifest.xml file in the temp package directory, but it only includes the path:
<runCommand path=""C:\Company\install-services.cmd"" />
Furthermore, I'm deploying the whole web site from Visual Studio.
Is there any way to get more than the path parameter added to the resulting file?

Everything is fine except that pubxml item group requires an additional XML element. The final and working result looks like the following code:
<ItemGroup>
<MsDeploySourceManifest Include="runCommand">
<waitInterval>60000</waitInterval>
<path>"C:\Company\install-services.cmd"</path>
<AdditionalProviderSettings>waitInterval</AdditionalProviderSettings>
</MsDeploySourceManifest>
</ItemGroup>
My markup lacked the <AdditionalProviderSettings> element. Once I've added this element, the *.SourceManifest.xml generated by Visual Studio looked like this code:
...
<runCommand path=""C:\Company\install-services.cmd"" waitInterval="60000" />
...

Related

Blazor component not linking css

I have a Blazor server app with a client project. In the client project, I have a bunch of pages and components. Adding a file with the same name as the razor page with the CSS extension worked so far to create scoped CSS files… But somehow not anymore.
I added a new page under the page's folder. Named Historia.razor. Added a Historia.razor.css file in the same folder. Visual Studio understands it nicely and nests the CSS page under the main razor file.
But when compiling and running the app, the styles do not appear. I checked the combined CSS file (MyApp.styles.css) and there are no entries from the Historia.razor.css file. Also checked the styles on the generated page and they don't contain the b-213321 extra ID on the class names.
I checked the project file to ensure the file is not under the "ignore", It is not. This is what the project file looks like:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazored.Toast" Version="3.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.3" />
</ItemGroup>
<ItemGroup>
<Watch Include="**\*.razor" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\VikingBoardGames.Shared.csproj" />
</ItemGroup>
</Project>
Once again, it DOES WORK for other components and pages that I added in the past and follows the same exact folder/naming structure.
Any ideas on what is preventing the CSS to be bundled with the rest?
NOTE: After doing a clean - build -delete .vs folder - restart VS as suggested by Henk Holterman my tags do show the b-312412wgz code. But still, the styles are not applied and the CSS content is not added to the myproject.styles.css file.
I tried also to create a new file, with its CSS file. Exactly the same behavior.
Whenever things don't work as they should, the following steps might help:
Do a Build|Clean Solution
Close VS
In the Solution folder, delete the .vs folder
Reopen the Project and do a Build|Rebuild
and in case of a Web App,
Use Ctrl+F5 to force refresh all files
With the Dev tools (F12), go to the Application tab and clean the Cache and Local storage.
Cross your fingers and try again.

How to exclude certain file types from dotnet watch run?

Looking to get the following setup going:
I'm working on a Blazor app, and with the official css isolation bundler. I'm using Less though, and installed a Less transformer which creates the required css on build.
However, running my app via dotnet watch run, it often ends up in an endless loop now.
The reason for this is probably that dotnet watch run sees a change in the *.razor.css files, rebuilds, and the cycle just repeats on and on.
So here's my question:
How can I configure my csproj (new Net Standard format) to exclude **\*.razor.css from the watch process? It would also be fine it it just disappears from my VS solution as a whole.
Had a play with both answers above, but neither worked for me. I generate some files during the build and that may be why the other 2 don't work for me. According to Microsoft docs shared above (https://learn.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.1), to remove an item from watch you can also set it through the definition. Doing this worked for my scenario.
<ItemGroup>
<Content Remove="wwwroot\dist\**" />
<Content Include="wwwroot\dist\**" Watch="false" />
</ItemGroup>
I did have to add the Content Remove as otherwise the item is declared twice and the build will fail.
Please edit your .csproj file and add the following to it
<ItemGroup>
<Watch Exclude="**\*.razor.css" />
</ItemGroup>
More info at
https://learn.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch?view=aspnetcore-3.1
I had the same issue after coming here, ended up with:
<ItemGroup>
<Watch Remove="wwwroot\**\*" />
</ItemGroup>
Works nicely for me :)
I have a similar set-up except but I'm using SASS. I have a custom target to execute the command npm run sass, so the files are being generated as part of the dotnet build process, which made the watch re-trigger builds in an infinite loop.
In my case, the solution I found was like the following:
Alter the DefaultItemExcludes:
<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);Features/**/*.css</DefaultItemExcludes>
</PropertyGroup>
Adjust sure the css compilation target to run before BeforeResGen instead of Compile (which I was using before):
<Target Name="CompileScopedScss" BeforeTargets="BeforeResGen">
<Exec Command="npm run sass -- %(ScopedScssFiles.FullPath) %(RootDir)%(Directory)%(FileName).css --no-source-map" />
</Target>
Include the css file and set Watch="False":
<ItemGroup>
<Content Include="Features/**/*.css" Watch="False" />
</ItemGroup>
I do this in a target after the previous target, but it seems to work also outside it.
Just using the <Content Update... Watch="False" /> wasn't enough in my case. The <Watch Remove="..." /> didn't work either in my case and I believe it could have something to do with the fact that the files are generated during the build.

dotnet core nuget package copying content files on restore

So I feel like I have come to the end of the rope here, but hoping someone knows more than I do here. I have some Typescript files, though that is mostly irrelevant as I am having this problem with all content files.
I am able to generate a nuget, or more precisely dotnet pack, nuget package that includes my content files in the package by using this in the .csproj of my parent project:
<ItemGroup>
<Content Include="Scripts\Utility.ts">
<Pack>true</Pack>
<PackagePath>contentFiles\Scripts\;content\Scripts</PackagePath>
</Content>
</ItemGroup>
I can browse the generated .nupkg and see that indeed the file was added to the package in both the content\Scripts and contentFiles\Scripts locations
The problem is that whenver I consume this package in my 'child' progect, that Typescript never gets copied into any folder of the child project, though I can see it extracted in the .nuget\packages\parent\... folders.
At first I thought it was something with my initial settings in the parent project, and it may be, but after trying what seems like everything in the book, that fails to copy the content files to the child project. I then tried going the dark path of trying to use Init.ps1 in the tools folder of my package, and though it was impossible to debug, it also seemed to run sporatically (I completely unistalled and reinstalled the package and it still failed to run most of the time.) This could be the way but I don't know why I can't get it to output to the Package Manager Console... maybe there's still hope with Init.ps1 but I can't seem to figure it out. Finally I see some potential with a nuget .targets file but I can's seem to grasp how to use it for my purpose either! I would love some feedback as to how to get this done.
From: Announcing NuGet 3.1 with Support for Universal Windows Platform
Importing content from a Nuget package was depreciated for projects using a project.json file in Nuget v3.1. Since then the project.json file has been dropped in favour of the new .csproj format. Importing content from a Nuget package should still work though if you're using the packages.config file instead.
Also mentioned is the fact that there are other package managers available for delivering content.
It looks to me like the answer in the new world is to create a node module containing utility.js and let npm deliver it to your project.
Possible Workaround:
I've looked at .targets to copy files and got this working, but it does run on each build - which may or may not be a problem for you. I can't do what I want with it.
In [PackageId].targets:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Either do this for all scripts in the Scripts/js folder -->
<Target Name="CopyScriptsToProject" BeforeTargets="Build">
<Message Text="Copying scripts to project" />
<ItemGroup>
<SourceScripts Include="$(MSBuildThisFileDirectory)..\..\content\Scripts\js\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="#(SourceScripts)" DestinationFiles="#(SourceScripts -> '$(MSBuildProjectDirectory)\wwwroot\js\%(RecursiveDir)%(Filename)%(Extension)')" Condition="!Exists('$(MSBuildProjectDirectory)\wwwroot\js\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<!-- Or do this for the individual script -->
<Target Name="CopyUtilityScriptToProject" BeforeTargets="Build">
<Copy SourceFiles="$(MSBuildThisFileDirectory)..\..\content\Scripts\js\Utility.js" DestinationFiles="$(MSBuildProjectDirectory)\wwwroot\js\Utility.js" Condition="!Exists('$(MSBuildProjectDirectory)\wwwroot\js\Utility.js')" />
</Target>
</Project>
<!-- Note: condition can be removed from either if you want it to overwrite each build -->
and in the .csproj file (replacing [PackageId] with the name of your package):
<Project Sdk="Microsoft.NET.Sdk">
... any Globals for source control stuff ...
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Version>7.0.0</Version>
<PackageId>[PackageId]</PackageId>
</PropertyGroup>
... any PackageReference stuff ...
<ItemGroup Label="Packaging">
<Content Include="build\netcoreapp2.0\[PackageId].targets" PackagePath="build\netcoreapp2.0\[PackageId].targets" />
<!-- Either -->
<Content Include="Scripts\js\**\*.*" PackagePath="content\Scripts\js;contentFiles\Scripts\js" />
<!-- or -->
<Content Include="Scripts\js\Utility.js" PackagePath="content\Scripts\js;contentFiles\Scripts\js" />
</ItemGroup>
</Project>
There seemed to be a bug whereby when the <PackageId>[PackageId]</PackageId> wasn't set explicitly in the .csproj, the build targets didn't work. Although that may well be an issue with my development environment.
Apparently you need the any\any in the path (learn more) as well as to include <PackageCopyToOutput>true</PackageCopyToOutput>, like this:
<ItemGroup>
<Content Include="Scripts\js\Utility.js">
<Pack>true</Pack>
<PackagePath>contentFiles\any\any\wwwroot\js\;content\any\any\wwwroot\js\</PackagePath>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
</ItemGroup>
You'll also need to precompile your TypeScript before including the .js files in the package
However, this still doesn't create a file there, just some strange reference to it.
In the end, we got it working with a .targets file, you can find a working repo here: https://github.com/NuGet/Home/issues/6743
Serj Sagan's answer got me on the right track, but it wasn't sufficient to deploy the content file to the bin directory (as he noted). I was able to get the file to be deployed by changing the package reference options in the consuming project's .csproj file, as follows:
<PackageReference Include="MyNuGetPackage" Version="0.0.0.1">
<IncludeAssets>all</IncludeAssets>
<PrivateAssets>analyzers;build</PrivateAssets>
</PackageReference>
It seems like the default for PrivateAssets is contentfiles;analyzers;build (documentation), which is not what we want in this case.
Simplified code and explanation from #PurplePiranha
TL;DR:
Basic .NET6 simplified sample code on Github
Step by Step guide
Selection of the files
First we need to select all the files that needs to get into the nuget package.
Add this to the <LibraryPackageName>.csproj:
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="Packaging">
<Content Include="<Your directory path>\<your file(s)>" />
</ItemGroup>
Multiple content lines are allowed.
Write a target
Make a target file to copy the files before (or after) the build to the bin directory:
The location and name of this file is important:
<root>\build\<LibraryPackageName>.targets
Now, make sure that it will get executed by referencing it in the <LibraryPackageName>.csproj by adding a content line:
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="Packaging">
<Content Include="build\<LibraryPackageName>.targets" PackagePath="build\<LibraryPackageName>.targets" />
<Content Include="filesToAdd\*.txt">
<Pack>true</Pack>
</Content>
</ItemGroup>
Eg: From the code in github:
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="Packaging">
<Content Include="build\PackageToGenerateFile.targets" PackagePath="build\PackageToGenerateFile.targets" />
<Content Include="filesToAdd/*.txt">
<Pack>true</Pack>
</Content>
</ItemGroup>
NOTE: By copying the files to the bin directory, the files are not part of your version control, but your package is!
Build and pack
In Visual Studio, right-click on the package name and select "Pack".
A new nuget package should be created in the bin directory of your library.
Use the nuget package
Install the nuget package now in your destination package.
Notice that the files are in the solution explorer, but not in a directory on your disk. They have a shortcut symbol.
Build the destination package
Check the bin directory.
The files should be copied to the location mentioned in the targets.

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.

MS Web Deploy Skip Delete Rule not skipping

I've added the following skip rule to my project but when I use Web Deploy to publish the contents, the files in the /config folder are being wiped out.
I'm using the process found here and I swear it was working previously.
I've added the following to my project file:
<PropertyGroup>
<OnBeforePackageUsingManifest>AddCustomSkipRules</OnBeforePackageUsingManifest>
</PropertyGroup>
<Target Name="AddCustomSkipRules">
<ItemGroup>
<MsDeploySkipRules Include="SkipConfigFolder">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>.*\\config\\$</AbsolutePath>
<XPath></XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipConfigSubFolders">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>.*\\config\\.*$</AbsolutePath>
<XPath></XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
When I publish (via command-line using the cmd file generated by the package), the following is outputted:
-------------------------------------------------------
Start executing msdeploy.exe
-------------------------------------------------------
"C:\Program Files\IIS\Microsoft Web Deploy V2\\msdeploy.exe"
-source:package='<MyPackageFile>'
-dest:auto,includeAcls='False'
-verb:sync
-disableLink:AppPoolExtension
-disableLink:ContentExtension
-disableLink:CertificateExtension
-skip:skipaction='Delete',objectname='dirPath',absolutepath='.*\\config\\$'
-skip:skipaction='Delete',objectname='dirPath',absolutepath='.*\\config\\.*$'
-setParamFile:"<MySetParameters.xml>"
Info: Deleting filePath (Default Web Site/uPPK_32\config\New Text Document.txt).
It looks like the skip rule is being added but notice New Text Document.txt is being deleted. How can I prevent this? Am I missing something?
I think your second skip line needs to use filePath instead of DirPath, as you're selecting files there.
The values of the absolutePath attributes are regexes, so you probably want a value like '\\config' or '\\config$' instead of the values for the two example skip settings shown in your question.

Resources