Sdk: msbuild fail : need to set SelfContained to false or UseAppHost to true

Created on 30 Aug 2018  ·  14Comments  ·  Source: dotnet/sdk

When I update .net core sdk to 2.1.4, error raised when my project was built to publish.

C:\Program Files (x86)\dotnet\sdk\2.1.401\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(122,5): error NETSDK1067: Self-contained applications are required to use the application host. Either set SelfContained to false or set UseAppHost to true. [C:\Program Files (x86)\Jenkins\workspace\TMQ4.DEV\Tmq.Web\Tmq.Web.csproj]

My publication Profile.pubxml is like below:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish>http://10.201.248.21:6063</SiteUrlToLaunchAfterPublish>
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <ProjectGuid>395ae9e5-cc25-4e6d-90c3-7eb056d30a9f</ProjectGuid>
    <MSDeployServiceURL>10.200.248.21</MSDeployServiceURL>
    <DeployIisAppPath>TMQ4</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
    <EnableMSDeployBackup>False</EnableMSDeployBackup>
    <UserName>10011531</UserName>
    <_SavePWD>False</_SavePWD>
    <AllowUntrustedCertificate>True</AllowUntrustedCertificate>
    <SelfContained>true</SelfContained>
    <_IsPortable>false</_IsPortable>
  </PropertyGroup>
</Project>

The profile.pubxml was created by visual studio with publication gui config.

When I add item

<UseAppHost>true</UseAppHost>

to PropertyGroup, It was fine.

1、When was it be introduced?

2、Who can show detail about UseAppHost ?

3、Is it conflict with SelfContained, I think SelfContained Setting is enough?

Most helpful comment

I think I see what's happening here. The reason you do not observe the problem when you specify -r win-x64 to dotnet publish is that the .NET Core SDK defaults both SelfContained and UseAppHost to true when it sees a non-empty RuntimeIdentifier. When the properties from the publish profile are applied, SelfContained is already true and UseAppHost remains true, so there is no error.

However, when you publish without specifying -r win-x64, the .NET Core SDK defaults SelfContained and UseAppHost to false because RuntimeIdentifier is empty. Your publish profile flips SelfContained to true, while UseAppHost remains false. The .NET Core SDK later notices this during publishing and errors.

This is an unfortunate regression that did not take into account users that would be setting SelfContained to true in a publish profile.

The best workaround for you is to also set UseAppHost to true in your publish profile. This property, which was introduced in the 2.1.400 version of the .NET Core SDK, controls whether or not a native executable will be created for your deployment, which is required for self-contained deployments.

I'll see if there's a way we can fix this, such as checking to see if UseAppHost, when defaulted, should be defaulted again as a result of SelfContained changing in a publish profile.

All 14 comments

You don't need to set UseAppHost.

cc @peterhuene

Hi @TimRowe. The SDK should be defaulting UseAppHost to true if SelfContained is true. Was there any place that was explicitly setting UseAppHost to false?

If possible, could you share a repro project or repro steps for me to take a look at? Thank you!

@peterhuene I think I found the problem.

At first, my publish cmd is like below
C:\Program Files (x86)\Jenkins\workspace\TMQ4.DEV>dotnet publish Tmq.sln /p:WebP ublishMethod=MSDeploy /p:Configuration=Release /p:PublishProfile=WebDeployProfile

Now I add the -r win-x64, It's fine without <UseAppHost>true</UseAppHost>

But I am confused, because <RuntimeIdentifier> is set in the Profile.pubxml.

I think I see what's happening here. The reason you do not observe the problem when you specify -r win-x64 to dotnet publish is that the .NET Core SDK defaults both SelfContained and UseAppHost to true when it sees a non-empty RuntimeIdentifier. When the properties from the publish profile are applied, SelfContained is already true and UseAppHost remains true, so there is no error.

However, when you publish without specifying -r win-x64, the .NET Core SDK defaults SelfContained and UseAppHost to false because RuntimeIdentifier is empty. Your publish profile flips SelfContained to true, while UseAppHost remains false. The .NET Core SDK later notices this during publishing and errors.

This is an unfortunate regression that did not take into account users that would be setting SelfContained to true in a publish profile.

The best workaround for you is to also set UseAppHost to true in your publish profile. This property, which was introduced in the 2.1.400 version of the .NET Core SDK, controls whether or not a native executable will be created for your deployment, which is required for self-contained deployments.

I'll see if there's a way we can fix this, such as checking to see if UseAppHost, when defaulted, should be defaulted again as a result of SelfContained changing in a publish profile.

@peterhuene Thanks for your detailed analysis.
But why <RuntimeIdentifier> in Profile.pubxml can't work?
I think these property value setting priority is like below.

RuntimeIndentifier(DotNet Cli)> RuntimeIndentifier(Profile.pubxml ) > SelfContained( DotNet Cli ) > SelfContained( Profile.pubxml ) > UseAppHost( DotNet Cli ) > UseAppHost( Profile.pubxml )

Hi @TimRowe. It's about order of evaluation and having a global property set. When you specify -r win-x64, it sets RuntimeIdentifier as a global property, which overrides anything set in a project file or publish profile. So this is what's happening:

-r win-x64 sets RuntimeIdentifier globally before any properties in the .NET Core SDK are evaluated. The .NET Core SDK sees RuntimeIdentifier set, so it defaults SelfContained and UseAppHost to true. When the publishing profile properties are evaluated, RuntimeIdentifier is set as a global property so it cannot change, and SelfContained is already true, so it has no effect. When the targets run during publishing, the .NET Core SDK sees both SelfContained and UseAppHost set to true, so it is happy.

Contrast this to not passing -r win-x64: RuntimeIdentifier is not set globally, so the .NET Core SDK defaults SelfContained and UseAppHost to not set. When the publishing profile properties are evaluated, RuntimeIdentifier changes to win-x64 and SelfContained changes to true. When the targets run during publishing, the .NET Core SDK sees SelfContained set to true, but UseAppHost is not set, thus it errors.

If the publishing profile also sets UseAppHost to true, then it should work regardless of whether or not -r win-x64 is passed to dotnet publish. I hope that makes sense.

@peterhuene thansk, it's clear.
but without -r win-x64 it's output without .exe although UseAppHost and RuntimeIdentifier has been set in .pubxml. Why?

That's unexpected, since the publish items (including the executable apphost) should not be added to the evaluation until after the publish profile has been evaluated (i.e. when the publish targets are actually running), otherwise I would expect setting SelfContained to true in the publish profile without specifying -r win-x64 to not have any affect even before the UseAppHost property was introduced.

Are you seeing a self-contained deployment, but just the .exe is missing? That is to say, the rest of the framework files are present?

I'll see what I can figure out.

@peterhuene Here is the sample project.
WebApplication6.zip
My publish command is
dotnet publish WebApplication6.csproj /p:WebPublishMethod=FileSystem /p:Configuration=Release /p:PublishProfile=FolderProfile

Hi @TimRowe,

Thanks for the repro project. I can confirm the behavior you're seeing, although it does not appear to be a regression related to the UseAppHost change itself, as that was introduced in 2.1.400 and I can reproduce the behavior with the older 2.1.302 SDK.

I am seeing apphost.exe appear, but it has not been renamed, nor does it seem to have had the path to the application embedded.

I think the publish profile is being applied "too late" for logic in the SDK to respect it properly.

A workaround for now is to pass the runtime to the publish command (i.e. -r win-x64), which should cause the project to publish self-contained with an apphost, as expected. Because of the above behavior, my previously suggested workaround of specifying UseAppHost in the publish profile will not work.

I'll investigate the root cause of that behavior. Thanks again for reporting this to us!

@peterhuene thanks,This is what I should do. I hope the next version will optimize these problems.

@peterhuene Is there a solution when using msbuild.exe, or is dotnet publish the only way to make it work?

@HolisticDeveloper you should be able to work around this similarly with msbuild using /p:RuntimeIdentifier=<rid>, which is effectively what the --runtime option does for dotnet publish.

This should now be fixed with the upcoming preview of the .NET Core 3.0 SDK.

Fixed in #3183.

Was this page helpful?
0 / 5 - 0 ratings