Как я могу получить текущий DateTime из прекомпилятора на С#?

StackOverflow https://stackoverflow.com/questions/419507

  •  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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top