I have a .NET 7.0 web-app that I want to publish as a singlefile including all the content of its 'wwwroot' folder and the 'web.config'.
I am trying to publish with
dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true
and the following annotation in the .csproj:
<ItemGroup>
<Content Update="wwwroot/**">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>false</ExcludeFromSingleFile>
</Content>
</ItemGroup>
I use 'Update' instead of 'Include' because the files are already included (because of default=true of EnableDefaultContentItems)
After all this I still get a directory 'wwwroot' and the file 'web.config' in the publish directory. Peeking in the .exe i can see there are none of the files included.
Can someone help me publish this webapp as a singlefile?
I have made a console-test-project with files in a subfolder. In this test the configuration above includes the dummy files.
OK I found a solution:
the publish-command was OK but the .csproject has to be modified further:
first you have to exclude the desired folder from the DefaultItems it is part of (see pokes answer)
<PropertyGroup>
<DefaultItemExcludes>wwwroot/**</DefaultItemExcludes>
...
Second, you have to re-include the directory as 'None' or in my case 'EmbeddedResource', but not 'Content' as I did above:
<ItemGroup>
<EmbeddedResource Include="wwwroot\**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Bonus: You can read your newly embedded-files as described here by adrianord on Jul 15, 2021
Related
When using examples such as
<!--Include in publish-->
<ItemGroup>
<None Include="exampleDirectory\**\*.*" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
</ItemGroup>
This folder has .cshtml and .cshtml.cs files but only the .cshtml.cs files are copied. Is there a specific reason these files do not copy over?
Copy and paste of the required folder into the publish output directory works. Meaning if this copy mechanism just worked and copied all the files this wouldn't be an issue.
I have it setup as <None because I need to have two directories and using <Content gives an error of having two contents being used.
C:\Program Files\dotnet\sdk\3.1.404\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(318,5): error NETSDK1022: Duplicate 'Content' items were included. The .NET SDK includes 'Content' i
tems from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultContentItems' property to 'false' if you want to explicitly include them in yo
ur project file. For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: 'dirName\fileName.cshtml'; 'dirName\fileName.cshtml' [C:\path\to\projectName.csproj]
Which when set to false for EnableDefaultContentItems it still does not copy the .cshtml files, just the .cshtml.cs files.
why do you have 'None'?
Example:
<ItemGroup> <Content Include="AppData\**" CopyToPublishDirectory="PreserveNewest"/> </ItemGroup>
I have the following pubxml file which I created via Visual Studio 2019:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<ProjectGuid>143a6329-27d9-474e-9521-835be634c293</ProjectGuid>
<SelfContained>true</SelfContained>
<publishUrl>bin\Release\netcoreapp3.1\publish\</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
When I run dotnet.exe publish src\MyProject.Web.sln -p:PublishProfile=Properties\PublishProfiles\ProductionPublish.pubxml Release does not contain anything and publish happens on Debug folder (debug build). Whys does this happens and pubxml is ignored?
Update #1
Structure
src\MyProject\MyProject.csproj
src\MyProject.Utils\ect.Utils.csproj
src\MyProject.Web\MyProject.Web.csproj
src\MyProject.Web.sln
and the path of the pubxml
src\MyProject.Web\Properties\PublishProfiles\ProductionPublish.pubxml
You need the use following command:
dotnet build -c Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile
It's build, not publish.
Even if my FolderProfile's configuration is set to Release, I had to
include -c Release because otherwise dependent projects were built
with debug configuration.
Files not copied to target location if called without /p:DeployOnBuild=true.
Just the name FolderProfile -without extension- is enough for the
profile file. Or you can give the path
/p:PublishProfile=Properties\PublishProfiles\FolderProfile.pubxml
See Folder publish example from Microsoft Docs.
Found a solution on VS2022 and Core 6 to publish to an specific folder without indicating the output path on the CLI.
I created a profile called IISC
If you open that publish profile, you will see the PublishUrl property as follows
<PublishUrl>bin\Release\net6.0\publish\IISC</PublishUrl>
In My case I'm publishing to the solution folder bin\releas....\IISC
The trick is to add another propery called PublishDir
<PublishDir>bin\Release\net6.0\publish\IISC</PublishDir>
Now you can publish with this:
dotnet publish -c Release /p:PublishProfile=IISC
Find Bellow My complete Profile with and addition of an environment variable specific for this profile and and item group to exclude all the appsettings except for appsettings.json and appsettings.IISC.json
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<ASPNETCORE_ENVIRONMENT>iisc</ASPNETCORE_ENVIRONMENT>
<DeleteExistingFiles>true</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>bin\Release\net6.0\publish\IISC</PublishUrl>
<PublishDir>bin\Release\net6.0\publish\IISC</PublishDir>
<WebPublishMethod>FileSystem</WebPublishMethod>
<SiteUrlToLaunchAfterPublish />
<TargetFramework>net6.0</TargetFramework>
<ProjectGuid>3e4c25a6-2051-4ccc-a518-645d46d120dd</ProjectGuid>
<SelfContained>false</SelfContained>
</PropertyGroup>
<ItemGroup>
<Content Update="appsettings.*.json">
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
<Content Update="appsettings.$(ASPNETCORE_ENVIRONMENT).json">
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\PublishProfiles\" />
</ItemGroup>
</Project>
I'm gonna answer for those who, like me, do want to use the publish command, because it's been designed to do so.
According to Options section on publish command, you can use the options configuration and output to solve your problem:
dotnet publish -c Release -o "<where you want>" -p:PublishProfile=<your profile name>
Note that where you want can be an absolute path and your profile name is only the name of profile, without "pubxml" and without the relative path (IF AND ONLY IF the profile is in "<project_folder>/Properties/PublishProfiles").
Let's say I have this structure of projects:
- AppRunner
| - Apprunner.csproj
| - wwwroot
- Tests
| - Tests.csproj
| - bin
| - debug
| - netcoreapp2.1
| - I want copy wwwroot here
I'd want to tell compiler to copy wwwroot with all items and folders inside to output folder of tests
but I'd want it to work fine not only on Windows but also on Linux
I addedd to Tests.csproj this:
<ItemGroup>
<None Update="..\AppRunner\wwwroot\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
but it doesn't really work
In your Tests.csproj you could set up a link to your wwwroot folder:
<ItemGroup>
<Content Include="..\AppRunner\wwwroot\**" Link="wwwroot\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always" />
</ItemGroup>
In Visual Studio this will look like a regular wwwroot folder in your Tests project, but it is actually just a link to the folder in AppRunner. When you specify CopyToOutputDirectory this folder and its contents will be copied to the bin folder when you build the Tests project
As #cyptus suggested you could utilize MsBuild tasks.
For example you can add task that will copy contents of wwwroot anywhere you want after each build. To do so add post build task at the end of your Apprunner.csproj.
<Target Name="CopyWwwroot" AfterTargets="Build">
<ItemGroup>
<CopyItems Include="$(SolutionDir)\Apprunner\wwwroot\**\*.*" />
</ItemGroup>
<Copy
SourceFiles="#(CopyItems)"
DestinationFolder="..\Tests\bin\$(Configuration)\$(TargetFramework)\wwwroot\%(RecursiveDir)"
SkipUnchangedFiles="false"
OverwriteReadOnlyFiles="true"
Retries="3"
RetryDelayMilliseconds="300"/>
</Target>
$(Configuration) is current configuration e.g. debug or release
$(TargetFramework) is framework you are building with in your scenario netcoreapp2.1
If you really want you can have those values hardcoded. You can read more about copy task on docs https://learn.microsoft.com/en-us/visualstudio/msbuild/copy-task?view=vs-2019
Also keep in mind that you can set condition on target for example to copy only if you are building in release.
I'm trying to publish a web API built in .NET Core to a Ubuntu server but am having difficulty with the dependencies. I am new to doing this in C# and haven't found a concise answer to how dependencies are included with the publish command. I was lead to believe that they were complied into a .dll but I am getting this error when running my app
Error:
An assembly specified in the application dependencies manifest (api.deps.json) was not found:
package: 'Newtonsoft.Json', version: '11.0.2'
path: 'lib/netstandard2.0/Newtonsoft.Json.dll'
Shouldn't that have been included in the "Release" directory after being published?
I'm using .NET Core on a Mac and then publishing to an Ubuntu sever should that affect anything here.
.csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>
</Project>
Shouldn't that have been included in the "Release" directory after being published?
No.
When you publish a project, you specify a different directory for the publish output when creating the publish profile.
The Release directory is only for assets that are used during debugging. During development, the NuGet dependencies are not in the Release folder, they are in the NuGet cache. So, you cannot always just copy the Release folder and expect it to run.
After publishing, the entire application (including all dependencies) are output to the publish location. Do note that the publish output doesn't necessarily have to be a folder. For example, depending on the type of project it may be published to IIS with web deploy or to an FTP location.
I'm trying to update my (previously working) pdf-creating web application to use the ABCpdf.NET and ABCpdf.NET Gecko Runtime nuget packages.
I've installed both packages (both are version 8.1.1.6) however when I run my application, I get the following WebSupergoo.ABCpdf8.Internal.PDFException:
Failed to add HTML: Gecko engine hit an error it was unable to recover
from. Possible causes: XULRunner folder is corrupt or is from another
version of ABCpdf.
After installing the ABCpdf.NET Gecko Runtime package, I got a dialog telling me that I would need to manually copy the XULRunner folder into my output directory. In order to achieve this, I added the following to my applications .csproj file:
<Target Name="AfterBuild">
<CallTarget Targets="CopyAbcpdfToDeployFolder" />
</Target>
<Target Name="CopyAbcpdfToDeployFolder">
<ItemGroup>
<SourceDir Include="$(ProjectDir)XULRunner\**\*.*" />
</ItemGroup>
<Copy SourceFiles="#(SourceDir)" DestinationFolder="$(WebProjectOutputDir)\$(OutputPath)%(SourceDir.RecursiveDir)\XULRunner" />
</Target>
(This seems to be working correctly - the XULRunner folder and its contents are present in my bin folder after a build)
The line of code that is failing is as follows:
theDoc.AddImageUrl(url);
Can anyone help me get this working?
As it turns out, my changes to the .csproj file we not copying all files into the correct subfolders. In order to copy the folder structure and files recursively, the XML should have looked like this:
<Target Name="AfterBuild">
<CallTarget Targets="CopyXULRunnerToDeployFolder" />
</Target>
<Target Name="CopyXULRunnerToDeployFolder">
<ItemGroup>
<MyFiles Include="XULRunner\**\*.*" />
</ItemGroup>
<Microsoft.Build.Tasks.Copy SourceFiles="#(MyFiles)" DestinationFiles="#(MyFiles->'$(OutputPath)\XULRunner\%(RecursiveDir)%(Filename)%(Extension)')"/>
</Target>
I was able to accomplish the same outcome with the following MSBuild xml:
<ItemGroup>
<Content Include="XULRunner\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
I fell upon this setup after dealing with issues concerning the building of a package via MSDeploy not including the XULRunner files.
Not sure if there's anything patently wrong with this, but so far it works for me on a multiple staged deployment setup.