NETプロジェクトの自動化:ワンクリックアップデートとリリーススクリプトの完全な解析

NETプロジェクトの自動化:ワンクリックアップデートとリリーススクリプトの完全な解析

この記事では、Power Shellスクリプトとバッチファイルを使用して、. NET Avalonia UIプロジェクトで自動バージョン更新とワンクリックパブリッシュを実装する方法を詳しく説明します。まず、スクリプトが正しく実行されるようにするためのPower Shell実行ポリシーの設定と変更について説明します。次に、バージョン番号を自動的に更新するスクリプトをVisual Studioプリビルドイベントに追加する方法と、バッチファイルを使用してアプリケーションを複数のプラットフォームにパブリッシュする方法について説明します。最後に、Gitタグに基づいてプログラムのバージョン情報を自動的に更新するPower Shellスクリプトの例を提供します。これらのアプローチは、. NETプロジェクトの開発効率とリリースプロセスの容易さを向上させます。

最后更新 2025/02/21 22:30
沙漠尽头的狼
预计阅读 7 分钟
分类
Avalonia UI
标签
.NET C# Avalonia UI Visual Studio 出版物を

NET開発の旅では、効率的なバージョン管理と簡単なリリースプロセスは、開発効率とプロジェクト品質を向上させるための重要な部分です。今日は、スクリプトを使用して. NET Avalonia UIプロジェクトの自動更新バージョンを実装し(もちろん、他の. NETプロジェクトにも適用されます)、ワンクリックリリースを実装し、開発プロセスをよりスムーズかつ効率的にする方法を詳しく見ていきます。

スクリプト実行権チェック

Power Shellスクリプトを実行する前に、実行ポリシーを理解し、適切に設定することが重要です。実行ポリシーは、Power Shellでスクリプトの実行を許可するかどうか、実行するスクリプトの種類を決定します。以下の簡単なコマンドを使用して、現在の実行ポリシーを確認できます:

Get-ExecutionPolicy

実行ポリシーの値によって意味が異なり、スクリプトの実行に制限の度合いが異なります。

  • ** 制限付き **:これはデフォルトのポリシーで、厳格なゲートキーパーのようなもので、スクリプトの実行は許可されず、Power Shellコンソールから1行ずつコマンドを入力することしかできません。これはシステムのセキュリティをある程度保証しますが、スクリプトを一括実行する必要がある開発者にとっては制約になります。
  • AllSigned:信頼できるパブリッシャーが署名したスクリプトのみが実行できます。これは、特定のパスを持っている人だけがアクセスできるようなもので、スクリプトのソースの信頼性を保証しますが、すべてのスクリプトに署名があるわけではないため、スクリプトの使用の障壁を高めます。
  • RemoteSigned:ローカルで作成されたスクリプトは直接実行できますが、インターネットからダウンロードされたスクリプトは信頼できるパブリッシャーが署名する必要があります。これは、セキュリティと利便性のバランスを取り、ローカル開発の柔軟性を可能にし、Webからダウンロードされたスクリプトのセキュリティチェックを提供します。
  • Unrestricted:すべてのスクリプトを実行できますが、インターネットからダウンロードしたスクリプトは実行前に確認を求められます。これは開発者に大きな自由を与えますが、厳密にチェックされていないスクリプトは悪意のあるコードを運ぶ可能性があるため、セキュリティリスクも伴います。
  • Bypass:スクリプトの実行をブロックせず、セキュリティ警告もありません。これは非常にオープンなセットアップであり、システムがセキュリティ脅威にさらされる可能性のある特定の安全で制御された環境でのみ使用されます。

デフォルトでは、実行ポリシーはRestrictedです。これにより、ストリームへの書き込みを許可しないようにライトバックファイルが失敗することがあります。たとえば、ファイルの内容を変更する必要があるスクリプトを実行しようとすると、パーミッションの問題が発生します。

実行ポリシーの修正

スクリプトをスムーズに実行するためには、ニーズに応じた実行戦略を選択する必要があります。一定のセキュリティを確保しながら、ローカルスクリプトと一定のセキュリティチェックを受けたネットワークダウンロードスクリプトを簡単に実行したい場合は、実行ポリシーをRemoteSignedに設定することが良い選択です。

ただし、実行ポリシーの変更には管理者権限が必要な場合があるため、Power Shellを管理者として実行し、次のコマンドを使用して変更してください。

Set-ExecutionPolicy RemoteSigned

これにより、ローカルで作成されたスクリプトは直接実行でき、インターネットからダウンロードされたスクリプトは署名検証が必要となり、セキュリティリスクを軽減できます。

変更結果の検証

実行ポリシーを変更した後、設定が有効であることを確認するには、Get-ExecutionPolicyコマンドを再度使用して、変更が成功したことを確認できます。出力がRemoteSignedと表示されたら、実行ポリシーの変更に成功したことを意味し、. ps 1スクリプトを正常に実行できるはずです。

VSリリース。

Visual Studioでは、ビルド前のイベントにスクリプトを追加することで、プロジェクトバージョンの自動更新を実装できます。プロジェクトプロパティーで“イベントの構築”タブを探し、“イベントの事前構築”コマンドラインに次のコマンドを追加します。

powershell -ExecutionPolicy Bypass -File "UpdateAssemblyVersion.ps1" -AssemblyInfoFile "GlobalAssembly.cs" -Configuration "$(ConfigurationName)" -Platform "$(PlatformName)"

パラメータには明確な意味がある。

  • ConfigurationName:アクティブなソリューション構成を表します。Debug(デバッグモード)やRelease(リリースモード)などの一般的なものです。異なる構成では、開発バージョンと公式リリースバージョンを区別するために、異なるバージョン番号のプログラムを生成することができます。
  • PlatformName:AnyCPU(任意のCPUアーキテクチャ)、x 86(32ビットアーキテクチャ)、x 64(64ビットアーキテクチャ)などのアクティブなソリューションプラットフォームを表します。プラットフォームによって、互換性とパフォーマンスのニーズを満たすために異なるバージョン識別が必要になる場合があります。

バッチファイルのパブリッシュ[ばっちふぁいるのぱぶりけーしょん]

Visual Studioを開かずにプログラムをリリースし、Windows、Linux、macOSなどの複数のプラットフォームに簡単に拡張できるようにしたい場合があります。この時点で、バッチファイルが便利です。次に、サンプルバッチファイルを示します。

@echo off
setlocal enabledelayedexpansion

rem 遍历 GlobalAssemblies 目录下的文件执行 PowerShell 脚本
for %%f in (GlobalAssemblies\*) do (
    powershell -ExecutionPolicy Bypass -File "UpdateAssemblyVersion.ps1" -AssemblyInfoFile "%%f" -Configuration "Release" -Platform "x64"
    rem 检查 PowerShell 脚本执行是否成功
    if !errorlevel! neq 0 (
        echo Failed to update assembly version for file %%f!
        endlocal
        exit /b !errorlevel!
    )
)

rem 设置发布路径
set PUBLISH_PATH=publish\win-x64

rem 定义项目信息数组,格式为 项目名称,项目路径(只写项目目录),相对发布目录名
set "projects=码坊工具箱,src\CodeWF.Toolbox.Desktop,codewf Avalonia发布测试,tests\AvaloniaAotDemo,AvaloniaAotDemo"

rem 遍历项目数组
for %%a in ("%projects: =","%") do (
    set "current_project=%%~a"
    for /f "tokens=1,2,3 delims=," %%b in ("!current_project!") do (
        set "projectName=%%b"
        set "projectPath=%%c"
        set "relativePublishDir=%%d"

        rem 拼接 .pubxml 文件的默认路径
        set "pubxmlPath=!projectPath!\Properties\PublishProfiles\FolderProfile-win_x64.pubxml"
        rem 拼接当前项目的发布路径
        set "CURRENT_PUBLISH_DIR=!PUBLISH_PATH!\!relativePublishDir!"

        echo "projectName after assignment: !projectName!"
        echo "projectPath after assignment: !projectPath!"
        echo "relativePublishDir after assignment: !relativePublishDir!"
        echo "pubxmlPath after assignment: !pubxmlPath!"
        echo "current publish dir after assignment: !CURRENT_PUBLISH_DIR!"


        echo Publishing !projectName! for win-64...
        rem 清空发布目录
        if exist "!CURRENT_PUBLISH_DIR!" (
            rd /s /q "!CURRENT_PUBLISH_DIR!"
        )
        rem 创建发布目录
        mkdir /p "!CURRENT_PUBLISH_DIR!" 2>nul
        rem 执行 dotnet publish 命令进行 AOT 发布,并指定目标框架
        dotnet publish "!projectPath!" /p:PublishProfile="!pubxmlPath!" -f net9.0-windows -o "!CURRENT_PUBLISH_DIR!"
        rem 检查 dotnet publish 命令的退出代码
        if !errorlevel! neq 0 (
            echo Publish of !projectName! failed!
            endlocal
            exit /b !errorlevel!
        )
        rem 检查发布目录是否存在
        if exist "!CURRENT_PUBLISH_DIR!" (
            rem 删除调试符号文件
            del "!CURRENT_PUBLISH_DIR!\*.pdb"
        )
        echo Publish of !projectName! succeeded!
        echo Published files of !projectName! are located at: "!CURRENT_PUBLISH_DIR!"
    )
)

endlocal

バッチファイルはまずGlobal Assembliesディレクトリ内のファイルをトラバースし、Power Shellスクリプトを実行してプログラムのバージョンを更新します。次に、プロジェクト名、プロジェクトパス、相対パブリッシュディレクトリ名など、プロジェクト情報の配列を定義します。次に,アイテム配列をループすることにより,各アイテムに対して順次公開操作を行う.パブリッシュプロセスでは、パブリッシュディレクトリを空にしてから新しいパブリッシュディレクトリを作成し、dotnet publishコマンドを実行してAOTパブリッシュを行い、ターゲットフレームワークをnet 9.0-windowsに指定します。最後に、パブリッシュが成功したかどうかをチェックし、成功した場合はデバッグシンボルファイルを削除し、成功情報とパブリッシュパスを出力します。

Power Shellスクリプトの自動バージョン更新

次のPower Shellスクリプトは、GitタグTagに基づいてプログラムのバージョンを自動的に更新するために使用します。

param(
	[Parameter(Mandatory=$true)]
	[string]$AssemblyInfoFile,

	[Parameter(Mandatory=$true)]
	[string]$Configuration,

	[Parameter(Mandatory=$true)]
	[string]$Platform
)

# 检查文件是否存在
if (-not (Test-Path $AssemblyInfoFile)) {
    throw "错误:文件 $AssemblyInfoFile 不存在"
}

Write-Output "AssemblyInfoFile: $AssemblyInfoFile"
Write-Output "Configuration: $Configuration"
Write-Output "Platform: $Platform"



#获取当前日期时间,并生成格式化的时间戳
$currentDateTime =Get-Date
#获取当前分支,签出标签创建时间[基准时间]
$strBranchCreateTime =git log -1 --format=%ai $latest_tag
$dateBranchCreateTime=[DateTime]::Parse($strBranchCreateTime)
#时间差的总分数
$timeDifMinutes =[math]::Round(($currentDateTime-$dateBranchcreateTime).TotalMinutes)
#版本号格式处理成x.x.65535.65535
$yy=[math]::Floor($timeDifMinutes/65535)
$thirdInfo=$timeDifMinutes-$yy*65535
#读取文件内容
$content = Get-Content -Path $AssemblyInfoFile -Encoding Unicode
#使用正则表达式获职 AssemblyProduct 的值
$productPattern='^\[assembly: AssemblyProduct\("([^"]+)"\)\]'
$product = ""
#查找包含 AssemblyProduct 的行,并匹配正则表达式
foreach($line in $content){
	if($line -match $productPattern){
		$product= $matches[1]
		break #找到匹配后退出循环
	}
}
$items=$product -split '_'
$product=$items[0]
#当前最近标签、checkout hash值
$currentCommitHash=git describe --always --tag --long
$items=$currentCommitHash.Split('-')
$hashInfo=$items[$items.Length-1]
$firstFileVersion="0.0"
$secondFileVersion="100"
if($items.Length -eq 3)
{
	$firstFileVersion=$items[0].Replace("v","");
	$firstFileItems=$firstFileVersion.split('.');
	$firstFileversion=$firstFileItems[0]+"."+$firstFileItems[1]
	$secondFileVersion=$items[1]+"$yy".PadLeft(2,'0')
}

$platformInfo = ""
if ($Configuration -eq "Debug") {
	$platformInfo = "D"
} elseif ($Configuration -eq "Release") {
	$platformInfo = "R"
} else {
	$platformInfo = "A"
}
switch ($Platform) {
	"x86" {
		$platformInfo += "-86"
	}
	"x64" {
		$platformInfo += "-64"
	}
	"ARM" {
		$platformInfo += "-ARM"
	}
	"AnyCPU" {
		$platformInfo += "-AnyCPU"
	}
	default {
		$platformInfo += "-Unknow"
	}
}

#定义新的 AssemblyProduct和 AssemblyFileversion
$strDayInfo= $currentDateTime.Tostring("yyyyMMddHHmm")
$newAssemblyProduct = "$product"+"_"+"$platformInfo"+"_"+"$hashInfo"+"_"+"$strDayInfo"
if($secondFileVersion -eq "000")
{
	$secondFileVersion="0"
}
$newAssemblyFileVersion = "$firstFileVersion"+"."+"$secondFileVersion"+"."+"$thirdInfo"

# 更新 AssemblyProduct
$content = $content -replace '^\[assembly: AssemblyProduct\(".*"\)\]', "[assembly: AssemblyProduct(`"$newAssemblyProduct`")]"

# 更新AssemblyVersion
$content = $content -replace '^\[assembly: AssemblyVersion\(".*"\)\]', "[assembly: AssemblyVersion(`"$newAssemblyFileVersion`")]"

# 更新AssemblyFileVersion
$content = $content -replace '^\[assembly: AssemblyFileVersion\(".*"\)\]', "[assembly: AssemblyFileVersion(`"$newAssemblyFileVersion`")]"

# 将更新后的内容写入 AssemblyInfo.cs 文件
Set-Content -Path $AssemblyInfoFile -Value $content -Encoding Unicode

このスクリプトは最初に、AssemblyInfoFile(アセンブリ情報ファイルパス)、Configuration(構成名)、Platform(プラットフォーム名)の3つのパラメータを受け取ります。次に、ファイルが存在するかどうかをチェックし、存在しない場合はエラーをスローします次に、現在の日時、Gitタグの作成時刻などの情報を取得することで、バージョン番号の各部分を算出します。構成とプラットフォーム情報に基づいて、新しいAssemblyProductとAssemblyFileVersionを生成します。最後に、ファイル内の古いバージョン情報を正規表現に置き換え、更新された内容をAssemblyInfo.csファイルに書き込むことで、プログラムのバージョンの自動更新を実現します。

これらのスクリプトとメソッドにより、. NETプロジェクトの開発効率を大幅に向上させ、バージョン管理とリリースプロセスを自動化することができます。これらのコンテンツがあなたの開発作業に役立ち、. NET開発の道をより良くすることを願っています。

以上示例脚本可在开源项目找到:dotnet9/CodeWF.Toolbox: CodeWF Toolbox 使用 Avalonia 开发的跨平台工具箱 Cross platform toolbox developed using Avalonia

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2026/01/11

Avalonia ClipboardとDataGridの問題点

Avaloniaデスクトップソフトウェアの最近の開発で解決された2つの問題を文書化します:クリップボードのコピーのクラッシュ、タブの切り替えDataGridのキートン、原因の分析と解決策

继续阅读
同分类 / 同标签 2025/08/09

Avalonia:Resx/XML/JSONフォーマットをシームレスにサポートするAvaloniaの多言語ソリューション

Avaloniaフレームワーク用に特別に設計された多言語管理ライブラリで、プラグインアーキテクチャを通じて多言語サポートロジックを再構築し、従来のResxリソースファイルと互換性があるだけでなく、XMLとJSONフォーマットのサポートを追加し、型セーフなリソース参照、動的言語切り替えなどの機能を提供し、多言語開発をより簡単かつ効率的にします。

继续阅读