build 脚本使用说明(use_build_script.md)
本文档说明 build.bat
/ build_cn.bat
的适用范围、参数用法、在当前工程 D:\MyItems\UdpClientUser\
的实际发布示例、输出结果与注意事项,便于日后参考。
先上脚本,有英文本和中文本,如果有兼容性问题,请优先使用英文版。
bash
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
rem =====================
rem Settings (editable via args; args override defaults)
rem =====================
set CONFIG=Release
set RUNTIME=win-x64
set SELF_CONTAINED=false
rem Usage: build_fail.bat [runtime] [selfContained(true/false)] [config]
if not "%~1"=="" set RUNTIME=%~1
if not "%~2"=="" set SELF_CONTAINED=%~2
if not "%~3"=="" set CONFIG=%~3
rem ---------------------
rem Paths & Project detection
rem ---------------------
set SCRIPT_DIR=%~dp0
set PUBLISH_DIR=%SCRIPT_DIR%publish
set CSPROJ=
pushd "%SCRIPT_DIR%" >nul 2>&1
for %%f in ("*.csproj") do (
if not defined CSPROJ set CSPROJ=%%~nxf
)
if not defined CSPROJ (
rem search subdirs for .csproj
for /r "%SCRIPT_DIR%" %%f in (*.csproj) do (
if not defined CSPROJ set CSPROJ=%%~nxf & set CSPROJ_DIR=%%~dpf
)
if defined CSPROJ_DIR pushd "%CSPROJ_DIR%" >nul 2>&1
)
if not defined CSPROJ (
echo No .csproj found. Place this script in the project folder or specify manually.
echo Current dir: %CD%
dir /b *.csproj
goto :fail
)
set FULL_CSPROJ_PATH=%CD%\%CSPROJ%
where dotnet >nul 2>&1
if errorlevel 1 (
echo dotnet SDK not found. Please install .NET SDK.
goto :fail
)
dotnet --info
echo.
echo Project: %FULL_CSPROJ_PATH%
echo Config: %CONFIG% Runtime: %RUNTIME% SelfContained: %SELF_CONTAINED%
echo.
if not exist "%PUBLISH_DIR%" mkdir "%PUBLISH_DIR%"
echo Cleaning...
dotnet clean "%FULL_CSPROJ_PATH%" -c %CONFIG%
if errorlevel 1 goto :fail
echo.
echo Publishing to: "%PUBLISH_DIR%"
dotnet publish "%FULL_CSPROJ_PATH%" ^
-c %CONFIG% ^
-r %RUNTIME% ^
--self-contained %SELF_CONTAINED% ^
-p:PublishSingleFile=true ^
-p:IncludeNativeLibrariesForSelfExtract=true ^
-o "%PUBLISH_DIR%"
if errorlevel 1 goto :fail
echo.
set APP_EXE=
for %%e in ("%PUBLISH_DIR%\*.exe") do (
if not defined APP_EXE set APP_EXE=%%~nxe
)
echo Done.
if defined APP_EXE (
echo Output EXE: %APP_EXE%
) else (
echo Note: no .exe found in publish; library/non-Windows-ui projects output .dll only.
)
goto :success
:fail
echo.
echo Build/Publish failed; see logs above.
set ERR=1
:success
popd >nul 2>&1
exit /b %ERR%
中文版:
bash
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
rem =====================
rem 构建与发布设置(可通过命令行参数覆盖默认值)
rem =====================
set CONFIG=Release
set RUNTIME=win-x64
set SELF_CONTAINED=false
rem 用法:build_cn.bat [运行时RID] [是否自包含(true/false)] [配置]
rem 示例:
rem build_cn.bat (等同于 win-x64 + 非自包含 + Release)
rem build_cn.bat win-x86 (发布为 32 位)
rem build_cn.bat win-x64 true (自包含单文件,无需安装 .NET 运行时)
rem build_cn.bat win-x64 false Debug
if not "%~1"=="" set RUNTIME=%~1
if not "%~2"=="" set SELF_CONTAINED=%~2
if not "%~3"=="" set CONFIG=%~3
rem ---------------------
rem 路径与项目探测
rem ---------------------
set SCRIPT_DIR=%~dp0
set PUBLISH_DIR=%SCRIPT_DIR%publish
set CSPROJ=
rem 先在当前目录找 .csproj
pushd "%SCRIPT_DIR%" >nul 2>&1
for %%f in ("*.csproj") do (
if not defined CSPROJ set CSPROJ=%%~nxf
)
rem 若未找到,则到子目录继续找
if not defined CSPROJ (
for /r "%SCRIPT_DIR%" %%f in (*.csproj) do (
if not defined CSPROJ set CSPROJ=%%~nxf & set CSPROJ_DIR=%%~dpf
)
if defined CSPROJ_DIR pushd "%CSPROJ_DIR%" >nul 2>&1
)
if not defined CSPROJ (
echo 未找到任何 .csproj 文件,请将脚本放在包含项目文件的目录下,或手动指定。
echo 当前目录:%CD%
dir /b *.csproj
goto :fail
)
set FULL_CSPROJ_PATH=%CD%\%CSPROJ%
rem 校验 .NET SDK 可用性
where dotnet >nul 2>&1
if errorlevel 1 (
echo 未检测到 dotnet SDK,请先安装 .NET SDK。
goto :fail
)
dotnet --info
echo.
echo 检测到项目: %FULL_CSPROJ_PATH%
echo 配置: %CONFIG% 运行时: %RUNTIME% 自包含: %SELF_CONTAINED%
echo.
if not exist "%PUBLISH_DIR%" mkdir "%PUBLISH_DIR%"
echo 清理旧构建...
dotnet clean "%FULL_CSPROJ_PATH%" -c %CONFIG%
if errorlevel 1 goto :fail
echo.
echo 发布到: "%PUBLISH_DIR%"
dotnet publish "%FULL_CSPROJ_PATH%" ^
-c %CONFIG% ^
-r %RUNTIME% ^
--self-contained %SELF_CONTAINED% ^
-p:PublishSingleFile=true ^
-p:IncludeNativeLibrariesForSelfExtract=true ^
-o "%PUBLISH_DIR%"
if errorlevel 1 goto :fail
echo.
set APP_EXE=
for %%e in ("%PUBLISH_DIR%\*.exe") do (
if not defined APP_EXE set APP_EXE=%%~nxe
)
echo 发布完成!
if defined APP_EXE (
echo 生成的可执行文件:%APP_EXE%
) else (
echo 注意:未在 publish 目录发现 .exe;如果是类库或非 Windows 桌面项目,可能只生成 .dll。
)
goto :success
:fail
echo.
echo 构建/发布失败,请查看上方错误信息。
set ERR=1
:success
popd >nul 2>&1
exit /b %ERR%
1. 适用范围
- 适用于 SDK 风格的 .NET 项目(.NET Core/.NET 5+/6+/7+/8+/9+),例如 WinForms、WPF、Console 等可执行项目。
- 支持生成"单文件"应用(SingleFile)。
- 支持"自包含"(Self-contained)或"依赖框架"(Framework-dependent)两种发布模式。
- 脚本可放置在:
- 目标项目根目录(该目录包含
.csproj
),或 - 项目根目录的上一层目录(脚本会自动向下探测首个
.csproj
)。
- 目标项目根目录(该目录包含
不适用或需改造的情况:
- 非 SDK 风格的旧版 .NET Framework 项目(如
TargetFrameworkVersion=v4.x
且.csproj
非 Sdk 格式)。这类项目不支持dotnet publish
的 SingleFile,需要改用 MSBuild 或第三方打包(如 ILMerge、Costura.Fody)。 - 纯类库(Class Library)项目不会生成
.exe
,而是.dll
------这是预期行为。
2. 脚本清单
build.bat
:英文注释版本(UTF-8 无 BOM + CRLF)。build_cn.bat
:中文注释版本(UTF-8 无 BOM + CRLF)。
二者功能一致:
- 自动探测当前/子目录中的第一个
.csproj
作为发布目标。 - 执行
dotnet clean
与dotnet publish
。 - 发布为"单文件",默认输出到同级目录下的
publish/
。
3. 快速开始
在项目目录 D:\MyItems\UdpClientUser\
中打开终端(PowerShell 或 CMD):
-
默认发布(Release +
win-x64
+ 非自包含):build_cn.bat
或:
build.bat
-
指定运行时(RID):
build_cn.bat win-x86
-
自包含发布(无需安装 .NET 运行时):
build_cn.bat win-x64 true
-
指定配置(Debug/Release):
build_cn.bat win-x64 false Debug
参数顺序:[运行时RID] [是否自包含(true/false)] [配置]
常见 RID:win-x64
、win-x86
、win-arm64
。
4. 参数说明
CONFIG
:构建配置,默认Release
。RUNTIME
:运行时标识(RID),默认win-x64
。SELF_CONTAINED
:是否自包含,默认false
。true
:自包含;目标机器无需安装 .NET 运行时,单文件体积更大。false
:依赖框架;目标机器需要安装对应版本的 .NET 运行时,体积较小。
脚本内部固定发布参数:
-p:PublishSingleFile=true
:启用单文件发布。-p:IncludeNativeLibrariesForSelfExtract=true
:包含原生库(避免部分场景缺失依赖)。-o publish/
:输出目录。
5. 以当前工程为例(D:\MyItems\UdpClientUser)
-
工程文件:
D:\MyItems\UdpClientUser\UdpClientUser.WinForms.csproj
-
目标框架:
net6.0-windows
-
运行命令(示例):
build_cn.bat
-
关键日志(典型):
dotnet --info
显示 SDK 与运行时信息。dotnet clean
清理成功。dotnet publish
输出:UdpClientUser.WinForms -> D:\MyItems\UdpClientUser\bin\Release\net6.0-windows\win-x64\UdpClientUser.WinForms.dll
UdpClientUser.WinForms -> D:\MyItems\UdpClientUser\publish\
-
发布产物:
- 目录:
D:\MyItems\UdpClientUser\publish\
- 文件:
UdpClientUser.WinForms.exe
(单文件,可直接运行)
- 目录:
6. 注意事项与常见问题(FAQ)
- 编码/换行:
- 脚本以"UTF-8 无 BOM + CRLF"保存,首行
@echo off
,第二行chcp 65001 >nul
。 - 避免使用 UTF-16(记事本的"Unicode")或仅 LF 换行,否则 CMD 解析可能异常。
- 脚本以"UTF-8 无 BOM + CRLF"保存,首行
- 中文注释:
- 中文注释不会影响执行,但必须保证脚本编码与换行规范;否则可能出现"不是内部或外部命令"的报错。
- 若终端显示中文乱码,建议使用 Windows Terminal/PowerShell 7,或保留
chcp 65001 >nul
。
- 多项目目录:
- 目录中若有多个
.csproj
,脚本会取扫描到的第一个作为目标。建议将脚本放入具体项目根目录,或在脚本中增强为"显式指定 .csproj 路径"。
- 目录中若有多个
- 类库项目:
- 类库不会生成
.exe
,publish/
下只有.dll
属正常现象。
- 类库不会生成
- 自包含 vs 非自包含:
- 自包含(
true
)生成更大的单文件,无需额外安装 .NET 运行时;适合分发给未装 .NET 的环境。 - 非自包含(
false
)体积更小,但依赖目标环境的 .NET 运行时版本。
- 自包含(
- 运行权限:
- 发布过程中需要访问网络(NuGet 恢复)与写入
publish/
目录的权限。若有防护软件拦截,需放行dotnet.exe
与当前工作目录。
- 发布过程中需要访问网络(NuGet 恢复)与写入
7. 进阶用法建议(可选增强)
- 显式指定项目文件:
- 可扩展脚本支持
PROJECT=path\to\MyApp.csproj
的命名参数,以避免在多项目目录中误选。
- 可扩展脚本支持
- 输出版本与文件信息:
- 在
.csproj
中设置AssemblyVersion
/FileVersion
/InformationalVersion
,便于追踪。
- 在
- 生成自包含默认:
- 若分发到无 .NET 环境的机器较多,可将脚本默认
SELF_CONTAINED=true
。
- 若分发到无 .NET 环境的机器较多,可将脚本默认
8. 参考命令(脚本内部核心命令)
bat
rem 清理
"dotnet" clean "%FULL_CSPROJ_PATH%" -c %CONFIG%
rem 发布单文件
"dotnet" publish "%FULL_CSPROJ_PATH%" ^
-c %CONFIG% ^
-r %RUNTIME% ^
--self-contained %SELF_CONTAINED% ^
-p:PublishSingleFile=true ^
-p:IncludeNativeLibrariesForSelfExtract=true ^
-o "%PUBLISH_DIR%"
如需将脚本增强为"显式选择 .csproj / 支持命名参数 / 默认自包含"等,请在 D:\MyItems\UdpClientUser\
中提出具体需求,我可以直接修改脚本并验证结果。