param( [string]$ProjectFile = "Vmianqian.csproj", [string]$Configuration = "Release", [string]$Framework = "net10.0-windows", [string]$OutputRoot = "release-packages", [string]$DeleteListFile = "delete-files.txt" ) $ErrorActionPreference = "Stop" function Write-Step { param([string]$Message) Write-Host "" Write-Host "==> $Message" -ForegroundColor Cyan } function Remove-IfExists { param([string]$PathValue) if (Test-Path $PathValue) { Remove-Item -Path $PathValue -Recurse -Force } } function Get-ProjectVersion { param([string]$CsprojPath) if (-not (Test-Path $CsprojPath)) { throw "Project file not found: $CsprojPath" } $content = Get-Content -Path $CsprojPath -Raw $patterns = @( "\s*([^<]+?)\s*", "\s*([^<]+?)\s*", "\s*([^<]+?)\s*", "\s*([^<]+?)\s*" ) foreach ($pattern in $patterns) { $match = [regex]::Match($content, $pattern) if ($match.Success) { return $match.Groups[1].Value.Trim() } } return (Get-Date -Format "yyyy.MM.dd.HHmm") } function Copy-RuntimeFiles { param( [string]$SourceDir, [string]$TargetDir ) if (-not (Test-Path $SourceDir)) { throw "Build output directory not found: $SourceDir" } $resolvedSourceDir = (Resolve-Path $SourceDir).Path.TrimEnd('\', '/') New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null $excludeDirectories = @( "Vmianqian.exe.WebView2", "EBWebView" ) $excludeExtensions = @( ".pdb", ".xml", ".config", ".tmp", ".log" ) $excludeFileNames = @( "appsettings.Development.json" ) Get-ChildItem -Path $resolvedSourceDir -Recurse -File | ForEach-Object { $fullName = $_.FullName $name = $_.Name $extension = $_.Extension foreach ($dirName in $excludeDirectories) { $marker = [System.IO.Path]::DirectorySeparatorChar + $dirName + [System.IO.Path]::DirectorySeparatorChar if ($fullName.Contains($marker)) { return } } if ($excludeExtensions -contains $extension) { return } if ($excludeFileNames -contains $name) { return } $relativePath = $fullName.Substring($resolvedSourceDir.Length).TrimStart('\', '/') $targetPath = Join-Path $TargetDir $relativePath $targetParent = Split-Path -Parent $targetPath if (-not (Test-Path $targetParent)) { New-Item -ItemType Directory -Path $targetParent -Force | Out-Null } Copy-Item -Path $fullName -Destination $targetPath -Force } } $projectVersion = Get-ProjectVersion -CsprojPath $ProjectFile $projectName = [System.IO.Path]::GetFileNameWithoutExtension($ProjectFile) $buildOutputDir = Join-Path "bin" (Join-Path $Configuration $Framework) $packageVersionDir = Join-Path $OutputRoot $projectVersion $packageRootDir = Join-Path $packageVersionDir "incremental" $zipFilePath = Join-Path $OutputRoot ("{0}_{1}.zip" -f $projectName, $projectVersion) Write-Step "Project version: $projectVersion" Write-Step "Building project" dotnet build $ProjectFile -c $Configuration if ($LASTEXITCODE -ne 0) { throw "dotnet build failed" } Write-Step "Cleaning old package output" Remove-IfExists -PathValue $packageVersionDir Remove-IfExists -PathValue $zipFilePath Write-Step "Copying runtime files" Copy-RuntimeFiles -SourceDir $buildOutputDir -TargetDir $packageRootDir if (Test-Path $DeleteListFile) { Write-Step "Including delete-files.txt" Copy-Item -Path $DeleteListFile -Destination (Join-Path $packageRootDir "delete-files.txt") -Force } Write-Step "Creating zip package" Compress-Archive -Path (Join-Path $packageRootDir '*') -DestinationPath $zipFilePath -Force Write-Step "Package completed" Write-Host "Version: $projectVersion" -ForegroundColor Green Write-Host "Incremental folder: $(Resolve-Path $packageRootDir)" -ForegroundColor Green Write-Host "Zip package: $(Resolve-Path $zipFilePath)" -ForegroundColor Green Write-Host "" Write-Host "Upload this zip file to your server:" -ForegroundColor Yellow Write-Host $zipFilePath -ForegroundColor Yellow