Как я могу получить текущий 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 / etc) для манипулирования исходным кодом перед его компиляцией. Я использую это, например, чтобы установить номер версии для текущей версии SVN.
Дешевый вариант - это событие перед сборкой (вы можете сделать это через диалог свойств проекта в VS): по сути, это bat-файл, который запускается перед сборкой; Затем вы можете написать любые изменения, которые вам нужны. Более сложный вариант - это задачи сборки.
Например, служебная библиотека здесь включает в себя задачу Time
и задача FileUpdate
; должно быть (теоретически) возможно связать их вместе, чтобы подражать тому, что вам нужно.
Лично я бы использовал подробности [AssemblyVersion]
, а не время - если вы свяжете это с вашей системой управления версиями, это позволит очень легко найти нарушающую версию; поэтому для моей версии SVN я затем использую (в моей сборке proj):
<!-- 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' />
И теперь моя версия ассемблера верна, включая версию файла, о которой сообщает ОС.
Другие советы
Вы можете получить его из самой 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;
}
Нет эквивалента для директивы препроцессора __ TIME __
в C #. Лучшее, что вы можете сделать, это получить текущую сборку и получить созданную дату, она будет содержать время компиляции. См. здесь
Я не думаю, что есть способ сделать это в C # - определения макросов в стиле C ++ явно запрещены.
Вы можете обойти это, используя либо дату последнего изменения сборки, либо потенциально включить текстовый файл в качестве встроенного ресурса и добавить настраиваемое действие сборки, которое записывает в него текущую дату / время.
Нет директивы препроцессора __ TIME __
, но есть и другие вещи, которые вы можете использовать, например время создания сборки. Вы также можете использовать подстановку ключевых слов из системы управления версиями ($ Date $ в subversion).
А Строить номер можно получить из метаданных сборки и установить в соответствии с датой сборки.
Обычно вы найдете или создадите запись в файле AssemblyInfo.cs.Когда ваш проект создается с помощью Visual Studio.Пример:
[assembly: AssemblyVersion("1.0.*")]
Цитата документации по Атрибут версии сборки.(Некоторые важные части я выделил жирным шрифтом)
Вы можете указать все значения или принять номер сборки по умолчанию, номер ревизии или оба, используя звездочку ().Например, [Ассамблея: Assemblyversion ("2.3.25.1")] указывает 2 в качестве основной версии, 3 в качестве второстепенной версии, 25 в виде номера сборки и 1 в качестве номера ревизии. Номер версии, такой как [сборка: Assemblyversion ("1.2.«)] Определяет 1 как основную версию, 2 как второстепенная версия, и принимает номера по умолчанию и пересмотр по умолчанию. Номер версии, такой как [Assembly: Assemblyversion ("1.2.15.*")] Указывает 1 в качестве основной версии, 2 как второстепенная версия, 15 в качестве номера сборки, и принимает номер ревизии по умолчанию. Номер сборки по умолчанию увеличивается ежедневно.Номер пересмотра по умолчанию является случайным.
Как видите, можно ли с помощью этого установить номер сборки по умолчанию.Номер сборки по умолчанию — это значение, которое увеличивается каждый день.
Затем вы можете получить номер сборки, используя ИмяСборки.Версия свойство.Примеры, предоставленные MSDN, должны помочь вам в этом.
Номер сборки по умолчанию — это количество дней, прошедших с 01.01.2000.
Этот вопрос также есть четкое объяснение того, как это использовать.
Вы ищете что-то вроде этого:
(Получить дату сборки сборки с помощью Version-Info; Build-Number - количество дней с 1.1.2000)
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime versionsDatum = new DateTime(2000, 1, 1);
versionsDatum = versionsDatum.AddDays(version.Build);