dotnet-file-based-apps

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

dotnet-file-based-apps

dotnet-file-based-apps

.NET 10 SDK file-based apps let you build, run, and publish C# applications from a single
.cs
file without creating a
.csproj
project file. The SDK auto-generates project configuration from
#:
directives embedded in the source file. This feature targets scripts, utilities, and small applications where traditional project scaffolding is unnecessary.
This is NOT file I/O. For FileStream, RandomAccess, FileSystemWatcher, and path handling, see [skill:dotnet-file-io].
Prerequisites: Requires .NET 10 SDK or later. Run [skill:dotnet-version-detection] to confirm SDK version.
Cross-references: [skill:dotnet-version-detection] for SDK version gating, [skill:dotnet-project-analysis] for project-based analysis (file-based apps have no
.csproj
), [skill:dotnet-scaffold-project] for csproj-based project scaffolding.
.NET 10 SDK 基于文件的应用允许你从单个
.cs
文件构建、运行和发布C#应用,无需创建
.csproj
项目文件。SDK会从嵌入在源文件中的
#:
指令自动生成项目配置。该功能面向脚本、实用工具和小型应用,这些场景下传统的项目脚手架并非必需。
注意:这不是文件I/O操作。有关FileStream、RandomAccess、FileSystemWatcher和路径处理的内容,请查看[skill:dotnet-file-io]。
前置要求: 需要.NET 10 SDK或更高版本。运行[skill:dotnet-version-detection]确认SDK版本。
交叉参考:版本检查请见[skill:dotnet-version-detection],基于项目的分析请见[skill:dotnet-project-analysis](基于文件的应用没有
.csproj
),基于csproj的项目脚手架请见[skill:dotnet-scaffold-project]。

Scope

适用范围

  • #: directives (package, sdk, property, project)
  • CLI commands for file-based apps (dotnet run, dotnet publish)
  • Migration from file-based to .csproj project format
  • #:指令(package、sdk、property、project)
  • 基于文件应用的CLI命令(dotnet run、dotnet publish)
  • 从基于文件格式迁移到.csproj项目格式

Out of scope

不适用范围

  • File I/O (FileStream, RandomAccess, paths) -- see [skill:dotnet-file-io]
  • Project-based .csproj scaffolding -- see [skill:dotnet-scaffold-project]
  • Solution structure analysis -- see [skill:dotnet-project-analysis]

  • 文件I/O(FileStream、RandomAccess、路径)——请查看[skill:dotnet-file-io]
  • 基于项目的.csproj脚手架——请查看[skill:dotnet-scaffold-project]
  • 解决方案结构分析——请查看[skill:dotnet-project-analysis]

Directives Overview

指令概述

File-based apps use
#:
directives to configure the build. Directives are SDK-level instructions, not C# syntax. They must appear at the top of the
.cs
file, before any C# code.
Four directive types are supported:
DirectivePurposeExample
#:package
Add a NuGet package reference
#:package Serilog@3.1.1
#:sdk
Set the SDK (default:
Microsoft.NET.Sdk
)
#:sdk Microsoft.NET.Sdk.Web
#:property
Set an MSBuild property
#:property PublishAot=false
#:project
Reference another project file
#:project ../Lib/Lib.csproj

基于文件的应用使用
#:
指令配置构建。这些指令是SDK级别的说明,而非C#语法。它们必须出现在
.cs
文件的顶部,位于任何C#代码之前。
支持四种指令类型:
指令用途示例
#:package
添加NuGet包引用
#:package Serilog@3.1.1
#:sdk
设置SDK(默认值:
Microsoft.NET.Sdk
#:sdk Microsoft.NET.Sdk.Web
#:property
设置MSBuild属性
#:property PublishAot=false
#:project
引用另一个项目文件
#:project ../Lib/Lib.csproj

#:package
Directive

#:package
指令

Adds a NuGet package reference. Specify the package name, optionally followed by
@version
.
csharp
#:package Newtonsoft.Json
#:package Serilog@3.1.1
#:package Spectre.Console@*
Version behavior:
  • @version
    -- pins to a specific version
  • @*
    -- uses the latest stable version (NuGet floating version)
  • No version -- only works when Central Package Management (CPM) is configured with a
    Directory.Packages.props
    file; otherwise, specify a version explicitly or use
    @*

添加NuGet包引用。指定包名称,可选择性跟随
@version
版本号。
csharp
#:package Newtonsoft.Json
#:package Serilog@3.1.1
#:package Spectre.Console@*
版本行为:
  • @version
    ——固定到特定版本
  • @*
    ——使用最新稳定版本(NuGet浮动版本)
  • 无版本 ——仅在通过
    Directory.Packages.props
    配置了中央包管理(CPM)时生效;否则,需要显式指定版本或使用
    @*

#:sdk
Directive

#:sdk
指令

Specifies which SDK to use. Defaults to
Microsoft.NET.Sdk
if omitted.
csharp
#:sdk Microsoft.NET.Sdk.Web
csharp
#:sdk Aspire.AppHost.Sdk@9.2.0
Use this directive to access SDK-specific features. For example,
Microsoft.NET.Sdk.Web
enables ASP.NET Core features and automatically includes
*.json
configuration files in the build.

指定要使用的SDK。如果省略,默认值为
Microsoft.NET.Sdk
csharp
#:sdk Microsoft.NET.Sdk.Web
csharp
#:sdk Aspire.AppHost.Sdk@9.2.0
使用此指令访问特定SDK的功能。例如,
Microsoft.NET.Sdk.Web
启用ASP.NET Core功能,并自动在构建中包含
*.json
配置文件。

#:property
Directive

#:property
指令

Sets an MSBuild property value. Use this to customize build behavior.
csharp
#:property TargetFramework=net10.0
#:property PublishAot=false
设置MSBuild属性值。用于自定义构建行为。
csharp
#:property TargetFramework=net10.0
#:property PublishAot=false

Conditional Property Values

条件属性值

Property directives support MSBuild property functions and expressions for conditional configuration.
Environment variables with defaults:
csharp
#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))
Conditional expressions:
csharp
#:property EnableLogging=$([System.Convert]::ToBoolean($([MSBuild]::ValueOrDefault('$(ENABLE_LOGGING)', 'true'))))

属性指令支持MSBuild属性函数和表达式,用于条件配置。
带默认值的环境变量:
csharp
#:property LogLevel=$([MSBuild]::ValueOrDefault('$(LOG_LEVEL)', 'Information'))
条件表达式:
csharp
#:property EnableLogging=$([System.Convert]::ToBoolean($([MSBuild]::ValueOrDefault('$(ENABLE_LOGGING)', 'true'))))

#:project
Directive

#:project
指令

References another project file or directory containing a project file. Use this to share code between a file-based app and a traditional project.
csharp
#:project ../SharedLibrary/SharedLibrary.csproj
The referenced project is built and linked as a project reference, just like
<ProjectReference>
in a
.csproj
.

引用另一个项目文件或包含项目文件的目录。用于在基于文件的应用和传统项目之间共享代码。
csharp
#:project ../SharedLibrary/SharedLibrary.csproj
被引用的项目会被构建并作为项目引用链接,就像
.csproj
中的
<ProjectReference>
一样。

CLI Commands

CLI命令

The .NET CLI supports file-based apps through familiar commands.
.NET CLI通过常用命令支持基于文件的应用。

Run

运行

bash
undefined
bash
undefined

Preferred: pass file directly

推荐方式:直接传递文件

dotnet run app.cs
dotnet run app.cs

Explicit --file option

显式--file选项

dotnet run --file app.cs
dotnet run --file app.cs

Shorthand (no 'run' subcommand)

简写形式(无需'run'子命令)

dotnet app.cs
dotnet app.cs

Pass arguments after --

在--之后传递参数

dotnet run app.cs -- arg1 arg2

When a `.csproj` exists in the current directory, `dotnet run app.cs` (without `--file`) runs the project and passes `app.cs` as an argument to preserve backward compatibility. Use `dotnet run --file app.cs` to force file-based execution.
dotnet run app.cs -- arg1 arg2

当当前目录中存在`.csproj`时,`dotnet run app.cs`(不带`--file`)会运行项目并将`app.cs`作为参数传递,以保持向后兼容性。使用`dotnet run --file app.cs`强制以基于文件的方式执行。

Pipe from stdin

从标准输入管道传入

bash
echo 'Console.WriteLine("hello");' | dotnet run -
The
-
argument reads C# code from standard input. Useful for quick testing and shell script integration.
bash
echo 'Console.WriteLine("hello");' | dotnet run -
-
参数表示从标准输入读取C#代码。适用于快速测试和shell脚本集成。

Build

构建

bash
dotnet build app.cs
Build output goes to a cached location under the system temp directory by default. Override with
--output
or
#:property OutputPath=./output
.
bash
dotnet build app.cs
默认情况下,构建输出会进入系统临时目录下的缓存位置。可通过
--output
#:property OutputPath=./output
覆盖。

Clean

清理

bash
undefined
bash
undefined

Clean build artifacts for a specific file

清理特定文件的构建产物

dotnet clean app.cs
dotnet clean app.cs

Clean all file-based app caches in the current directory

清理当前目录中所有基于文件应用的缓存

dotnet clean file-based-apps
dotnet clean file-based-apps

Clean caches unused for N days (default: 30)

清理N天未使用的缓存(默认:30天)

dotnet clean file-based-apps --days 7
undefined
dotnet clean file-based-apps --days 7
undefined

Publish

发布

bash
dotnet publish app.cs
File-based apps enable native AOT by default. The output goes to an
artifacts
directory next to the
.cs
file. Disable AOT with
#:property PublishAot=false
.
bash
dotnet publish app.cs
基于文件的应用默认启用原生AOT。输出会进入
.cs
文件旁边的
artifacts
目录。可通过
#:property PublishAot=false
禁用AOT。

Pack as .NET Tool

打包为.NET工具

bash
dotnet pack app.cs
File-based apps set
PackAsTool=true
by default. Disable with
#:property PackAsTool=false
.
bash
dotnet pack app.cs
基于文件的应用默认设置
PackAsTool=true
。可通过
#:property PackAsTool=false
禁用。

Restore

还原

bash
dotnet restore app.cs
Restore runs implicitly on build/run. Pass
--no-restore
to
dotnet build
or
dotnet run
to skip it.

bash
dotnet restore app.cs
还原会在构建/运行时自动执行。在
dotnet build
dotnet run
中传递
--no-restore
可跳过还原。

Shell Execution (Unix)

Shell执行(Unix)

Enable direct execution on Unix-like systems with a shebang line.
csharp
#!/usr/bin/env dotnet
#:package Spectre.Console

using Spectre.Console;

AnsiConsole.MarkupLine("[green]Hello, World![/]");
bash
chmod +x app.cs
./app.cs
The file must use
LF
line endings (not
CRLF
) and must not include a BOM.

在类Unix系统中,可通过shebang行启用直接执行。
csharp
#!/usr/bin/env dotnet
#:package Spectre.Console

using Spectre.Console;

AnsiConsole.MarkupLine("[green]Hello, World![/]");
bash
chmod +x app.cs
./app.cs
文件必须使用
LF
换行符(而非
CRLF
),且不能包含BOM。

Launch Profiles

启动配置文件

File-based apps support launch profiles via a flat
[AppName].run.json
file in the same directory as the source file. For
app.cs
, create
app.run.json
:
json
{
  "profiles": {
    "https": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
Select a profile with
--launch-profile
:
bash
dotnet run app.cs --launch-profile https
If both
app.run.json
and
Properties/launchSettings.json
exist, the traditional location takes priority.

基于文件的应用支持通过源文件同一目录下的扁平
[AppName].run.json
文件设置启动配置。对于
app.cs
,创建
app.run.json
json
{
  "profiles": {
    "https": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
使用
--launch-profile
选择配置:
bash
dotnet run app.cs --launch-profile https
如果同时存在
app.run.json
Properties/launchSettings.json
,传统位置的文件优先级更高。

User Secrets

用户机密

File-based apps generate a stable user secrets ID from the file's full path.
bash
dotnet user-secrets set "ApiKey" "your-secret-value" --file app.cs
dotnet user-secrets list --file app.cs

基于文件的应用会根据文件的完整路径生成稳定的用户机密ID。
bash
dotnet user-secrets set "ApiKey" "your-secret-value" --file app.cs
dotnet user-secrets list --file app.cs

Implicit Build Files

隐式构建文件

File-based apps respect MSBuild and NuGet configuration files in the same or parent directories:
  • Directory.Build.props
    -- inherited MSBuild properties
  • Directory.Build.targets
    -- inherited MSBuild targets
  • Directory.Packages.props
    -- Central Package Management versions
  • nuget.config
    -- NuGet package source configuration
  • global.json
    -- SDK version pinning
Be mindful of these files when placing file-based apps in a repository that also contains traditional projects. Inherited properties may cause unexpected build behavior.

基于文件的应用会遵循同一目录或父目录中的MSBuild和NuGet配置文件:
  • Directory.Build.props
    ——继承的MSBuild属性
  • Directory.Build.targets
    ——继承的MSBuild目标
  • Directory.Packages.props
    ——中央包管理版本
  • nuget.config
    ——NuGet包源配置
  • global.json
    ——SDK版本固定
当将基于文件的应用放置在同时包含传统项目的仓库中时,请注意这些文件。继承的属性可能导致意外的构建行为。

Build Caching

构建缓存

The SDK caches build outputs based on source content, directives, SDK version, and implicit build files. Caching improves repeated
dotnet run
performance.
Known caching pitfalls:
  • Changes to implicit build files (
    Directory.Build.props
    , etc.) may not trigger rebuilds
  • Moving files to different directories does not invalidate the cache
  • Concurrent execution of the same file-based app can cause build contention errors -- build first with
    dotnet build app.cs
    , then run multiple instances with
    dotnet run app.cs --no-build
Clear the cache with
dotnet clean app.cs
or
dotnet clean file-based-apps
.

SDK会根据源内容、指令、SDK版本和隐式构建文件缓存构建输出。缓存可提升重复
dotnet run
的性能。
已知的缓存陷阱:
  • 修改隐式构建文件(如
    Directory.Build.props
    )可能不会触发重建
  • 将文件移动到不同目录不会使缓存失效
  • 并发执行同一个基于文件的应用可能导致构建冲突错误——先使用
    dotnet build app.cs
    构建,然后使用
    dotnet run app.cs --no-build
    运行多个实例
可使用
dotnet clean app.cs
dotnet clean file-based-apps
清除缓存。

Folder Layout

目录布局

Do not place file-based apps inside a
.csproj
project's directory tree. The project's implicit build configuration will interfere.
undefined
请勿将基于文件的应用放置在
.csproj
项目的目录树中。项目的隐式构建配置会产生干扰。
undefined

Recommended layout

推荐布局

repo/ src/ MyProject/ MyProject.csproj Program.cs scripts/ # Separate directory for file-based apps utility.cs tool.cs

---
repo/ src/ MyProject/ MyProject.csproj Program.cs scripts/ # 单独的目录用于存放基于文件的应用 utility.cs tool.cs

---

Migration: File-Based to Project-Based

迁移:从基于文件到基于项目

When a file-based app outgrows a single file, convert to a traditional project.
当基于文件的应用超出单个文件的范围时,可转换为传统项目。

Automatic Conversion

自动转换

bash
dotnet project convert app.cs
This creates a new directory named after the app, containing:
  • A
    .csproj
    with equivalent SDK, properties, and package references derived from the
    #:
    directives
  • A copy of the
    .cs
    file with
    #:
    directives removed
The original
.cs
file is left untouched.
bash
dotnet project convert app.cs
这会创建一个以应用命名的新目录,包含:
  • 一个
    .csproj
    文件,包含从
    #:
    指令派生的等效SDK、属性和包引用
  • 一份移除了
    #:
    指令的
    .cs
    文件副本
原始
.cs
文件会被保留。

When to Convert

转换时机

Convert to a project-based app when:
  • Multiple source files are needed
  • Complex MSBuild customization is required beyond what
    #:property
    supports
  • The app needs
    dotnet test
    with a test framework
  • The app needs integration with CI/CD workflows that expect a
    .csproj
  • Team members need IDE project support (Solution Explorer, etc.)

当出现以下情况时,转换为基于项目的应用:
  • 需要多个源文件
  • 需要
    #:property
    之外的复杂MSBuild自定义
  • 应用需要使用
    dotnet test
    和测试框架
  • 应用需要与期望
    .csproj
    的CI/CD工作流集成
  • 团队成员需要IDE项目支持(如解决方案资源管理器等)

Default Behaviors

默认行为

File-based apps differ from project-based apps in several default settings:
SettingFile-based defaultProject-based default
Native AOT (
PublishAot
)
true
false
Pack as tool (
PackAsTool
)
true
false
Build output locationSystem temp directory
bin/
in project directory
Publish output location
artifacts/
next to
.cs
file
bin/<config>/<tfm>/publish/

基于文件的应用与基于项目的应用在一些默认设置上有所不同:
设置基于文件的默认值基于项目的默认值
原生AOT(
PublishAot
true
false
打包为工具(
PackAsTool
true
false
构建输出位置系统临时目录项目目录中的
bin/
发布输出位置
.cs
文件旁的
artifacts/
bin/<config>/<tfm>/publish/

Agent Gotchas

注意事项

  1. Do not confuse file-based apps with file I/O --
    dotnet-file-based-apps
    covers running C# without a project file (
    .NET 10 SDK feature
    ). For FileStream, RandomAccess, and path handling, use [skill:dotnet-file-io].
  2. Do not use
    #:
    directives after C# code
    -- all directives must appear at the top of the file, before any C# statements,
    using
    directives, or namespace declarations. The SDK ignores directives placed later in the file.
  3. Do not omit package versions without CPM --
    #:package SomePackage
    without a version only works when Central Package Management is configured via
    Directory.Packages.props
    . Without CPM, use
    #:package SomePackage@1.0.0
    or
    #:package SomePackage@*
    .
  4. Do not assume
    dotnet build
    and
    dotnet test
    work the same
    --
    dotnet build app.cs
    compiles via a virtual project, but
    dotnet test
    does not apply to file-based apps. Convert to a project for test framework support.
  5. Do not place file-based apps inside a
    .csproj
    project directory
    -- the project's implicit build files (
    Directory.Build.props
    , etc.) will affect the file-based app, causing unexpected behavior. Use a separate directory.
  6. Do not run concurrent instances without pre-building -- parallel execution of the same file-based app causes build output contention. Build first with
    dotnet build app.cs
    , then run instances with
    dotnet run app.cs --no-build
    .
  7. Do not forget backward compatibility -- when a
    .csproj
    exists in the current directory,
    dotnet run app.cs
    passes
    app.cs
    as an argument to the project rather than running it as a file-based app. Use
    dotnet run --file app.cs
    to force file-based execution.
  8. Do not use
    CRLF
    line endings with shebang
    -- Unix shebang execution requires
    LF
    line endings and no BOM. Files with
    CRLF
    will fail with
    /usr/bin/env: 'dotnet\r': No such file or directory
    .

  1. 不要将基于文件的应用与文件I/O混淆——
    dotnet-file-based-apps
    涵盖无需项目文件即可运行C#的功能(.NET 10 SDK特性)。有关FileStream、RandomAccess和路径处理的内容,请使用[skill:dotnet-file-io]。
  2. 不要在C#代码之后使用
    #:
    指令
    ——所有指令必须出现在文件顶部,位于任何C#语句、
    using
    指令或命名空间声明之前。SDK会忽略文件中后续位置的指令。
  3. 不要在未配置CPM的情况下省略包版本——不带版本的
    #:package SomePackage
    仅在通过
    Directory.Packages.props
    配置了中央包管理时生效。未配置CPM时,请使用
    #:package SomePackage@1.0.0
    #:package SomePackage@*
  4. 不要假设
    dotnet build
    dotnet test
    的工作方式相同
    ——
    dotnet build app.cs
    通过虚拟项目编译,但
    dotnet test
    不适用于基于文件的应用。转换为项目以获得测试框架支持。
  5. 不要将基于文件的应用放置在
    .csproj
    项目目录中
    ——项目的隐式构建文件(如
    Directory.Build.props
    )会影响基于文件的应用,导致意外行为。请使用单独的目录。
  6. 不要在未预构建的情况下运行并发实例——同一个基于文件的应用的并行执行会导致构建输出冲突。先使用
    dotnet build app.cs
    构建,然后使用
    dotnet run app.cs --no-build
    运行实例。
  7. 不要忘记向后兼容性——当当前目录中存在
    .csproj
    时,
    dotnet run app.cs
    会将
    app.cs
    作为参数传递给项目,而非以基于文件的方式运行。请使用
    dotnet run --file app.cs
    强制以基于文件的方式执行。
  8. 不要在shebang中使用
    CRLF
    换行符
    ——Unix shebang执行需要
    LF
    换行符且无BOM。带有
    CRLF
    的文件会失败,错误信息为
    /usr/bin/env: 'dotnet\r': No such file or directory

References

参考资料