123

バージョン管理としてGitを使用して、C#アプリケーションを構築しています。

アプリケーションをビルドするときに、実行可能ファイルに最後のコミットハッシュを自動的に埋め込む方法はありますか?

たとえば、コミットハッシュをコンソールに出力すると、次のようになります。

class PrintCommitHash
{
    private String lastCommitHash = ?? // What do I put here?
    static void Main(string[] args)
    {
        // Display the version number:
        System.Console.WriteLine(lastCommitHash );
    }
}

デプロイされた実行可能ファイルではgitリポジトリにアクセスできないため、これは実行時ではなくビルド時に実行する必要があることに注意してください。

C ++に関連する質問は、ここにあります。

編集

@mattanjaのリクエストに従って、プロジェクトで使用するgitフックスクリプトを投稿しています。セットアップ:

  • フックはLinuxシェルスクリプトであり、path_to_project \ .git\hooksの下に配置されます。
  • msysgitを使用している場合、hooksフォルダーにはすでにいくつかのサンプルスクリプトが含まれています。gitにそれらを呼び出させるには、スクリプト名から「.sample」拡張子を削除します。
  • フックスクリプトの名前は、それらを呼び出すイベントと一致します。私の場合、post-commitpost-mergeを変更しました。
  • 私のAssemblyInfo.csファイルはプロジェクトパスのすぐ下にあります( .gitフォルダーと同じレベル)。23行含まれており、gitを使用して24行目を生成します。

私のLinuxシェルは少し錆びているので、スクリプトはAssemblyInfo.csの最初の23行を一時ファイルに読み取り、gitハッシュを最後の行にエコーし、ファイルの名前をAssemblyInfo.csに戻します。これを行うためのより良い方法があると確信しています:

#!/bin/sh
cmt=$(git rev-list --max-count=1 HEAD)
head -23 AssemblyInfo.cs > AssemblyInfo.cs.tmp
echo [assembly: AssemblyFileVersion\(\"$cmt\"\)] >> AssemblyInfo.cs.tmp
mv AssemblyInfo.cs.tmp AssemblyInfo.cs

お役に立てれば。

4

17 に答える 17

87

version.txtファイルを実行可能ファイルに埋め込んでから、実行可能ファイルからversion.txtを読み取ることができます。version.txtファイルを作成するには、git describe --long

手順は次のとおりです。

ビルドイベントを使用してgitを呼び出す

  • プロジェクトを右クリックして、[プロパティ]を選択します

  • ビルドイベントで、以下を含むビルド前イベントを追加します(引用符に注意してください)。

    "C:\ Program Files \ Git \ bin \ git.exe" describe --long> "$(ProjectDir)\ version.txt"

    これにより、プロジェクトディレクトリにversion.txtファイルが作成されます。

実行可能ファイルにversion.txtを埋め込みます

  • プロジェクトを右クリックして、[既存のアイテムの追加]を選択します
  • version.txtファイルを追加します(すべてのファイルが表示されるようにファイルチューザーフィルターを変更します)
  • version.txtを追加したら、ソリューションエクスプローラーで右クリックして、[プロパティ]を選択します。
  • ビルドアクションを埋め込みリソースに変更します
  • [出力ディレクトリにコピー]を[常にコピー]に変更します
  • version.txt.gitignoreファイルに追加します

埋め込まれたテキストファイルのバージョン文字列を読み取る

埋め込まれたテキストファイルのバージョン文字列を読み取るためのサンプルコードを次に示します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace TryGitDescribe
{
    class Program
    {
        static void Main(string[] args)
        {
            string gitVersion= String.Empty;
            using (Stream stream = Assembly.GetExecutingAssembly()
                    .GetManifestResourceStream("TryGitDescribe." + "version.txt"))
            using (StreamReader reader = new StreamReader(stream))
            {
                gitVersion= reader.ReadToEnd();
            }

            Console.WriteLine("Version: {0}", gitVersion);
            Console.WriteLine("Hit any key to continue");
            Console.ReadKey();
        }
    }
}
于 2013-02-28T20:33:27.620 に答える
80

アップデート:

私が最初にこの質問に答えて以来、物事は進化してきました。(Microsoft.NET.Sdksdkスタイルのプロジェクトを使用している必要があることを意味します)には、いくつかの条件が満たされた場合に、アセンブリ情報バージョンとnugetパッケージメタデータの両方にコミットハッシュを追加するためのサポートが含まれるようになりました。

  1. <SourceRevisionId>プロパティを定義する必要があります。これは、次のようなターゲットを追加することで実行できます。
<Target Name="SetSourceRevisionId" BeforeTargets="InitializeSourceControlInformation">
    <Exec 
      Command="git describe --long --always --dirty --exclude=* --abbrev=8"
      ConsoleToMSBuild="True"
      IgnoreExitCode="False"
      >
      <Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput"/>
    </Exec>
  </Target>

このターゲットはSourceRevisionId、短縮(8文字)ハッシュに設定されるコマンドを実行します。BeforeTargetsにより、アセンブリ情報バージョンが作成される前にこれが実行されます。

  1. nugetパッケージメタデータにハッシュを含めるには、<RepositoryUrl>も定義する必要があります。

  2. <SourceControlInformationFeatureSupported>プロパティはである必要がありますtrue。これにより、nugetパックタスクもSourceRevisionIdを取得します。

この新しい手法はよりクリーンで一貫性があるため、MSBuildGitHashパッケージの使用を避けます。

オリジナル:

プロジェクトに含めることができる単純なnugetパッケージを作成しました。これは、これを処理します:https ://www.nuget.org/packages/MSBuildGitHash/

このnugetパッケージは、「純粋な」MSBuildソリューションを実装します。nugetパッケージに依存したくない場合は、これらのターゲットをcsprojファイルにコピーするだけで、カスタムアセンブリ属性としてgitハッシュを含める必要があります。

<Target Name="GetGitHash" BeforeTargets="WriteGitHash" Condition="'$(BuildHash)' == ''">
  <PropertyGroup>
    <!-- temp file for the git version (lives in "obj" folder)-->
    <VerFile>$(IntermediateOutputPath)gitver</VerFile>
  </PropertyGroup>

  <!-- write the hash to the temp file.-->
  <Exec Command="git -C $(ProjectDir) describe --long --always --dirty &gt; $(VerFile)" />

  <!-- read the version into the GitVersion itemGroup-->
  <ReadLinesFromFile File="$(VerFile)">
    <Output TaskParameter="Lines" ItemName="GitVersion" />
  </ReadLinesFromFile>
  <!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
  <PropertyGroup>
    <BuildHash>@(GitVersion)</BuildHash>
  </PropertyGroup>    
</Target>

<Target Name="WriteGitHash" BeforeTargets="CoreCompile">
  <!-- names the obj/.../CustomAssemblyInfo.cs file -->
  <PropertyGroup>
    <CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
  </PropertyGroup>
  <!-- includes the CustomAssemblyInfo for compilation into your project -->
  <ItemGroup>
    <Compile Include="$(CustomAssemblyInfoFile)" />
  </ItemGroup>
  <!-- defines the AssemblyMetadata attribute that will be written -->
  <ItemGroup>
    <AssemblyAttributes Include="AssemblyMetadata">
      <_Parameter1>GitHash</_Parameter1>
      <_Parameter2>$(BuildHash)</_Parameter2>
    </AssemblyAttributes>
  </ItemGroup>
  <!-- writes the attribute to the customAssemblyInfo file -->
  <WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
</Target>

ここには2つのターゲットがあります。最初の「GetGitHash」は、gitハッシュをBuildHashという名前のMSBuildプロパティにロードします。これは、BuildHashがまだ定義されていない場合にのみ実行されます。これにより、必要に応じて、コマンドラインでMSBuildに渡すことができます。次のようにMSBuildに渡すことができます。

MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL

2番目のターゲット「WriteGitHash」は、「CustomAssemblyInfo.cs」という名前の一時的な「obj」フォルダー内のファイルにハッシュ値を書き込みます。このファイルには、次のような行が含まれます。

[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]

このCustomAssemblyInfo.csファイルはアセンブリにコンパイルされるため、リフレクションを使用して実行時に検索できAssemblyMetadataます。次のコードは、AssemblyInfoクラスが同じアセンブリに含まれている場合にこれを実行する方法を示しています。

using System.Linq;
using System.Reflection;

public static class AssemblyInfo
{
    /// <summary> Gets the git hash value from the assembly
    /// or null if it cannot be found. </summary>
    public static string GetGitHash()
    {
        var asm = typeof(AssemblyInfo).Assembly;
        var attrs = asm.GetCustomAttributes<AssemblyMetadataAttribute>();
        return attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value;
    }
}

この設計のいくつかの利点は、プロジェクトフォルダー内のファイルに影響を与えず、変更されたすべてのファイルが「obj」フォルダーの下にあることです。プロジェクトは、VisualStudio内またはコマンドラインからも同じようにビルドされます。また、プロジェクトに合わせて簡単にカスタマイズでき、csprojファイルとともにソース制御されます。

于 2017-07-21T23:23:54.723 に答える
68

gitでタグを使用してバージョンを追跡します。

git tag -a v13.3.1 -m "version 13.3.1"

次の方法でgitからハッシュ付きのバージョンを取得できます。

git describe --long

ビルドプロセスでは、GitハッシュをAssemblyInfo.csファイルのAssemblyInformationalVersion属性に配置します。

[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]

コンパイルすると、Windowsエクスプローラーからバージョンを表示できます。

ここに画像の説明を入力してください

プログラムで入手することもできます。

var build = ((AssemblyInformationalVersionAttribute)Assembly
  .GetAssembly(typeof(YOURTYPE))
  .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
  .InformationalVersion;

ここで、YOURTYPEは、AssemblyInformationalVersion属性を持つアセンブリ内の任意のタイプです。

于 2013-02-28T19:14:54.387 に答える
14

これを行う別の方法は、オンボードVisualStudioの魔法でNetRevisionToolを使用することです。ここでは、これをVisual Studio 2013 Professional Editionで紹介しますが、これは他のバージョンでも機能します。

したがって、最初にNetRevisionToolをダウンロードします。NetRevisionTool.exeをPATHに含めるか、リポジトリにチェックインして、Visual Studioのビルド前およびビルド後のアクションを作成し、AssemblyInfo.csを変更します。

AssemblyInformationVersionにgit-hashを追加する例は、次のとおりです。プロジェクト設定:

ここに画像の説明を入力してください

プロジェクトのAssemblyInfo.csで、次の行を変更/追加します。

[アセンブリ:AssemblyInformationalVersion( "1.1。{dmin:2015}。{chash:6} {!}-{branch}")]

示されているスクリーンショットでは、External/binフォルダーのNetRevisionTool.exeをチェックインしました

ビルド後、バイナリを右クリックしてプロパティに移動すると、次のようなものが表示されます。

ここに画像の説明を入力してください

これが誰かに役立つことを願っています

于 2015-03-23T12:04:37.627 に答える
14

この質問は、完全なステップバイステップの回答を与える価値があると思います。ここでの戦略は、テンプレートファイルを取り込んで、gitタグとコミットカウント情報が含まれるAssemblyInfo.csファイルを生成するビルド前のイベントからPowerShellスクリプトを実行することです。

手順1:元のAssemblyInfo.csに基づいて、Project \ PropertiesフォルダーにAssemblyInfo_template.csファイルを作成しますが、次のものが含まれます。

[assembly: AssemblyVersion("$FILEVERSION$")]
[assembly: AssemblyFileVersion("$FILEVERSION$")]
[assembly: AssemblyInformationalVersion("$INFOVERSION$")]

手順2:ソースが次のInjectGitVersion.ps1という名前のPowerShellスクリプトを作成します。

# InjectGitVersion.ps1
#
# Set the version in the projects AssemblyInfo.cs file
#


# Get version info from Git. example 1.2.3-45-g6789abc
$gitVersion = git describe --long --always;

# Parse Git version info into semantic pieces
$gitVersion -match '(.*)-(\d+)-[g](\w+)$';
$gitTag = $Matches[1];
$gitCount = $Matches[2];
$gitSHA1 = $Matches[3];

# Define file variables
$assemblyFile = $args[0] + "\Properties\AssemblyInfo.cs";
$templateFile =  $args[0] + "\Properties\AssemblyInfo_template.cs";

# Read template file, overwrite place holders with git version info
$newAssemblyContent = Get-Content $templateFile |
    %{$_ -replace '\$FILEVERSION\$', ($gitTag + "." + $gitCount) } |
    %{$_ -replace '\$INFOVERSION\$', ($gitTag + "." + $gitCount + "-" + $gitSHA1) };

# Write AssemblyInfo.cs file only if there are changes
If (-not (Test-Path $assemblyFile) -or ((Compare-Object (Get-Content $assemblyFile) $newAssemblyContent))) {
    echo "Injecting Git Version Info to AssemblyInfo.cs"
    $newAssemblyContent > $assemblyFile;       
}

手順3: InjectGitVersion.ps1ファイルをBuildScriptsフォルダーのソリューションディレクトリに保存します

ステップ4:プロジェクトのビルド前イベントに次の行を追加します

powershell -ExecutionPolicy ByPass -File  $(SolutionDir)\BuildScripts\InjectGitVersion.ps1 $(ProjectDir)

ステップ5:プロジェクトをビルドします。

ステップ6:必要に応じて、AssemblyInfo.csをgitignoreファイルに追加します

于 2016-09-22T20:50:47.883 に答える
4

MSBuildの.NETリビジョンタスクとVisualStudio2019の操作が非常に簡単になりました。

NuGetパッケージUnclassified.NetRevisionTaskをインストールし、 GitHubドキュメントAssemblyInfo.csの説明に従って、ファイルに必要な情報を構成するだけです。

最後のコミット(長さ= 8)のハッシュのみが必要な場合:

[assembly: AssemblyInformationalVersion("1.0-{chash:8}")]

プロジェクト/ソリューションを構築すると、次のようになります。

ここに画像の説明を入力してください

于 2020-01-24T16:48:48.597 に答える
3

他の回答ではすでにgitビットについて言及しているので、SHAを取得したら、AssemblyInfo.csビルド前のフックでプロジェクトのファイルを生成することを検討できます。

これを行う1つの方法はAssemblyInfo.cs.tmpl、SHAのプレースホルダーを$$ GITSHA $$とすると、テンプレートファイルを作成することです。

[assembly: AssemblyDescription("$$GITSHA$$")]

次に、ビルド前のフックでこのプレースホルダーを置き換え、C#コンパイラが取得できるようにAssemblyInfo.csファイルを出力する必要があります。

SubWCRev for SVNを使用してこれを行う方法については、この回答を参照してください。gitで同様のことをするのは難しいことではありません。

他の方法は、前述の「makeステージ」です。つまり、同様のことを行うMSBuildタスクを記述します。さらに別の方法は、DLLを何らかの方法で後処理することです(ildasm + ilasmと言います)が、上記のオプションがおそらく最も簡単だと思います。

于 2013-02-28T18:46:42.870 に答える
3

完全に自動化された柔軟なメソッドチェックアウトについては、https://github.com/Fody/Stampをご覧ください。これをGitプロジェクト(およびSVNプロジェクトのこのバージョン)で正常に使用しました

更新:Stamp.Fodyが維持されなくなったため、これは古くなっています

于 2016-12-17T15:18:59.993 に答える
2

PowerShellワンライナーを使用して、すべてのAssemblyinfoファイルをコミットハッシュで更新できます。

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }
于 2016-12-02T08:10:29.450 に答える
1
  1. ビルド時に外部プログラムを呼び出して出力をインターセプトする方法を知っているといいのですが。
  2. gitの作業ディレクトリでバージョン管理されていないファイルを無視する方法を知っているといいのですが。

@ learath2で指摘されているように、の出力はgit rev-parse HEADプレーンハッシュを提供します。

Gitリポジトリでタグを使用する場合(そしてタグを使用する場合は、より説明的で読みやすいのではないでしょうかgit rev-parse)、出力はから受信される可能性がありますgit describe(後で正常に使用されgit checkoutます)

次の場所でrev-parse|describeを呼び出すことができます。

于 2013-02-28T18:30:12.443 に答える
1

私は受け入れられた答えと小さな追加の組み合わせを使用しています。AutoT4拡張機能(https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4)をインストールして、ビルド前にテンプレートを再実行します。

GITからバージョンを取得する

git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"プロジェクトプロパティのビルド前イベントにあります。git_version.txtとVersionInfo.csを.gitignoreに追加することは非常に良い考えです。

メタデータにバージョンを埋め込む

VersionInfo.ttプロジェクトにテンプレートを追加しました。

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

<#
if (File.Exists(Host.ResolvePath("git_version.txt")))
{
    Write("[assembly: AssemblyInformationalVersion(\""+ File.ReadAllText(Host.ResolvePath("git_version.txt")).Trim() + "\")]");
}else{
    Write("// version file not found in " + Host.ResolvePath("git_version.txt"));
}

#>

これで、「ProductVersion」にgitタグとハッシュが追加されました。

于 2017-05-31T07:34:49.537 に答える
1

もう1つの方法は、ビルド前のステップからVersion.csファイルを生成することです。現在のコミットハッシュを出力する小さな概念実証プロジェクトでこれを調査しました。

プロジェクトはhttps://github.com/sashoalm/GitCommitHashPrinterにアップロードされています。

Version.csファイルを作成するバッチコードは次のとおりです。

@echo off

echo "Writing Version.cs file..."

@rem Pushd/popd are used to temporarily cd to where the BAT file is.
pushd $(ProjectDir)

@rem Verify that the command succeeds (i.e. Git is installed and we are in the repo).
git rev-parse HEAD || exit 1

@rem Syntax for storing a command's output into a variable (see https://stackoverflow.com/a/2340018/492336).
@rem 'git rev-parse HEAD' returns the commit hash.
for /f %%i in ('git rev-parse HEAD') do set commitHash=%%i

@rem Syntax for printing multiline text to a file (see https://stackoverflow.com/a/23530712/492336).
(
echo namespace GitCommitHashPrinter
echo {
echo     class Version
echo     {
echo         public static string CommitHash { get; set; } = "%commitHash%";
echo     }
echo }
)>"Version.cs"

popd    
于 2018-08-01T11:00:45.563 に答える
1
  • を開き、最初.csprojに追加します<GenerateAssemblyInfo>false</GenerateAssemblyInfo>PropertyGroup
    • AssemblyInfo.csフォルダーに既に生成されている内容をコピーして、objすべてを自分で作成する必要がないようにすることもできます。
  • AssemblyInfo.ttプロパティフォルダに(T4テンプレート)を作成します。
  • 次のコンテンツと以前に自動生成された古いコンテンツを貼り付けますAssemblyInfo.cs
<#@ template debug="true" hostspecific="True" language="C#" #>
<#@ assembly name="System.Core" #>
<# /*There's a bug with VS2022 where you have to be real specific about envDTE.*/ #>
<#@ assembly name="./PublicAssemblies/envdte.dll" #>  
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Globalization" #>
<#@ output extension=".cs" #>
<#
    var dte = ((IServiceProvider)this.Host).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
    string buildConfig = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
    string solutionDirectory = Path.GetDirectoryName(dte.Solution.FullName);

    var (gitRevision, gitBranch, gitCompactRevision) = ("", "", "");

    using(var process = new System.Diagnostics.Process() {
        StartInfo = new System.Diagnostics.ProcessStartInfo() {
            WorkingDirectory = solutionDirectory,
            FileName = @"cmd.exe",
            Arguments = "/C git rev-parse HEAD & git rev-parse --abbrev-ref HEAD",
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        }
    }) {
        process.Start();
        string[] lines = process.StandardOutput.ReadToEnd().Split();
        gitRevision = lines[0].Trim();
        gitBranch = lines[1].Trim();
        gitCompactRevision = gitRevision.Substring(0, 6);
    }
    string appPurpose         = "Launcher"; // & Updater
    string companyShort       = "todo";
    string companyFull        = "todo";
    string productNameShort   = "todo";
    string productName        = $"{companyShort} {productNameShort}";
    string fileName           = $"{companyShort}{productNameShort}";
    string exeNAME            = $"{fileName}Launch";
    string originalFilename   = $"{exeNAME}.exe";
    string CALLEXE            = $"{fileName}.exe";
    string BROWSEREXE         = $"{fileName}Browser.exe";
    string FULLINSTALLER      = $"{fileName}Setup.exe";

    DateTime dtBuiltDate      = DateTime.UtcNow;
    string cBuildYear         = dtBuiltDate.Year.ToString();
    string cBuildDay          = dtBuiltDate.ToString("dd");
    string cBuildMonth        = dtBuiltDate.ToString("MM");
    string cBuildTime         = dtBuiltDate.ToString("T", DateTimeFormatInfo.InvariantInfo);
    string assemblyVersion    = $"3.0.{cBuildYear}.{cBuildMonth}{cBuildDay}";

    string JOB_NAME           = System.Environment.GetEnvironmentVariable("JOB_NAME") ?? "0.0";
    string buildVersion       = System.Environment.GetEnvironmentVariable("BUILD_NUMBER") ?? "0-dev";
    string buildSeries        = Regex.Replace(JOB_NAME, @"[^0-9\.]+", "");
    string buildNumber        = Regex.Replace(buildVersion, @"[^0-9\.]+", "");
    string InternalVersion    = $"{JOB_NAME}.{buildVersion}";
    string fileVersion        = Regex.Replace(InternalVersion, @"[^0-9\.]+", "");
#>
using System.Reflection;

[assembly: System.Runtime.InteropServices.ComVisible(false)]
[assembly: System.Resources.NeutralResourcesLanguageAttribute("en")]
[assembly: AssemblyConfigurationAttribute("<#= buildConfig #>")]
[assembly: AssemblyProduct("<#= productName #>")]
[assembly: AssemblyTitle("<#= $"{companyShort}{productNameShort}" #>")]
[assembly: AssemblyCompany("<#= companyFull #>")]
[assembly: AssemblyDescription("<#= $"{companyShort} {productNameShort} .... {appPurpose} - ...... by {companyFull}" #>")]
[assembly: AssemblyCopyright("<#= $"© 1983-{cBuildYear} {companyFull}" #>")]
[assembly: AssemblyTrademark("<#= $"{productName} is a trademark of {companyFull}, Inc." #>")]
[assembly: AssemblyInformationalVersion("<#= InternalVersion #>")]
[assembly: AssemblyVersion("<#= assemblyVersion #>")]
[assembly: AssemblyFileVersion("<#= fileVersion #>")]
[assembly: AssemblyMetadataAttribute("OriginalFilename",    "<#= originalFilename #>")]
[assembly: AssemblyMetadataAttribute("NAME",                "<#= $"{productName} {appPurpose}" #>")]
[assembly: AssemblyMetadataAttribute("EXENAME",             "<#= exeNAME #>")]
[assembly: AssemblyMetadataAttribute("DIRNAME",             "<#= productNameShort #>")]
[assembly: AssemblyMetadataAttribute("CALLEXE",             "<#= $"{fileName}.exe" #>")]
[assembly: AssemblyMetadataAttribute("BROWSEREXE",          "<#= $"{fileName}Browser.exe" #>")]
[assembly: AssemblyMetadataAttribute("FULLINSTALLER",       "<#= $"{fileName}Setup.exe" #>")]
[assembly: AssemblyMetadataAttribute("COMPANY",             "<#= companyFull #>")]
[assembly: AssemblyMetadataAttribute("License",             "<#= $"Contains copyrighted code and applications ..." #>")]
[assembly: AssemblyMetadataAttribute("TermsOfUse",          "<#= "https://www.company.com/en-us/terms-of-use/" #>")]
[assembly: AssemblyMetadataAttribute("Website",             "<#= "https://www.company.com/en-us" #>")]
[assembly: AssemblyMetadataAttribute("UpdateURL",           "https://subdomain.product.net/version_check")]

[assembly: AssemblyMetadataAttribute("BuildYear",           "<#= cBuildYear #>")]
[assembly: AssemblyMetadataAttribute("BuildDay",            "<#= cBuildDay #>")]
[assembly: AssemblyMetadataAttribute("BuildMonth",          "<#= cBuildMonth #>")]
[assembly: AssemblyMetadataAttribute("BuildTime",           "<#= cBuildTime #>")]
[assembly: AssemblyMetadataAttribute("DateModified",        "<#= $"{dtBuiltDate.ToString("MMM dd, yyyy", DateTimeFormatInfo.InvariantInfo)} at {cBuildTime}" #>")]

[assembly: AssemblyMetadataAttribute("BuildSeries",         "<#= buildSeries #>")]
[assembly: AssemblyMetadataAttribute("BuildNumber",         "<#= buildNumber #>")]
[assembly: AssemblyMetadataAttribute("BuildDate",           "<#= dtBuiltDate.ToString("s") #>")]
[assembly: AssemblyMetadataAttribute("BuildMachine",        "<#= Environment.MachineName #>")]
[assembly: AssemblyMetadataAttribute("BuildMachineUser",    "<#= Environment.UserName #>")]
[assembly: AssemblyMetadataAttribute("BuildOSVersion",      "<#= Environment.OSVersion #>")]
[assembly: AssemblyMetadataAttribute("BuildPlatform",       "<#= Environment.OSVersion.Platform #>")]
[assembly: AssemblyMetadataAttribute("BuildClrVersion",     "<#= Environment.Version #>")]

[assembly: AssemblyMetadataAttribute("BuildBranch",         "<#= gitBranch #>")]
[assembly: AssemblyMetadataAttribute("BuildRevision",       "<#= gitCompactRevision #>")]
[assembly: AssemblyMetadataAttribute("CommitHash",          "<#= gitRevision #>")]
[assembly: AssemblyMetadataAttribute("RepositoryUrl",       "")]
[assembly: AssemblyMetadataAttribute("RepositoryType",      "")]
<#+

#>

これで、C#の全機能を使用して、現在使用しているgitブランチやリビジョンなど、必要なものを生成できます。いくつかのヒント:

  • <# #>変数はブロック内のどこでも宣言できます
  • 使用するメソッドはすべて、<#+ #>ブロック内のファイルの最後で宣言する必要があります。(+記号は非常に重要であり、ファイルの最後にある必要があります))
  • ブロックの外側はすべて<# #>プレーンテキストです。
  • VS2019には、構文の強調表示やインテリセンスはありません。.ttファイルはプレーンテキストです。拡張機能をインストールした後、vscodeで編集することをお勧めしT4 Supportます(vs2019では使用できません...)
于 2021-09-22T14:12:18.113 に答える
0

別の回答(https://stackoverflow.com/a/44278482/4537127 )を参照すると、 AutoT4なしVersionInfo.ttで生成するためにテキストテンプレートも利用しました。AssemblyInformationalVersion

(少なくとも私のC#WPFアプリケーションで動作します)

問題は、ビルド前のイベントがテンプレートの変換後に実行されたため、クローン作成後、git_version.txtファイルが存在せず、ビルドが失敗することでした。変換を1回通過できるように手動で作成した後、変換後に更新され、常に1コミット遅れていました。

.csprojファイルに2つの調整を加える必要がありました(これは少なくともVisual Studio Community 2017に適用されます)

1)テキスト変換ターゲットをインポートし、すべてのビルドで実行するテンプレート変換を行います:(https://msdn.microsoft.com/en-us/library/ee847423.aspxを参照)

<PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
    <TransformOnBuild>true</TransformOnBuild>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

以降<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

2)git describeテンプレート変換の前に実行します(変換されるgit_version.txtときに実行されVersionInfo.ttます):

<Target Name="PreBuild" BeforeTargets="ExecuteTransformations">
  <Exec Command="git -C $(ProjectDir) describe --long --always --dirty &gt; $(ProjectDir)git_version.txt" />
</Target>

..そして取得するC#コードAssemblyInformationalVersion(参照https://stackoverflow.com/a/7770189/4537127

public string AppGitHash
{
    get
    {
        AssemblyInformationalVersionAttribute attribute = (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

        return attribute.InformationalVersion;
    }
}

..そして生成されたファイルを.gitignoreに追加します

VersionInfo.cs
git_version.txt
于 2017-07-04T22:20:40.310 に答える
0

場所

<Target Name="UpdateVersion" BeforeTargets="CoreCompile">
  <Exec Command="php &quot;$(SolutionDir)build.php&quot; $(SolutionDir) &quot;$(ProjectDir)Server.csproj&quot;" />
</Target>

YOUR_PROJECT_NAME.csproj

<?php

function between(string $string, string $after, string $before, int $offset = 0) : string{
    return substr($string, $pos = strpos($string, $after, $offset) + strlen($after),
        strpos($string, $before, $pos) - $pos);
}

$pipes = [];
$proc = proc_open("git rev-parse --short HEAD", [
    0 => ["pipe", "r"],
    1 => ["pipe", "w"],
    2 => ["pipe", "w"]
], $pipes, $argv[1]);

if(is_resource($proc)){
    $rev = stream_get_contents($pipes[1]);
    proc_close($proc);
}

$manifest = file_get_contents($argv[2]);
$version = between($manifest, "<Version>", "</Version>");
$ver = explode("-", $version)[0] . "-" . trim($rev);
file_put_contents($argv[2], str_replace($version, $ver, $manifest));

echo "New version generated: $ver" . PHP_EOL;

于 2020-02-17T06:15:09.143 に答える
0

@John Jesusの回答に大きく影響を受けて、各ビルドで実行されるPowershell v1スクリプトを作成し、アセンブリバージョンを現在のGitタグに調整しました。

Powershellスクリプト

# Get build running directory
$scriptPath = split-path -parent $MyInvocation.MyCommand.Path
try {
    $v = git describe --tags
}
catch [System.Management.Automation.CommandNotFoundException] {
    # Git not found
    exit
}

# Letters are incompatible with AssemblyVersion.cs so we remove them
$v = $v -replace "v", ""
# Version format is major[.minor[.build[.revision]] so we remove them
$v = $v -replace "-(\D.*)", ''
$v = $v -replace "-", '.'

# We replace versions inside AssemblyInfo.cs content
$info = (Get-Content ($scriptPath + "/properties/AssemblyInfo.cs"))
$av = '[assembly: AssemblyVersion("'+$v+'")]'
$avf = '[assembly: AssemblyFileVersion("'+$v+'")]'
$info = $info -replace '\[assembly: AssemblyVersion\("(.*)"\)]', $av
$info = $info -replace '\[assembly: AssemblyFileVersion\("(.*)"\)]', $avf
Set-Content -Path ($scriptPath + "/properties/AssemblyInfo.cs") -Value $info -Encoding UTF8

ソリューションフォルダに配置し、ビルド前イベントを設定して起動します。 prebuild-event

于 2021-08-18T14:56:24.373 に答える
0

これらのファイルを開発/ステージングシステムにデプロイして、簡単に確認します。

git.exe -C "$(ProjectDir.TrimEnd('\'))" describe --long > "$(ProjectDir)_Version.info":

MyResult:10.02.0.3-247-gbeeadd082

git.exe -C "$(ProjectDir.TrimEnd('\'))" branch --show-current > "$(ProjectDir)_Branch.info"

MyResult:feature/JMT-3931-ジャガー

(Visual Studio PreBuildイベント)

于 2022-03-04T13:26:26.080 に答える