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
+36-21Lines changed: 36 additions & 21 deletions
Original file line number
Diff line number
Diff line change
@@ -47,7 +47,8 @@ The command takes a path which can be either
47
47
## Target path
48
48
49
49
The path passed to `dotnet run ./some/path.cs` is called *the target path*.
50
-
The target path must be a file which has the `.cs` file extension.
50
+
The target path must be a file which either has the `.cs` file extension,
51
+
or a file whose contents start with `#!`.
51
52
*The target directory* is the directory of the target file.
52
53
53
54
## Integration into the existing `dotnet run` command
@@ -57,13 +58,23 @@ specifically `file.cs` is passed as the first command-line argument to the targe
57
58
We preserve this behavior to avoid a breaking change.
58
59
The file-based build and run kicks in only when:
59
60
- a project file cannot be found (in the current directory or via the `--project` option), and
60
-
- if the target file exists and has the `.cs` file extension.
61
+
- if the target file exists, and has the `.cs` file extension or contents that start with `#!`.
61
62
62
63
File-based programs are processed by `dotnet run` equivalently to project-based programs unless specified otherwise in this document.
63
64
For example, the remaining command-line arguments after the first argument (the target path) are passed through to the target app
64
65
(except for the arguments recognized by `dotnet run` unless they are after the `--` separator)
65
66
and working directory is not changed (e.g., `cd /x/ && dotnet run /y/file.cs` runs the program in directory `/x/`).
66
67
68
+
`dotnet path.cs` is a shortcut for `dotnet run path.cs` provided that `path.cs` is a valid [target path](#target-path).
69
+
70
+
### Other commands
71
+
72
+
Commands `dotnet restore file.cs` and `dotnet build file.cs` are needed for IDE support and hence work for file-based programs.
73
+
74
+
Command `dotnet publish file.cs` is also supported for file-based programs.
75
+
Note that file-based apps have implicitly set `PublishAot=true`, so publishing uses Native AOT (and building reports AOT warnings).
76
+
To opt out, use `#:property PublishAot=false` directive in your `.cs` file.
77
+
67
78
## Entry points
68
79
69
80
If a file is given to `dotnet run`, it has to be an *entry-point file*, otherwise an error is reported.
@@ -86,6 +97,10 @@ other files in the target directory or its subdirectories are included in the co
86
97
For example, other `.cs` files but also `.resx` (embedded resources).
87
98
Similarly, implicit build files like `Directory.Build.props` or `Directory.Packages.props` are used during the build.
88
99
100
+
> [!CAUTION]
101
+
> Multi-file support is postponed for .NET 11.
102
+
> In .NET 10, only the single file passed as the command-line argument to `dotnet run` is part of the compilation.
103
+
89
104
### Nested files
90
105
91
106
If there are nested project files like
@@ -148,26 +163,32 @@ They are not cleaned immediately because they can be re-used on subsequent runs
148
163
149
164
It is possible to specify some project metadata via *file-level directives*
150
165
which are [ignored][ignored-directives] by the C# language but recognized by the SDK CLI.
151
-
Directives `sdk`, `package`, and `property` are translated into `<Project Sdk="...">`, `<PackageReference>`, and `<Property>` project elements, respectively.
166
+
Directives `sdk`, `package`, `property`, and `project` are translated into
167
+
`<Project Sdk="...">`, `<PackageReference>`, `<PropertyGroup>`, and `<ProjectReference>` project elements, respectively.
152
168
Other directives result in an error, reserving them for future use.
153
169
154
170
```cs
155
171
#:sdk Microsoft.NET.Sdk.Web
156
-
#:property TargetFrameworknet11.0
157
-
#:property LangVersionpreview
172
+
#:property TargetFramework=net11.0
173
+
#:property LangVersion=preview
158
174
#:package System.CommandLine@2.0.0-*
175
+
#:project ../MyLibrary
159
176
```
160
177
161
-
The value must be separated from the name of the directive by white space (`@` is additionally allowed separator for the package directive)
178
+
The value must be separated from the kind (`package`/`sdk`/`property`) of the directive by whitespace
162
179
and any leading and trailing white space is not considered part of the value.
163
-
Any value can optionally have two parts separated by a space (more whitespace characters could be allowed in the future).
180
+
Any value can optionally have two parts separated by `@` in case of `package`/`sdk` or `=` in case of `property`
181
+
and whitespace is trimmed from the two parts around the separator.
164
182
The value of the first `#:sdk` is injected into `<Project Sdk="{0}">` with the separator (if any) replaced with `/`,
165
183
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).
166
184
It is an error if the first part (name) is empty (the version is allowed to be empty, but that results in empty `Version=""`).
167
185
The value of `#:property` is split by the separator and injected as `<{0}>{1}</{0}>` in a `<PropertyGroup>`.
168
186
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.
169
187
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>`.
170
188
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=""`).
189
+
The value of `#:project` is injected as `<ProjectReference Include="{0}" />` in an `<ItemGroup>`.
190
+
If the value points to an existing directory, a project file is found inside that directory and its path is used instead
191
+
(because `ProjectReference` items don't support directory paths).
171
192
172
193
Because these directives are limited by the C# language to only appear before the first "C# token" and any `#if`,
173
194
dotnet CLI can look for them via a regex or Roslyn lexer without any knowledge of defined conditional symbols
@@ -280,31 +301,26 @@ Also, `InternalsVisibleTo` needs to be added into a C# file as an attribute, or
280
301
281
302
### Shebang support
282
303
283
-
It might be beneficial to also ship `dotnet-run` binary
284
-
(or `dotnet-run-file` that would only work with file-based programs, not project-based ones, perhaps simply named `cs`)
285
-
because some shells do not support multiple command-line arguments in the shebang
304
+
Some shells do not support multiple command-line arguments in the shebang
286
305
which is needed if one wants to use `/usr/bin/env` to find the `dotnet` executable
287
-
(although `-S` argument can be sometimes used to enable multiple argument support):
306
+
(although `-S` argument can be sometimes used to enable multiple argument support),
307
+
so `dotnet file.cs` instead of `dotnet run file.cs` should be used in shebangs:
288
308
289
309
```cs
290
310
#!/usr/bin/env dotnet run
291
311
// ^ Might not work in all shells. "dotnet run" might be passed as a single argument to "env".
292
312
```
293
313
```cs
294
-
#!/usr/bin/env dotnet-run
314
+
#!/usr/bin/env dotnet
295
315
// ^ Should work in all shells.
296
316
```
297
317
```cs
298
318
#!/usr/bin/env -S dotnet run
299
-
// ^ Workaround in some shells.
319
+
// ^ Works in some shells.
300
320
```
301
321
302
-
We could also consider making `dotnet file.cs` work because `dotnet file.dll` also works today
303
-
but that would require changes to the native dotnet host.
304
-
305
-
### Other commands
322
+
### Other possible commands
306
323
307
-
Commands `dotnet restore file.cs` and `dotnet build file.cs` are needed for IDE support and hence work for file-based programs.
308
324
We can consider supporting other commands like `dotnet pack`, `dotnet watch`,
309
325
however the primary scenario is `dotnet run` and we might never support additional commands.
310
326
@@ -319,9 +335,8 @@ We could also add `dotnet compile` command that would be the equivalent of `dotn
319
335
e.g., via `dotnet clean --file-based-program <path-to-entry-point>`
320
336
or `dotnet clean --all-file-based-programs`.
321
337
322
-
323
-
Adding package references via `dotnet package add` could be supported for file-based programs as well,
324
-
i.e., the command would add a `#:package` directive to the top of a `.cs` file.
338
+
Adding references via `dotnet package add`/`dotnet reference add` could be supported for file-based programs as well,
339
+
i.e., the command would add a `#:package`/`#:project` directive to the top of a `.cs` file.
0 commit comments