在VS扩展工具中使用powershell脚本发布 dotnetcore单一文件
参考:dotnet publish 命令 - .NET CLI | Microsoft Docs
最近使用VS2019和VS2022,发布 AOT时,总是提示失败,要好几回才成功,没得办法,自己搞吧,反复重试总是能成功的,改改就可以在持续集成中打包了,也免得每个项目都要创建发布脚本FolderProfile.pubxml
拿走不谢
在外部工具中创建一个命令
命令和参数如下
@@@code
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-ExecutionPolicy RemoteSigned -File "c:\qoushuidll\tools\publish_core.ps1" "$(ProjectDir)$(ProjectFileName)" "net5.0;net6.0"
PS脚本内容如下:
@@@code
Param(
[string]$path,
[string]$verions
)
# $path="D:\code\Zooy\PatrolCore\src\PatrolPlugins\PatrolHelloForm\PatrolHelloForm.csproj"
# $vers=("net5.0","net6.0")
# 变量定义
if ([String]::IsNullOrEmpty($path)){
Write-Host "路径为空" -ForegroundColor Red
exit
return
}
$rarTool="C:\Program Files\WinRAR\winrar.exe"
$publishDir="d:\publish"
$toolPath= Split-Path -Parent $MyInvocation.MyCommand.Definition
$slnPath =[System.IO.Path]::GetDirectoryName($path)
$name = [System.IO.Path]::GetFileNameWithoutExtension($path)
$vers = $verions.Split(";")
# 以项目名为发布文件夹名
$publishDir = [System.IO.Path]::Combine($publishDir,$name)
Write-Host "发布NETCORE项目" $path "至" $publishDir -ForegroundColor Yellow
# 选择发布模式
$types = (1,2,4,8)
Write-Host "选择发布模式,1 依赖 2 独立 4 单一文件 8 只有一个文件 15 全部 "
$type = Read-Host "请选择"
Set-Location $slnPath
Function GetFrames($vers,$path){
Write-Host "自动分析csproj是否为多目标" -ForegroundColor Yellow
[System.Collections.Generic.List[String]]$arraylist={}
$arraylist.Clear();
# 自动判断netcore版本
$csprojText=[String][System.IO.File]::ReadAllText($path)
$reg = "(?<a>\<TargetFrameworks\>)(?<s>.*)(?<b>\</TargetFrameworks\>)"
if (-not [System.Text.RegularExpressions.Regex]::IsMatch($csprojText,$reg)){
#单目标 <TargetFramework>net6.0</TargetFramework>
$m =[System.Text.RegularExpressions.Regex]::Match($csprojText, "(?<a>\<TargetFramework\>)(?<s>.*)(?<b>\</TargetFramework\>)").Groups["s"].Value.ToLower()
ForEach($ver in $vers){
if($ver -eq $m ){
$arraylist.Add($m)
}
}
}else{
$m =[System.Text.RegularExpressions.Regex]::Match($csprojText,$reg)
#Write-Host $m.Groups["s"].Value
foreach($v in $m.Groups["s"].Value.ToLower().Split(";")){
ForEach($ver in $vers){
#Write-Host $ver $v
if($v.StartsWith($ver) ){
$arraylist.Add($v)
}
}
}
}
return $arraylist
}
Function GetOutputTarget($mDotnetVer,$mPublishDir,$v){
if ($mDotnetVer -eq "net6.0")
{
$trg= [System.IO.Path]::Combine($mPublishDir, $v)
}else
{
$trg= [System.IO.Path]::Combine($mPublishDir,$mDotnetVer, $v)
}
return $trg
}
Function GetZipFile($mDotnetVer,$mPublishDir,$v){
if ($mDotnetVer -eq "net6.0")
{
$zip="$mPublishDir\$v.zip"
}else
{
$zip="$mPublishDir\$mDotnetVer\"+"$v.zip"
}
return $zip
}
Function Publish ($csprojPath, $numbers ,$mDotnetVer,$mDotnetRuntime, $mPublishDir ,$mDicOutput){
$cmd = " -c Release "
[System.Collections.Generic.Dictionary[int,String]]$mDic = @{}
# 发布可移植包
$mDic.Add(1,"-f $mDotnetRuntime")
$mDic.Add(2,"-f $mDotnetRuntime -r win-x64 --self-contained true ")
# 发布可移植单一包
$mDic.Add(4,"-f $mDotnetRuntime -r win-x64 --self-contained false /p:PublishSingleFile=true")
# 发布包含运行时的可移植单一包
if ($dotnetRuntime -eq "net6.0")
{
$mDic.Add(8,"-f $mDotnetRuntime -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true /p:PublishTrimmed=false /p:EnableCompressionInSingleFile=true")
}
else
{
$mDic.Add(8,"-f $mDotnetRuntime -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true /p:PublishTrimmed=false")
}
foreach($i in $numbers){
if(($i -band $type) -eq $i )
{
$retry =5
$trg = GetOutputTarget -mDotnetVer $mDotnetVer -mPublishDir $mPublishDir -v $mDicOutput[$i]
# 清除现有文件
if ([System.IO.Directory]::Exists($trg))
{
Remove-Item $trg -Recurse -Force
}
$v = $mDic[$i]
$tmp =" dotnet publish `"$csprojPath`" -o `"$trg`" $cmd $v "
Write-Host $tmp
# 检查是否失败,重试5次
do {
$retry = $retry -1
$b =0
$v= $mDicOutput[$i]
if(-not [System.IO.Directory]::Exists($trg)){
$b=1
Write-Host "$v $mDotnetRuntime 生成" -ForegroundColor Yellow
}else{
if ([System.IO.Directory]::GetFiles($trg,"*").Length -lt 2){
$b=2
Write-Host "$v $mDotnetRuntime 生成失败,重试" -ForegroundColor Red
}
}
if($b -gt 0)
{
if([System.Diagnostics.Process]::GetProcessesByName("dotnet.exe").Length -lt 0){
& cmd /c " taskkill /F /IM `"dotnet.exe`""
}
& timeout /T 5 /NOBREAK
& cmd /c " $tmp "
}
} while( $retry -gt 0)
}
}
}
Function Rar($numbers,$mDotnetVer,$mDotnetRuntime,$mPublishDir,$mRarTool,$mDicOutput){
foreach($i in $numbers){
$v= $mDicOutput[$i]
$trg = GetOutputTarget -mDotnetVer $mDotnetVer -mPublishDir $mPublishDir -v $mDicOutput[$i]
if(($i -band $type) -eq $i )
{
if($i -eq 8){
if($mDotnetVer -eq "net6.0-windows") {
Write-Host "net6.0-windows aot 在win7,2008上包含运行时会出现动态库丢失的问题" -ForegroundColor Yellow
}
}
$b =1
if(-not [System.IO.Directory]::Exists($trg)){
$b= 0
Write-Host "$i $v $mDotnetRuntime 未生成" -ForegroundColor Red
}else{
if ([System.IO.Directory]::GetFiles($trg,"*").Length -lt 2){
$b=2
Write-Host "$i $v $mDotnetRuntime 生成失败" -ForegroundColor Red
}
}
if ($b -eq 1){
$zip = GetZipFile -mDotnetVer $mDotnetVer -mPublishDir $mPublishDir -v $mDicOutput[$i]
Write-Host "$i $v $mDotnetRuntime 生成成功"
if ([System.IO.Directory]::Exists($zip))
{
Remove-Item $zip -Force
}
& cmd /c " `"$mRarTool`" a -EP1 -r -DF -x*.Development.json -x*.pdb $zip $trg "
#删除生成的文件
Remove-Item $trg -Recurse -Force
}
}
}
}
#判断是否为多目标
# 构造发布参数
[System.Collections.Generic.Dictionary[int,String]]$tDicOutput = @{}
$tDicOutput.Add(1,"$name")
$tDicOutput.Add(2,"$name"+"_portable")
# 发布可移植单一包
$tDicOutput.Add(4,"$name"+"_aot")
# 发布包含运行时的可移植单一包
$tDicOutput.Add(8,"$name"+"_single")
$frames = GetFrames -vers $vers -path $path
Write-Host "有效编译目标为" $frames
# 解开CSPROJ,查看是否包含 <UseWindowsForms>true</UseWindowsForms>
Foreach($dotnetRuntime in $frames){
# Write-Host $dotnetRuntime
$dotnetVer=$dotnetRuntime.Split("-")[0]
Publish -csprojPath $path -numbers $types -mDotnetVer $dotnetVer -mDotnetRuntime $dotnetRuntime -mPublishDir $publishDir -mDicOutput $tDicOutput
}
Write-Host "============++++++++++++++++++++++++++++++++++++==========================="
Write-Host "统计汇报以及压缩" -ForegroundColor Yellow
Foreach($dotnetRuntime in $frames){
$dotnetVer=$dotnetRuntime.Split("-")[0]
Rar -numbers $types -mPublishDir $publishDir -mDotnetVer $dotnetVer -mDotnetRuntime $dotnetRuntime -mRarTool $rarTool -mDicOutput $tDicOutput
}
Write-Host "即将退出..." -ForegroundColor Yellow
& timeout /T 5 /NOBREAK
Start-Process explorer "$publishDir"