当前位置: 首页 > news >正文

自动化 NuGet 包打包与上传:完整批处理脚本详解(含 SVN 支持)

在大型项目中,我们常常需要定期打包多个 .csproj 项目为 NuGet 包,并上传到私有 NuGet 服务。这篇文章分享一份实战脚本,支持以下自动化流程:

  • 自动读取、更新 .csproj 文件中的 VersionPackageOutputPath 等节点;

  • 自动构建并打包为 .nupkg

  • 自动上传至私有 NuGet 源;

  • 支持 SVN 更新与提交;

  • 支持中文路径,日志分离记录成功与失败信息。

✅ 功能概览

功能点

说明

自动更新版本号

根据日期自动生成版本号,并支持手动输入

修改 .csproj

自动注入 VersionDescriptionPackageOutputPath 等必要节点

打包 NuGet

使用 dotnet pack 命令完成打包

上传 NuGet

自动上传所有打包成功的 .nupkg 包至私有源

SVN 支持

自动执行 SVN 更新并提交修改

日志清晰分离

success_log.txterror_log.txtsvn_commit_list.txt 等日志文件帮助排查问题


📦 脚本内容

以下是完整的批处理脚本代码,推荐将其保存为 auto_push_nuget.bat

@echo off
REM 切换到 UTF-8 编码,支持中文路径
chcp 65001 >nul
setlocal EnableDelayedExpansion
echo ===== Auto push nuget started =====REM ---------------- 配置区 ----------------
set "NUGET_SOURCE=你的私有nuget服务器"
set "API_KEY=私有nuget服务器的key,没有填空"
set "SUCCESS_LOG=success_log.txt"
set "ERROR_LOG=error_log.txt"
set "SVN_COMMIT_LIST=svn_commit_list.txt"
set "TEMP_LOG=temp_ps_output.txt"
set "SVN_UPDATE_TEMP=svn_update_temp.txt"
set SUCCESS_COUNT=0
set FAIL_COUNT=0
REM -----------------------------------------

⚙️ 脚本前置说明:

  • 脚本自动将当前控制台设置为 UTF-8,确保支持中文路径和日志输出;

  • 所有日志均分离输出到文件中,避免控制台信息混乱。

🎯 项目路径配置

修改以下部分,添加你要打包的 .csproj 路径(相对路径):

注意:索引数与COUNT一致

:: 定义项目路径数组
set "PROJECT_PATHS[0]=Xxx.BI.WebSite.Core\Xxx.BI.WebSite.Core.csproj"
set "PROJECT_PATHS[1]=Xxx.BI.WebSite.RazorWeb\Xxx.BI.WebSite.RazorWeb.csproj"
set "PROJECT_COUNT=2"

根据你的项目实际路径修改 PROJECT_PATHS,添加你希望打包的工程列表。

⚠️ 注意:这里的路径请填写 相对于脚本所在目录的路径,不要写绝对路径。如下图

版本号格式为:
6{YY}.{MM}.{DD}.{X},其中 X 是递增的补丁号。

例如:624.05.14.2

for /f "tokens=1-3 delims=/" %%a in ('powershell -command "Get-Date -Format 'yyyy/MM/dd'"') do (set YYYY=%%aset MM=%%bset DD=%%c
)
set YY=!YYYY:~2,2!
set /a M=1!MM! - 100
set /a D=1!DD! - 100
set VERSION_PREFIX=6!YY!.!M!.!D!

🔧 修改 .csproj 文件

使用 PowerShell 对 XML 进行修改,确保插入以下节点:

  • <Version>:自动计算或用户输入;

  • <Description>:设置描述;

  • <PackageOutputPath>:统一输出至 ..\..\..\nupkgs

  • <GeneratePackageOnBuild>:确保打包时包含所有内容。

$pg = $xml.Project.PropertyGroup | Where-Object { $_.Condition -eq $null -or $_.Condition -eq '' } | Select-Object -First 1;
if (-not $pg) { $pg = $xml.CreateElement('PropertyGroup'); $xml.Project.AppendChild($pg) | Out-Null };
# 后续注入节点逻辑...

🏗️ 构建与打包

dotnet build "!CSProjPath!" -c Release
dotnet pack "!CSProjPath!" -c Release --output "%~dp0nupkgs"

脚本会在 nupkgs 文件夹生成对应 .nupkg 文件。

☁️ 自动上传 NuGet 包

所有成功打包的路径会记录到 success_log.txt,随后逐个推送:

如果没有API-KEY,请删除 --api-key "%API_KEY%"

dotnet nuget push "!NUPKG_PATH!" --source "%NUGET_SOURCE%" --api-key "%API_KEY%"

🧾 SVN 自动化支持

  • 支持脚本运行前执行 svn update

  • 成功处理的项目会记录在 svn_commit_list.txt

  • 最后统一执行 svn commit 自动提交版本号更新:

svn commit "项目路径" -m "Auto update Version to 624.05.14.1"

🧠 SVN 提交

每次成功修改 .csproj 后,记录在列表文件 svn_commit_list.txt 中,最终一并执行 SVN 提交:

svn commit "项目路径" -m "Auto update Version to 6xx.xx.xx.x"

📜 附录:完整批处理脚本源码

@echo off
REM 切换到 UTF-8 编码,支持中文路径
chcp 65001 >nul
setlocal EnableDelayedExpansion
echo ===== Auto push nuget started =====
REM ---------------- 配置区 ----------------
set "NUGET_SOURCE=你的私有nuget服务器"
set "API_KEY=私有nuget服务器key"
set "SUCCESS_LOG=success_log.txt"
set "ERROR_LOG=error_log.txt"
set "SVN_COMMIT_LIST=svn_commit_list.txt"
set "TEMP_LOG=temp_ps_output.txt"
set "SVN_UPDATE_TEMP=svn_update_temp.txt"::成功/失败条数
set SUCCESS_COUNT=0
set FAIL_COUNT=0
REM 注意:建议检查服务器是否支持 HTTPS,例如 https://www.baidu.com:8888
REM -----------------------------------------:: 清空日志和 SVN 提交列表
if exist "%SUCCESS_LOG%" del "%SUCCESS_LOG%"
if exist "%ERROR_LOG%" del "%ERROR_LOG%"
if exist "%SVN_COMMIT_LIST%" del "%SVN_COMMIT_LIST%"
if exist "%TEMP_LOG%" del "%TEMP_LOG%"
if exist "%SVN_UPDATE_TEMP%" del "%SVN_UPDATE_TEMP%":: 清理 SVN_DIR,确保无换行符或多余字符
set "SVN_DIR=%~dp0"
:: 去掉末尾反斜杠
if "!SVN_DIR:~-1!"=="\" set "SVN_DIR=!SVN_DIR:~0,-1!"
:: 规范化路径
for %%P in ("!SVN_DIR!") do set "SVN_DIR=%%~fP"
echo [Debug] SVN directory: !SVN_DIR! >> "%SUCCESS_LOG%":: 执行 SVN 更新
echo [Info] Updating SVN working copy for directory: !SVN_DIR! >> "%SUCCESS_LOG%"
echo [Info] Updating SVN working copy...
svn update "!SVN_DIR!" > "%SVN_UPDATE_TEMP%" 2>&1
if errorlevel 1 (echo [Error] Failed to update SVN working copy. >> "%ERROR_LOG%"echo [Error] Failed to update SVN working copy. Error details:type "%SVN_UPDATE_TEMP%"echo [Error] Script will exit. >> "%ERROR_LOG%"echo [Error] Script will exit.del "%SVN_UPDATE_TEMP%"exit /b 1
) else (echo [Success] SVN working copy updated successfully. >> "%SUCCESS_LOG%"echo [Success] SVN working copy updated successfully.del "%SVN_UPDATE_TEMP%"
):: 获取当前日期作为版本前缀(6 + 年后两位 + 月 + 日)
for /f "tokens=1-3 delims=/" %%a in ('powershell -command "Get-Date -Format 'yyyy/MM/dd'"') do (set YYYY=%%aset MM=%%bset DD=%%c
)
set YY=!YYYY:~2,2!
set /a M=1!MM! - 100
set /a D=1!DD! - 100
set VERSION_PREFIX=6!YY!.!M!.!D!
echo [Debug] VERSION_PREFIX: !VERSION_PREFIX! >> "%SUCCESS_LOG%":: 定义项目路径数组
::注意:PROJECT_PATHS[X]=实际条数(X),COUNT=实际条数
:: 这里的路径规则,请录入相对路径,就是你的BAT所在文件夹以后的路径
set "PROJECT_PATHS[0]=Xxx.BI.WebSite.Core\Xxx.BI.WebSite.Core.csproj"
set "PROJECT_PATHS[1]=Xxx.BI.WebSite.RazorWeb\Xxx.BI.WebSite.RazorWeb.csproj"
set "PROJECT_COUNT=2":: 循环处理数组中的相对路径
for /l %%i in (0,1,%PROJECT_COUNT%-1) do (set "RELATIVE_PATH=!PROJECT_PATHS[%%i]!"if not "!RELATIVE_PATH!"=="" (echo [Info] Reading relative path: !RELATIVE_PATH! >> "%SUCCESS_LOG%"call :ProcessProject "!RELATIVE_PATH!")
)REM 统一 NuGet 包上传
echo.
echo ===== Pushing NuGet packages =====
echo ===== Pushing NuGet packages ===== >> "%SUCCESS_LOG%"
echo ===== Pushing NuGet packages ===== >> "%ERROR_LOG%"
set "FOUND_NUPKG=0"
if exist "%SUCCESS_LOG%" (for /f "tokens=1,* delims=:" %%a in ('findstr /B "\[Success\] Pack succeeded:" "%SUCCESS_LOG%"') do (set "NUPKG_PATH=%%b"REM 去除首尾空格并规范化路径for /f "tokens=*" %%c in ("!NUPKG_PATH!") do (set "NUPKG_PATH=%%~fc")if "!NUPKG_PATH!"=="" (echo [Warning] Skipping empty NUPKG_PATH >> "%ERROR_LOG%"echo [Warning] Skipping empty NUPKG_PATH) else (echo [Debug] Checking NuGet package: !NUPKG_PATH! >> "%SUCCESS_LOG%"if exist "!NUPKG_PATH!" (set "FOUND_NUPKG=1"echo Pushing: !NUPKG_PATH!echo Pushing: !NUPKG_PATH! >> "%SUCCESS_LOG%"dotnet nuget push "!NUPKG_PATH!" --source "%NUGET_SOURCE%" --api-key "%API_KEY%" >> "%SUCCESS_LOG%" 2>> "%ERROR_LOG%"if errorlevel 1 (set /a FAIL_COUNT+=1echo [Error] Push failed: !NUPKG_PATH! >> "%ERROR_LOG%"echo [Error] Push failed: !NUPKG_PATH!) else (				set /a SUCCESS_COUNT+=1echo [Success] Push succeeded: !NUPKG_PATH! >> "%SUCCESS_LOG%"echo [Success] Push succeeded: !NUPKG_PATH! )) else (set /a FAIL_COUNT+=1echo [Error] NuGet package not found during push: !NUPKG_PATH! >> "%ERROR_LOG%"echo [Error] NuGet package not found during push: !NUPKG_PATH!)))
)
if "!FOUND_NUPKG!"=="0" (echo [Warning] No successful NuGet packages found to push >> "%ERROR_LOG%"echo [Warning] No successful NuGet packages found to push
)REM 统一 SVN 提交
if exist "%SVN_COMMIT_LIST%" (echo.echo ===== Committing to SVN =====echo ===== Committing to SVN ===== >> "%SUCCESS_LOG%"echo ===== Committing to SVN ===== >> "%ERROR_LOG%"for /f "tokens=1,2 delims=;" %%a in (%SVN_COMMIT_LIST%) do (echo Committing: %%aecho Committing: %%a >> "%SUCCESS_LOG%"svn commit "%%a" -m "Auto update Version to %%b" >> "%SUCCESS_LOG%" 2>&1if errorlevel 1 (echo [Error] SVN commit failed: %%a >> "%ERROR_LOG%"echo [Error] SVN commit failed: %%a >> "%SUCCESS_LOG%"echo [Error] SVN commit failed: %%a) else (echo [Success] SVN commit succeeded: %%a >> "%SUCCESS_LOG%"echo [Success] SVN commit successed: %%a))del "%SVN_COMMIT_LIST%"
)echo. >> "%SUCCESS_LOG%"
echo ===== All tasks completed ===== >> "%SUCCESS_LOG%"
echo. >> "%ERROR_LOG%"
echo ===== All tasks completed ===== >> "%ERROR_LOG%"
echo.
echo ===== All tasks completed =====
echo Success log: %SUCCESS_LOG%
echo Error log: %ERROR_LOG%
echo Nuget push successed : %SUCCESS_COUNT%
echo Nuget push error: %FAIL_COUNT%
del "%ERROR_LOG%"
del "%SUCCESS_LOG%"
if exist "%SVN_UPDATE_TEMP%" del "%SVN_UPDATE_TEMP%"
pauseecho ===== Auto push nuget ended =====
endlocal
exit /b 0:ProcessProject
set "RELATIVE_PATH=%~1"
echo [Info] Processing relative path: %RELATIVE_PATH% >> "%SUCCESS_LOG%"REM 移除相对路径的前导 \(如果存在)
set "CLEAN_PATH=%RELATIVE_PATH%"
if "!CLEAN_PATH:~0,1!"=="\" set "CLEAN_PATH=!CLEAN_PATH:~1!"
echo [Debug] CLEAN_PATH: !CLEAN_PATH! >> "%SUCCESS_LOG%"REM 使用 pushd 切换到脚本目录
pushd "%~dp0"
echo [Debug] Current directory after pushd: %CD% >> "%SUCCESS_LOG%"REM 拼接完整路径
set "CSProjPath=%CD%\!CLEAN_PATH!"
REM 规范化路径
for %%P in ("!CSProjPath!") do set "CSProjPath=%%~fP"
echo [Info] Full .csproj path: !CSProjPath! >> "%SUCCESS_LOG%"REM 验证 .csproj 文件存在
if not exist "!CSProjPath!" (echo [Warning] File not found: !CSProjPath! >> "%ERROR_LOG%"echo [Warning] File not found: !CSProjPath!popdexit /b 0
)REM 恢复原始目录
popd
echo [Debug] Directory restored: %CD% >> "%SUCCESS_LOG%"echo.
echo ===== Processing: !CSProjPath! =====
echo ===== Processing: !CSProjPath! ===== >> "%SUCCESS_LOG%"REM —— 清空上次遗留的变量 ——
set "OLD_VERSION="
set "LAST_PART="REM —— 1) 读取 csproj 中已有的 Version —— 
powershell -NoProfile -Command ^"try { [xml]$x = Get-Content -Path '!CSProjPath!' -Encoding UTF8 -ErrorAction Stop; $version = $x.Project.PropertyGroup | Where-Object { $_.Version -and ($_.Condition -eq $null -or $_.Condition -eq '') } | Select-Object -ExpandProperty Version -First 1; if ($version) { $version.Trim() } else { '' } } catch { Write-Output 'ERROR: ' + $_.Exception.Message; exit 1 }" > "%TEMP_LOG%"
if errorlevel 1 (echo [Error] Failed to read Version from !CSProjPath! >> "%ERROR_LOG%"echo [Error] Failed to read Version from !CSProjPath!type "%TEMP_LOG%" >> "%ERROR_LOG%"popdexit /b 1
)
for /f "delims=" %%v in (%TEMP_LOG%) do (set "OLD_VERSION=%%v"
)
echo [Debug] OLD_VERSION: !OLD_VERSION! >> "%SUCCESS_LOG%"
del "%TEMP_LOG%"REM —— 2) 基于 OLD_VERSION 计算新的 LAST_PART ——
set "LAST_PART=1"
if defined OLD_VERSION (REM 检查 OLD_VERSION 是否包含错误if not "!OLD_VERSION!"=="!OLD_VERSION:ERROR:=!" (echo [Warning] Invalid OLD_VERSION: !OLD_VERSION! >> "%ERROR_LOG%"echo [Warning] Invalid OLD_VERSION: !OLD_VERSION!set "OLD_VERSION=") else (REM 清理 OLD_VERSION 中的空格set "OLD_VERSION=!OLD_VERSION: =!"echo [Debug] Cleaned OLD_VERSION: !OLD_VERSION! >> "%SUCCESS_LOG%"for /f "tokens=1-4 delims=." %%a in ("!OLD_VERSION!") do (set "OLD_PREFIX=%%a.%%b.%%c"echo [Debug] OLD_PREFIX: !OLD_PREFIX!, VERSION_PREFIX: !VERSION_PREFIX! >> "%SUCCESS_LOG%"if "!OLD_PREFIX!"=="!VERSION_PREFIX!" (set /a LAST_PART=%%d + 1echo [Debug] LAST_PART: !LAST_PART! >> "%SUCCESS_LOG%")))
)echo [Info] version number generation in progress...
echo [Info] recommend version: !VERSION_PREFIX!.!LAST_PART! ,Enter use this version or input new version:
set /p USER_VER=if defined USER_VER (set "CUSTOM_VERSION=!USER_VER!"
)if defined CUSTOM_VERSION (set "NEW_VERSION=!CUSTOM_VERSION!"
) else (set "NEW_VERSION=!VERSION_PREFIX!.!LAST_PART!"
)echo [Info] NEW_VERSION = !NEW_VERSION! >> "%SUCCESS_LOG%"
echo [Info] NEW_VERSION = !NEW_VERSION!
echo [Info] version number generation completed...REM —— 3) 使用 PowerShell 注入并**覆盖**所有必要节点 —— 
echo [Info] modify the csproj file...
set NEW_VERSION=!NEW_VERSION!
powershell -NoProfile -Command ^"$path = '!CSProjPath!';" ^"try { [xml]$xml = Get-Content -Path $path -Encoding UTF8 -Raw -ErrorAction Stop; $pg = $xml.Project.PropertyGroup | Where-Object { $_.Condition -eq $null -or $_.Condition -eq '' } | Select-Object -First 1; if (-not $pg) { $pg = $xml.CreateElement('PropertyGroup'); $xml.Project.AppendChild($pg) | Out-Null }; $vn = $pg.SelectSingleNode('Version'); if (-not $vn) { $vn = $xml.CreateElement('Version'); $pg.AppendChild($vn) | Out-Null }; $vn.InnerText = $env:NEW_VERSION; $desc = $pg.SelectSingleNode('Description'); if (-not $desc) { $desc = $xml.CreateElement('Description'); $pg.AppendChild($desc) | Out-Null }; $desc.InnerText = 'Automatically generate nuget packages'; $gpb = $pg.SelectSingleNode('GeneratePackageOnBuild'); if (-not $gpb) { $gpb = $xml.CreateElement('GeneratePackageOnBuild'); $gpb.InnerText = 'true'; $pg.AppendChild($gpb) | Out-Null }; $pop = $pg.SelectSingleNode('PackageOutputPath'); if (-not $pop) { $pop = $xml.CreateElement('PackageOutputPath'); $pg.AppendChild($pop) | Out-Null }; $pop.InnerText = '..\\..\\..\\nupkgs'; $sw = New-Object System.IO.StreamWriter($path, $false, (New-Object System.Text.UTF8Encoding $true)); $xml.Save($sw); $sw.Close(); Write-Output 'PS_INJECTION_SUCCESS'; } catch { Write-Output 'ERROR: ' + $_.Exception.Message; exit 1 }" > "%TEMP_LOG%"findstr "PS_INJECTION_SUCCESS" "%TEMP_LOG%" >nul
if errorlevel 1 (echo [Error] XML injection failed: !CSProjPath! >> "%ERROR_LOG%"echo [Error] XML injection failed: !CSProjPath!type "%TEMP_LOG%" >> "%ERROR_LOG%"exit /b 1
) else (echo [Success] modify successed
)
echo [Info] modify the csproj file...REM —— 验证 Version 节点 —— 
powershell -NoProfile -Command ^"try { [xml]$x = Get-Content -Path '!CSProjPath!' -Encoding UTF8 -ErrorAction Stop; $version = $x.Project.PropertyGroup | Where-Object { $_.Version -and ($_.Condition -eq $null -or $_.Condition -eq '') } | Select-Object -ExpandProperty Version -First 1; if ($version) { $version.Trim() } else { '' } } catch { Write-Output 'ERROR: ' + $_.Exception.Message; exit 1 }" > "%TEMP_LOG%"
if errorlevel 1 (echo [Error] Failed to verify Version in !CSProjPath! >> "%ERROR_LOG%"echo [Error] Failed to verify Version in !CSProjPath!type "%TEMP_LOG%" >> "%ERROR_LOG%"exit /b 1
)
for /f "delims=" %%v in (%TEMP_LOG%) do (set "VERIFIED_VERSION=%%v"
)
echo [Debug] Version after injection: !VERIFIED_VERSION! >> "%SUCCESS_LOG%"
if not "!VERIFIED_VERSION!"=="!NEW_VERSION!" (echo [Error] Version node not updated to !NEW_VERSION!, found !VERIFIED_VERSION! >> "%ERROR_LOG%"echo [Error] Version node not updated to !NEW_VERSION!, found !VERIFIED_VERSION!exit /b 1
)REM —— 4) 构建 —— 
echo [Info] building csproj...
dotnet build "!CSProjPath!" -c Release >> "%SUCCESS_LOG%" 2>> "%ERROR_LOG%"
if errorlevel 1 (echo [Error] Build failed: !CSProjPath! >> "%ERROR_LOG%"echo [Error] Build failed: !CSProjPath!exit /b 1
) else (echo [Success] build successed
)
echo [Info] end of csproj construction...REM —— 5) 打包 —— 
echo [Info] package in csproj...
if not exist "%~dp0nupkgs" mkdir "%~dp0nupkgs"
dotnet pack "!CSProjPath!" -c Release --output "%~dp0nupkgs" -p:Description="Automatically generate nuget packages" >> "%SUCCESS_LOG%" 2>> "%ERROR_LOG%"
if errorlevel 1 (echo [Error] Pack failed: !CSProjPath! >> "%ERROR_LOG%"echo [Error] Pack failed: !CSProjPath!exit /b 1
) else (echo [Success] pack successed
)
REM 记录成功打包的 .nupkg 文件
for %%P in ("%~dp0nupkgs\%~n1.!NEW_VERSION!.nupkg") do (if exist "%%P" (echo [Success] Pack succeeded: %%P >> "%SUCCESS_LOG%"echo [Success] Pack succeeded: %%P) else (echo [Error] Pack file not found: %%P >> "%ERROR_LOG%"echo [Error] Pack file not found: %%Pexit /b 1)
)
echo [Info] end of packaging csproj...REM —— 6) 记录 SVN 提交 —— 
echo !CSProjPath!;!NEW_VERSION!>> "%SVN_COMMIT_LIST%"del "%TEMP_LOG%"
exit /b 0

✅ 建议将脚本保存为 auto_push_nuget.bat,每次发布时双击运行即可。

📁 目录结构推荐

/你的解决方案根目录
│
├─ auto_push_nuget.bat
├─ nupkgs/
├─ success_log.txt
├─ error_log.txt
├─ svn_commit_list.txt

📌 注意事项

  • 建议手动验证 .csproj 路径是否正确;

  • 确保 svn 命令行工具已正确安装;

  • dotnet SDK 和私有 NuGet 源地址需提前配置;

  • 每次运行脚本前,请使用最新版源码(SVN update);

  • 批处理脚本推荐使用 Windows PowerShell 5+ 和 Windows Terminal。


🎉 效果展示

成功输出如下所示:

[Success] build successed
[Success] pack successed
Pushing: Xxx.BI.WebSite.Core.624.05.14.1.nupkg
[Success] Push succeeded: Xxx.BI.WebSite.Core.624.05.14.1.nupkg
Committing: Xxx.BI.WebSite.Core.csproj
[Success] SVN commit succeeded: Xxx.BI.WebSite.Core.csproj

🧩 最后

本脚本适合用于 CI/CD 之外的 本地开发辅助打包上传工具。你可以结合 gitJenkinsTeamCity 等系统,将其进一步整合为流水线任务。

如果你有类似自动化构建打包需求,欢迎参考本脚本并结合你项目的实际路径进行修改和优化。


如需该脚本的 .bat 文件,可留言或私信获取完整代码包。

如果你觉得这篇文章对你有帮助,欢迎 👍 点赞 / ⭐ 收藏 / 📝 留言!

相关文章:

自动化 NuGet 包打包与上传:完整批处理脚本详解(含 SVN 支持)

在大型项目中&#xff0c;我们常常需要定期打包多个 .csproj 项目为 NuGet 包&#xff0c;并上传到私有 NuGet 服务。这篇文章分享一份实战脚本&#xff0c;支持以下自动化流程&#xff1a; 自动读取、更新 .csproj 文件中的 Version、PackageOutputPath 等节点&#xff1b; 自…...

Go语言空白导入的作用与用途

在 Go 语言中&#xff0c;导入包时前面加下划线 _ 是一种特殊的导入方式&#xff0c;称为 “空白导入” 或 “匿名导入”。 作用&#xff1a; 执行包的初始化&#xff08;init 函数&#xff09;但不直接使用包中的标识符 import _ "go.uber.org/automaxprocs" 表示你…...

实验六:按键模拟控制实现

FPGA序列检测器实验(远程实验系统) 文章目录 FPGA序列检测器实验(远程实验系统)一、数字电路基础知识1. 时钟与同步2. 按键消抖原理代码讲解:分频与消抖3. 有限状态机(FSM)设计代码讲解:状态机编码与转移4. 边沿检测与信号同步5. 模块化设计二、实验数字电路整体思想三…...

【愚公系列】《Manus极简入门》038-数字孪生设计师:“虚实映射师”

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…...

Linux重定向与缓冲区

目录 文件描述符的分配规则 重定向 使用 dup2 系统调用 FILE 文件描述符的分配规则 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main() {int fd open("myfile", O_RDONLY);if(fd < 0){per…...

经典还原反应解析:Wolff-Kishner机制与黄鸣龙改进法

在有机化学发展史上记载的万余种经典反应中&#xff0c;当论及以科学家命名的标志性转化反应时&#xff0c;Wolff-Kishner-黄鸣龙还原反应必然占据重要地位。在大学《有机化学》课程中&#xff0c;学习还原反应时肯定会提到Wolff-Kishner-黄鸣龙还原反应&#xff0c;这是第一个…...

DataX从Mysql导数据到Hive分区表案例

0、下载DataX并解压到对应目录 DataX安装包&#xff0c;开箱即用&#xff0c;无需配置。 https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz 相关参考文档 https://github.com/alibaba/DataX/blob/master/hdfswriter/doc/hdfswriter.md 1、Hive分区…...

npm 报错 gyp verb `which` failed Error: not found: python2 解决方案

一、背景 npm 安装依赖报如下错&#xff1a; gyp verb check python checking for Python executable "python2" in the PATH gyp verb which failed Error: not found: python2 一眼看过去都觉得是Python环境问题&#xff0c;其实并不是你python环境问题&#xf…...

安装npm:npm未随Node.js一起安装

文章目录 上传至linux服务器/usr/local/目录下 如果npm没有随Node.js一起安装&#xff0c;你可以尝试单独下载并安装npm。但通常情况下&#xff0c;这是不必要的&#xff0c;因为npm是Node.js的一部分。如果确实需要单独安装npm&#xff0c;你可以参考npm的官方安装指南。 npm…...

C++23 ranges::to:范围转换函数 (P1206R7)

文章目录 引言C23 Ranges 概述ranges::to 的定义与功能定义功能 使用场景范围转换为容器简化字符串解析映射转换为向量 ranges::to 的优势代码简洁性提高开发效率与C23的stl容器的范围版本构造函数配合良好 模板参数约束的思考总结 引言 在C的发展历程中&#xff0c;每一个新版…...

openfeign 拦截器实现微服务上下文打通

目录 openfeign 拦截器实现微服务上下文打通需求分析&#xff1a;代码实现&#xff1a;subject 服务&#xff1a;controllerFeign 拦截器&#xff1a;将 Feign 拦截器注册为一个Bean&#xff1a; auth 鉴权服务&#xff1a;全局配置类&#xff1a;登录拦截器&#xff1a;上下文…...

【MySQL】变更缓冲区:作用、主要配置以及如何查看

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

TCP/IP-——C++编程详解

1. TCP/IP 编程基本概念 TCP&#xff08;传输控制协议&#xff09;&#xff1a;面向连接、可靠的传输层协议&#xff0c;保证数据顺序和完整性。IP&#xff08;网际协议&#xff09;&#xff1a;负责将数据包路由到目标地址。Socket&#xff08;套接字&#xff09;&#xff1a…...

微服务如何实现服务的高可用

背景&#xff1a;微服务分层需要考虑高可用和高并发的问题 微服务如何实现服务的高可用 先说结论&#xff1a;微服务实现高可用主要通过集群冗余故障自动转移来实现的具体可以从底下几种方案来实现。 “端”到“反向代理”的高可用“反向代理”到“站点应用”的高可用“站点…...

微服务调试问题总结

本地环境调试。 启动本地微服务&#xff0c;使用公共nacos配置。利用如apifox进行本地代码调试解决调试问题。除必要的业务微服务依赖包需要下载到本地。使用mvn clean install -DskipTests进行安装启动前选择好profile环境进行启动&#xff0c;启动前记得mvn clean清理项目。…...

egpo进行train_egpo训练时,keyvalueError:“replay_sequence_length“

def execution_plan(workers: WorkerSet, config: TrainerConfigDict) -> LocalIterator[dict]: if config.get(“prioritized_replay”): prio_args { “prioritized_replay_alpha”: config[“prioritized_replay_alpha”], “prioritized_replay_beta”: config[“prior…...

Hadoop的组成

&#xff08;一&#xff09;Hadoop的组成 对普通用户来说&#xff0c; Hadoop就是一个东西&#xff0c;一个整体&#xff0c;它能给我们提供无限的磁盘用来保存文件&#xff0c;可以使用提供强大的计算能力。 在Hadoop3.X中&#xff0c;hadoop一共有三个组成部分&#…...

Android锁

引言 &#x1f512; 在 Android 应用的开发过程中&#xff0c;随着业务需求的复杂度不断提升&#xff0c;多线程并发场景层出不穷。为了保证数据一致性与线程安全&#xff0c;锁&#xff08;Lock&#xff09;成为了不可或缺的工具。本篇博客将深入剖析 Android 中常用的锁机制…...

XD08M3232接近感应单片机的接近感应模块的工作原理

XD08M3232接近感应单片机的接近感应模块基于电容式感应原理&#xff0c;通过硬件电路与软件配置实现对物体接近的检测。以下是其工作原理的详细解析&#xff1a; 一、硬件架构与核心组件 1. 核心电路组成 接近感应模块由三大关键部分构成&#xff1a; 两个轨到轨运算放大器&…...

编程日志5.6

串的习题 1.2236. 判断根结点是否等于子结点之和 - 力扣(LeetCode) /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * Tr…...

量子计算实用化突破:从云端平台到国际竞合,开启算力革命新纪元

在硅谷某生物医药实验室&#xff0c;研究员艾米丽正盯着量子计算模拟界面露出微笑 —— 搭载中电信 "天衍" 量子计算云平台的 880 比特超导量子处理器&#xff0c;用 17 分钟完成了传统超算需 3 个月才能跑完的新型抗生素分子键合模拟。这个场景标志着量子计算正从 &…...

Made with Unity | 拓展“双点”宇宙版图

双点工作室&#xff08;Two Point Studios&#xff09;团队成立于2016年&#xff0c;其创立初衷是打造一个完美的游戏IP&#xff1a;构建一个既能持续吸引玩家&#xff0c;又具备足够扩展空间&#xff0c;同时经得起时间考验的虚拟世界。2018年&#xff0c;团队以《双点医院&am…...

3D 数据可视化系统是什么?具体应用在哪方面?

目录 一、3D 数据可视化系统的定义与内涵 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;核心要素 二、3D 数据可视化系统的优势 三、3D 数据可视化系统的应用领域 &#xff08;一&#xff09;城市规划与管理 &#xff08;二&#xff09;工业制造 &am…...

2025-5-14渗透测试:利用Printer Bug ,NTLMv2 Hash Relay(中继攻击),CVE-2019-1040漏洞复现

python3 printerbug.py test.com/test192.168.186.131 192.168.186.134 sudo python2 MultiRelay.py -t 192.168.186.132 -u ALLPrinter Bug 原理 PrinterBug&#xff08;CVE-2018-0886&#xff09;是Windows打印系统服务&#xff08;Spooler&#xff09;的一个设计缺陷&…...

OracleLinux7.9-ssh问题

有套rac环境&#xff0c;db1主机无法ssh db1和db1-priv&#xff0c;可以ssh登录 db2和db2-priv [rootdb1 ~]# ssh db1 ^C [rootdb1 ~]# ssh db2 Last login: Wed May 14 18:25:19 2025 from db2 [rootdb2 ~]# ssh db2 Last login: Wed May 14 18:25:35 2025 from db1 [rootdb2…...

《AI大模型应知应会100篇》第64篇:构建你的第一个大模型 Chatbot

第64篇&#xff1a;构建你的第一个大模型 Chatbot 手把手教你从零开始搭建一个基于大模型的聊天机器人 摘要 你是否想过&#xff0c;自己也能构建一个像 ChatGPT 一样能对话、能思考的聊天机器人&#xff08;Chatbot&#xff09;&#xff1f;别担心&#xff0c;这并不需要你是…...

鸿蒙OSUniApp 实现精美的用户登录和注册页面#三方框架 #Uniapp

UniApp 实现精美的用户登录和注册页面 前言 在开发鸿蒙APP时&#xff0c;登录注册页面作为用户与应用交互的第一道门槛&#xff0c;其体验与质量往往决定了用户的第一印象。去年我接手了一个电商小程序项目&#xff0c;产品经理特别强调要做一个既美观又实用的登录注册页面。…...

c#中equal方法与gethashcode方法之间有何关联?

文章目录 前言一、对hash运算的深入思考二、equal与gethashcode的关联三、 equal与gethashcode不同步的后果四、 规范的重写gethashcode 前言 大家有没有遇到过&#xff0c;当你重写了c#对象的equal方法之后&#xff0c;编译器会提示你对相应的gethashcode进行重写&#xff0c…...

查询公网IP地址的方法:查看自己是不是公网ip,附内网穿透外网域名访问方案

本地搭建服务并提供互联网连接时&#xff0c;较为传统的方法是使用公网IP地址。因此&#xff0c;如何查询本地自己是不是公网IP&#xff0c;是必须要掌握的一种技巧。当面对确实无公网IP时&#xff0c;则可以通过内网穿透方案&#xff0c;如nat123网络映射工具&#xff0c;将本…...

【轻松学 C:编程小白的大冒险】— 16 函数的定义与调用

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【轻松学 C&#xff1a;编程小白的大冒险…...

【Tools】CPU 分析

CPU 分析 Windows SDK 本指南提供了可用于调查影响评估指标的中央处理单元 (CPU) 相关问题的详细技术。 特定于评估的分析指南中的各个指标或问题部分确定了需要调查的常见问题。 本指南提供了可用于调查这些问题的技术和工具。 本指南中的技术使用 Windows Performance Too…...

进阶2_1:QT5多线程与定时器共生死

1、在widget.ui中使用 LCD Number控件 注意&#xff1a;若 LCD 控件不是多线程&#xff0c;LCD控件则会瞬间自增到最大的数值&#xff0c;如上图&#xff0c;说明两者都是多线程处理 2、实现方式 1、创建 LCD 控件并修改为 LCD1 2、创建任务类 mytask. h&#xff0c;对任务类…...

ECharts:数据可视化的强大引擎

在当今这个信息爆炸的时代&#xff0c;如何有效地展示和理解复杂的数据成为了每一个开发者和技术爱好者面临的挑战。Apache ECharts 作为一款基于 JavaScript 的开源可视化库&#xff0c;以其强大的功能、丰富的图表类型以及高度的可定制性&#xff0c;迅速成为了数据可视化领域…...

记录 QT 在liunx 下 QFileDialog 类调用问题 ()Linux下QFileDialog没反应)

1. 2025.05.14 踩坑记录 因为QT 在 liunx 文件系统不同导致的 Windows &#xff1a; QString filePath QFileDialog::getOpenFileName(nullptr, "选择文件", ".", "文本文件 (*.txt);所有文件 (*.*)"); 没问题 liunx 下 打不开&#xff…...

通用软件项目技术报告 - 导读III

现在,我们正式进入报告的第六个主要领域:6. 领域六:与第三方服务/API 集成 (含 LLM API)。 连接: 在现代软件开发中,很少有应用程序是完全孤立的。我们经常需要与各种外部的第三方服务或 API 进行集成,以利用它们提供的特定功能(如支付处理、地图服务、社交媒体登录、云…...

Kali Linux 桌面环境安装与配置指南

一、为什么选择 Kali Linux&#xff1f; Kali Linux 由 Offensive Security 维护&#xff0c;集成了数百种安全测试工具&#xff08;如 Metasploit、Nmap 和 Burp Suite&#xff09;&#xff0c;非常适合安全研究。但需要注意的是&#xff0c;Kali 默认以 root 用户运行&#…...

FFmpeg视频编码的完整操作指南

步骤如下&#xff1a; 安装和准备FFmpeg&#xff1a;确保包含所需编码器&#xff08;如libx264&#xff09;。基本命令行编码&#xff1a;使用ffmpeg命令进行转码&#xff0c;设置视频编码器、CRF、预设等。API编码流程&#xff08;针对开发者&#xff09;&#xff1a; a. 注册…...

【网络协议】TCP、HTTP、MQTT 和 WebSocket 对比

从协议本质、工作原理、特点、应用场景等方面详细对比 TCP、HTTP、MQTT 和 WebSocket。 1. TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09; 本质 协议类型&#xff1a;传输层协议&#xff08;OSI模型第4层&#xff09;。核心功能&#x…...

Leetcode数组day1

704 二分查找 注意点&#xff0c;左闭右闭 class Solution { public:int search(vector<int>& nums, int target) {//整数类型的动态数组的引用。int left0;int right nums.size()-1;while (left < right){int middle (rightleft)/2;if (nums[middle]>targ…...

leetcode2934. 最大化数组末位元素的最少操作次数-medium

1 题目&#xff1a;最大化数组末位元素的最少操作次数 官方标定难度&#xff1a;中 给你两个下标从 0 开始的整数数组 nums1 和 nums2 &#xff0c;这两个数组的长度都是 n 。 你可以执行一系列 操作&#xff08;可能不执行&#xff09;。 在每次操作中&#xff0c;你可以选…...

常见相机焦段的分类及其应用

相机焦段是指镜头的焦距范围&#xff0c;决定了拍摄时的视角、画面范围和透视效果。不同焦段适合不同的拍摄场景和主题&#xff0c;以下是常见焦段的分类及其应用&#xff1a; 一、焦段的核心概念 焦距&#xff1a;镜头光学中心到成像传感器的距离&#xff08;单位&#xff1a…...

FPGA在光谱相机中的核心作用

FPGA&#xff08;现场可编程门阵列&#xff09;作为光谱相机的核心控制与加速单元&#xff0c;通过硬件级并行处理能力和动态可编程特性&#xff0c;实现高速、高精度的光谱数据采集与处理。以下是其具体作用分类&#xff1a; 一、高速光电信号处理 ‌实时光谱复原‌ 通过硬…...

【证书与信任机制​】证书透明度(Certificate Transparency):如何防止恶意证书颁发?​​

证书透明度&#xff08;Certificate Transparency, CT&#xff09;的核心原理 证书透明度&#xff08;CT&#xff09;是一项由Google主导的开放标准&#xff0c;旨在通过公开记录所有SSL/TLS证书的颁发行为&#xff0c;防止恶意CA错误或故意颁发虚假证书。其核心机制如下&#…...

【RabbitMq C++】消息队列组件

RabbitMq 消息队列组件 1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C客户端库4. AMQP-CPP 库的简单使用4.1 使用4.1.1 TCP 模式4.1.2 扩展模式 4.2 常用类与接口介绍4.2.1 Channel4.3.2 ev 5. RabbitMQ样例编写5.1 发布消息5.2 订阅消息 1. RabbitMq介绍 RabbitMq - …...

基于SpringBoot+Vue的房屋租赁管理系统源码包(完整版)开发实战

基于SpringBootVue的房屋租赁管理系统源码包&#xff08;完整版&#xff09;开发实战 一、引言 随着城市化进程加速&#xff0c;房屋租赁市场规模持续扩大&#xff0c;传统管理方式已无法满足高效、精准的业务需求。本文基于SpringBootVue框架&#xff0c;设计并实现了一套完…...

《AI大模型应知应会100篇》第61篇:FastAPI搭建大模型API服务

第61篇&#xff1a;FastAPI搭建大模型API服务 摘要 随着大语言模型&#xff08;LLM&#xff09;在各行各业的广泛应用&#xff0c;构建一个高性能、可扩展的大模型 API 服务变得尤为重要。FastAPI 以其异步支持、类型安全、自动生成文档等优势&#xff0c;成为当前最流行的选择…...

Java 源码 HashMap源码分析

Java 源码 HashMap源码分析 1 初始容量 /*** The default initial capacity - MUST be a power of two.* 默认的初始容量&#xff0c;必须为2的幂*/static final int DEFAULT_INITIAL_CAPACITY 1 << 4; // aka 16容量表示哈希表中槽的数量&#xff08;即哈希数组的长度…...

requestAnimationFrame 与 requestIdleCallback 对比

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、背景与问题场景二、核心API对比分析三、选择 requestIdleCallback 的核心原因四、特殊场景处理建议五、最佳实践总结六、结论前言 看过埋点库 sunshine-track ,很多人疑惑为啥批量上报埋点信息的时候,用的是 request…...

【C/C++】自定义类型:结构体

文章目录 前言自定义类型&#xff1a;结构体1.结构体类型的声明1.1 结构体回顾1.1.1 结构的声明 1.1.2 结构体变量的创建和初始化1.2 结构的特殊声明1.3 结构的自引用 2.结构体内存对齐2.1 对⻬规则2.2 为什么存在内存对齐&#xff1f;2.3 修改默认对⻬数 3. 结构体传参4.结构体…...

视频编解码学习十二之Android疑点

一、android.view.SurfaceControl.setDisplaySurface的作用 android.view.SurfaceControl.setDisplaySurface 是 Android 系统中一个 native 层级别的 API&#xff0c;主要用于 设置某个物理显示屏&#xff08;Display&#xff09;的输出 Surface&#xff0c;属于 SurfaceFlin…...