Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Use update-index to regenerate it:
|----|-----|------|
| | [Add ability to embed install location options in apphost](proposed/apphost-embed-install-location.md) | |
| | [Annotating members as `unsafe`](proposed/caller-unsafe.md) | |
| | [Launching .NET Apps](proposed/net-app-launch.md) | |
| | [Rate limits](proposed/rate-limit.md) | [John Luo](https://github.com/juntaoluo), [Sourabh Shirhatti](https://github.com/shirhatti) |
| | [Readonly references in C# and IL verification.](proposed/verifiable-ref-readonly.md) | |
| | [Ref returns in C# and IL verification.](proposed/verifiable-ref-returns.md) | |
Expand Down
30 changes: 30 additions & 0 deletions proposed/net-app-launch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

# Launching .NET Apps

This document covers recommendations for launching .NET applications. There are two main form factors for .NET app deployment:

* Self-contained
* Framework-dependent

Self-contained apps are the simplest. They have a platform-native entry executable and contain all files needed for their execution. They match the native platform standard for launching executables. They do not support configuration beyond the native platform convention.

Framework-dependent apps do not contain a runtime themselves and instead need a separate runtime located somewhere on the machine. This is the most complicated scenario with the most configuration options.

## Framework-dependent apps

There are two ways to run framework-dependent apps: through the "apphost" launcher and via `dotnet app.dll`. Whenever possible, it's recommended to use the apphost. There are a number of advantages to using the apphost:

* Executables appear like standard native platform executables.
* Executable names are preserved in the process names, meaning apps can be easily recognized based on their names.
* Because the apphost is a native binary, native assets like manifests can be attached to them.
* Apphost has available [low-level security mitigations](accepted/2021/runtime-security-mitigations.md) applied by default that makes it more secure. Mitigations applied to `dotnet` are the lowest common denominator of all supported runtimes.

The apphost will generally use a global install of the .NET runtime, where install locations are defined by [install locations](accepted/2021/install-location-per-architecture.md).

The .NET runtime path can also be customized on a per-execution basis. The DOTNET_ROOT environment variable can be used to point to the custom location. Details for all DOTNET_ROOT configuration can also be found in [install locations](accepted/2021/install-location-per-architecture.md).

In general, the best practice for using `DOTNET_ROOT` to set the runtime location for an app is to:

1. Clear DOTNET_ROOT environment variables first, meaning all environment variables that start with the text `DOTNET_ROOT`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd link to https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_root-dotnet_rootx86-dotnet_root_x86-dotnet_root_x64 since I don't think it's widely known that there are multiple variations of DOTNET_ROOT

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. That adds context to why this needs to be done.

2. Set `DOTNET_ROOT`, and only `DOTNET_ROOT`, to the target path.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth mentioning that if you are a tool launched by dotnet or MSBuild (since 18.x), you can determine the path from DOTNET_HOST_PATH (documented at https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_host_path)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: that DOTNET_HOST_PATH doc is also being updated: dotnet/docs#49422

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No: DOTNET_HOST_PATH is an SDK-only property. You can only rely on it if you were launched from the SDK. Since only things which ship in the SDK can count on being launched by the SDK, this should not be a public guarantee. It is an implementation detail for SDK apps.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I know that's SDK only property, I was just thinking it's a common scenario and might be good mentioning it here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s not a common scenario though: it’s only for Microsoft apps that ship in the sdk, or maybe for tools that people launch with MSBuild. One of those is internal-only and the other is only relevant for people who don’t have .NET globally installed.

3. Execute the target apphost.