You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: documentation/general/dotnet-run-file.md
+49-15Lines changed: 49 additions & 15 deletions
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,23 @@ The [guiding principle](#guiding-principle) implies that we can think of file-ba
28
28
The implicit project file is the default project that would be created by running `dotnet new console`.
29
29
This means that the behavior of `dotnet run file.cs` can change between SDK versions if the `dotnet new console` template changes.
30
30
31
+
Additionally, the implicit project file has the following customizations:
32
+
33
+
-`PublishAot` is set to `true`, see [`dotnet publish file.cs`](#other-commands) for more details.
34
+
35
+
-[File-level directives](#directives-for-project-metadata) are applied.
36
+
37
+
- The following are virtual only, i.e., not preserved after [converting to a project](#grow-up):
38
+
39
+
-`ArtifactsPath` is set to a [temp directory](#build-outputs).
40
+
41
+
-`RuntimeHostConfigurationOption`s are set for `EntryPointFilePath` and `EntryPointFileDirectoryPath` which can be accessed in the app via `AppContext`:
@@ -60,6 +77,8 @@ The file-based build and run kicks in only when:
60
77
- a project file cannot be found (in the current directory or via the `--project` option), and
61
78
- if the target file exists, and has the `.cs` file extension or contents that start with `#!`.
62
79
80
+
Otherwise, project-based `dotnet run` fallback is used and you might get an error like "Couldn't find a project to run."
81
+
63
82
File-based programs are processed by `dotnet run` equivalently to project-based programs unless specified otherwise in this document.
64
83
For example, the remaining command-line arguments after the first argument (the target path) are passed through to the target app
65
84
(except for the arguments recognized by `dotnet run` unless they are after the `--` separator)
@@ -179,20 +198,28 @@ Other directives result in an error, reserving them for future use.
179
198
#:project ../MyLibrary
180
199
```
181
200
182
-
The value must be separated from the kind (`package`/`sdk`/`property`) of the directive by whitespace
183
-
and any leading and trailing white space is not considered part of the value.
184
-
Any value can optionally have two parts separated by `@` in case of `package`/`sdk` or `=` in case of `property`
185
-
and whitespace is trimmed from the two parts around the separator.
186
-
The value of the first `#:sdk` is injected into `<Project Sdk="{0}">` with the separator (if any) replaced with `/`,
187
-
and the subsequent `#:sdk` directive values are split by the separator and injected as `<Sdk Name="{0}" Version="{1}" />` elements (or without the `Version` attribute if there is no separator).
188
-
It is an error if the first part (name) is empty (the version is allowed to be empty, but that results in empty `Version=""`).
189
-
The value of `#:property` is split by the separator and injected as `<{0}>{1}</{0}>` in a `<PropertyGroup>`.
190
-
It is an error if no separator appears in the value or if the first part (property name) is empty (the property value is allowed to be empty) or contains invalid characters.
191
-
The value of `#:package` is split by the separator and injected as `<PackageReference Include="{0}" Version="{1}">` (or without the `Version` attribute if there is no separator) in an `<ItemGroup>`.
192
-
It is an error if the first part (package name) is empty (the package version is allowed to be empty, but that results in empty `Version=""`).
193
-
The value of `#:project` is injected as `<ProjectReference Include="{0}" />` in an `<ItemGroup>`.
194
-
If the value points to an existing directory, a project file is found inside that directory and its path is used instead
195
-
(because `ProjectReference` items don't support directory paths).
201
+
Each directive has a kind (e.g., `package`), a name (e.g., `System.CommandLine`), a separator (e.g., `@`), and a value (e.g., the package version).
202
+
The value is required for `#:property`, optional for `#:package`/`#:sdk`, and disallowed for `#:project`.
203
+
204
+
The name must be separated from the kind (`package`/`sdk`/`property`) of the directive by whitespace
205
+
and any leading and trailing white space is not considered part of the name and value.
206
+
207
+
The directives are processed as follows:
208
+
209
+
- The name and value of the first `#:sdk` is injected into `<Project Sdk="{0}/{1}">` (or just `<Project Sdk="{0}">` if it has no value),
210
+
and the subsequent `#:sdk` directive names and values are injected as `<Sdk Name="{0}" Version="{1}" />` elements (or without the `Version` attribute if it has no value).
211
+
It is an error if the name is empty (the version is allowed to be empty, but that results in empty `Version=""`).
212
+
213
+
- A `#:property` is injected as `<{0}>{1}</{0}>` in a `<PropertyGroup>`.
214
+
It is an error if property does not have a value or if its name is empty (the value is allowed to be empty) or contains invalid characters.
215
+
216
+
- A `#:package` is injected as `<PackageReference Include="{0}" Version="{1}">` (or without the `Version` attribute if it has no value) in an `<ItemGroup>`.
217
+
It is an error if its name is empty (the value, i.e., package version, is allowed to be empty, but that results in empty `Version=""`).
218
+
219
+
- A `#:project` is injected as `<ProjectReference Include="{0}" />` in an `<ItemGroup>`.
220
+
If the path points to an existing directory, a project file is found inside that directory and its path is used instead
221
+
(because `ProjectReference` items don't support directory paths).
222
+
An error is reported if zero or more than one projects are found in the directory, just like `dotnet reference add` would do.
196
223
197
224
Because these directives are limited by the C# language to only appear before the first "C# token" and any `#if`,
198
225
dotnet CLI can look for them via a regex or Roslyn lexer without any knowledge of defined conditional symbols
@@ -235,7 +262,13 @@ The build is performed using MSBuild APIs on in-memory project files.
235
262
236
263
### Optimizations
237
264
238
-
MSBuild invocation can be skipped in subsequent `dotnet run file.cs` invocations if an up-to-date check detects that inputs didn't change.
265
+
If an up-to-date check detects that inputs didn't change in subsequent `dotnet run file.cs` invocations,
266
+
building is skipped (as if `--no-build` option has been passed).
267
+
The up-to-date check is not 100% precise (e.g., files imported through an implicit build file are not considered).
268
+
It is possible to enforce a full build using `--no-cache` flag or `dotnet build file.cs`.
269
+
Environment variable [`DOTNET_CLI_CONTEXT_VERBOSE=true`][verbose-env] can be used to get more details about caching decisions made by `dotnet run file.cs`.
270
+
271
+
There are multiple optimization levels - skipping build altogether, running just the C# compiler, or running full MSBuild.
239
272
We always need to re-run MSBuild if implicit build files like `Directory.Build.props` change but
240
273
from `.cs` files, the only relevant MSBuild inputs are the `#:` directives,
241
274
hence we can first check the `.cs` file timestamps and for those that have changed, compare the sets of `#:` directives.
@@ -351,6 +384,7 @@ Instead of implicitly including files from the target directory, the importing c
1. Workload is not installed. Try running `dotnet workload restore`. If that does not work, try running `dotnet build -getItem:MissingWorkloadPack` to determine what workload packs are missing. Our workload detection logic could be wrong and you could need a different workload than we list. This call should provide the pack we need and file an issue in the SDK repo with this information.
28
28
_NETSDK1147: To build this project, the following workloads must be installed:_
29
-
2. You installed workloads previously but now your workload templates are missing (Aspire and MAUI templates are installed by the workloads). This could be because your workloads were installed correctly at some point in the past but are now out of sync.
29
+
2. You installed workloads previously but now your workload templates are missing (MAUI templates are installed by the workloads). This could be because your workloads were installed correctly at some point in the past but are now out of sync.
30
30
1. You installed a new band of the SDK. Workloads are installed per band so installing a new SDK could lead to your workloads not working. [Workload versions](https://github.com/dotnet/designs/pull/294) should improve that.
31
31
2. You installed a different workload from the dotnet CLI. We've improved this a few times but it's still possible to install a different workload which updates your workload manifests without updating your workloads. Please file a bug if this happens to you.
32
32
3. You install a new version of Visual Studio that doesn't have worklaods selected. Visual Studio should include all available workloads so make sure to select them in Visual Studio setup.
0 commit comments