C#のプリコンパイラから現在のDateTimeを取得するにはどうすればよいですか?
-
03-07-2019 - |
質問
C#3.0には、クラスのバージョンを含むと想定されるプロパティがあります。バージョン番号は、単にコンパイルの日付と時刻です。現在、次のコードがあります:
public DateTime Version
{
get { return DateTime.UtcNow; }
}
明らかに、このプロパティは現在の日付と時刻を返すため、これは間違っています。 では、プリコンパイラはコンパイル時にDateTimeを印刷できますか?この場合、次のようなことができます。
public DateTime Version
{
get { return new DateTime("PRECOMPILER DATE"); }
}
解決
C#にはマクロの概念がありません。ただし、ビルドスクリプトの他のツール(csproj / NANT /など)を使用して、コンパイルする前にソースを操作できます。たとえば、これを使用して、リビジョン番号を現在のSVNリビジョンに設定します。
安価なオプションは、ビルド前のイベントです(VSのプロジェクトプロパティダイアログでこれを行うことができます)。基本的に、ビルド前に実行されるbatファイル。その後、必要な変更をスクリプト化できます。より洗練されたオプションはビルドタスクです。
たとえば、ユーティリティライブラリこちらには、 Time
タスクと FileUpdate
タスク。 (理論的には)必要なものをエミュレートするために2つを連鎖させることができるはずです。
個人的には、時間ではなく [AssemblyVersion]
の詳細を使用します。これをソース管理システムにリンクすると、問題のあるバージョンを簡単に見つけることができます。 SVNバージョンの場合、(ビルドプロジェクトで)を使用します。
<!-- See http://msbuildtasks.tigris.org -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...
<SvnInfo LocalPath=".">
<Output TaskParameter="Revision" PropertyName="BuildRev" />
</SvnInfo>
...
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
ReplacementText='$1.$2.$(BuildRev)$5' />
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
ReplacementText='$1.$2.$(BuildRev)$5' />
これで、OSによって報告されるファイルバージョンを含むアセンブリバージョンが正しくなりました。
他のヒント
dll自体から取得できます(出典:codinghorror )
private DateTime RetrieveLinkerTimestamp() {
string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
const int c_PeHeaderOffset = 60;
const int c_LinkerTimestampOffset = 8;
byte[] b = new byte[2048];
System.IO.Stream s = null;
try {
s = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
s.Read(b, 0, 2048);
} finally {
if (s != null) {
s.Close();
}
}
int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);
dt = dt.AddSeconds(secondsSince1970);
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
return dt;
}
C#の __ TIME __
プリプロセッサディレクティブに相当するものはありません。最善の方法は、現在のアセンブリを取得し、作成日を取得することです。これにはコンパイル時間が含まれます。 こちら
C#でこれを行う方法はないと思います-C ++スタイルのマクロ定義は明示的に禁止されています。
アセンブリの最終変更日を使用して回避するか、埋め込みリソースとしてテキストファイルを含め、現在の日付/時刻を書き込むカスタムビルドアクションを追加する可能性があります。
プリプロセッサ __ TIME __
ディレクティブはありませんが、アセンブリの作成時間など、他に使用できるものがあります。ソース管理システムからのキーワード置換の使用を検討することもできます(subversionでは$ Date $)。
ビルドは次から取得できます。アセンブリのメタデータ。ビルドの日付と一致するように設定できます。
通常、AssemblyInfo.csファイルにエントリを見つけるか、作成します。 Visual Studioを使用してプロジェクトが作成されたとき。例:
[assembly: AssemblyVersion("1.0.*")]
AssemblyVersionAttribute のドキュメントの引用。 (重要な部分を太字で示しています)
すべての値を指定するか、または デフォルトのビルド番号を受け入れることができます、 リビジョン番号、またはその両方を使用して アスタリスク()。例えば、 [assembly:AssemblyVersion(&quot; 2.3.25.1&quot;)] メジャーバージョンとして2、3として3を示します マイナーバージョン、ビルドとして25 番号、およびリビジョン番号として1。 次のようなバージョン番号 [assembly:AssemblyVersion(&quot; 1.2。 &quot;)] メジャーバージョンとして1、2として2を指定します マイナーバージョン、および受け入れます デフォルトのビルド番号とリビジョン番号。 A などのバージョン番号 [assembly:AssemblyVersion(&quot; 1.2.15。*&quot;)] メジャーバージョンとして1、2として2を指定します マイナーバージョン、ビルドとして15 番号、およびデフォルトを受け入れます リビジョン番号。 デフォルトのビルド 数は毎日増加します。デフォルト リビジョン番号はランダムです。
ご覧のとおり、これでデフォルトのビルド番号を設定できるかどうか。デフォルトのビルド番号は、毎日増加する値です。
AssemblyName.Version プロパティ。 MSDNが提供するサンプルをご覧ください。
デフォルトのビルド番号は、1/1/2000以降の日数です。
この質問また、これの使用方法に関する明確な説明があります。
次のようなものをお探しですか:
(Version-Infoを使用してアセンブリをビルドする日付を取得します。ビルド番号は2000年1月1日からの日数です)
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime versionsDatum = new DateTime(2000, 1, 1);
versionsDatum = versionsDatum.AddDays(version.Build);