Как я могу получить текущий DateTime из прекомпилятора в C #? - PullRequest
6 голосов
/ 07 января 2009

В C # 3.0 у меня есть свойство, которое должно содержать версию класса. Номер версии - это просто дата и время компиляции. Прямо сейчас у меня есть следующий код:

public DateTime Version
{
    get { return DateTime.UtcNow; }
}

Очевидно, что это неправильно, так как это свойство возвращает мне текущие дату и время. Итак, может ли прекомпилятор напечатать DateTime во время компиляции? В этом случае я мог бы сделать что-то похожее на приведенное ниже.

public DateTime Version
{
    get { return new DateTime("PRECOMPILER DATE"); }
}

Ответы [ 7 ]

8 голосов
/ 07 января 2009

Вы можете получить его из самой 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;
    }
7 голосов
/ 07 января 2009

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' />

И теперь моя сборочная версия верна, включая версию файла, о которой сообщает ОС.

3 голосов
/ 07 января 2009

Нет эквивалента директиве препроцессора __TIME__ в C #. Лучшее, что вы можете сделать, это получить текущую сборку и получить созданную дату, она будет содержать время компиляции. Смотри здесь

0 голосов
/ 28 августа 2009

Вы ищете что-то вроде этого:
(Получить дату сборки сборки с помощью 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);
0 голосов
/ 07 января 2009

Номер Build можно извлечь из метаданных сборки и установить в соответствии с датой сборки.

Обычно вы найдете или создадите запись в файле AssemblyInfo.cs. Когда ваш проект создан с использованием Visual Studio. Пример:

[assembly: AssemblyVersion("1.0.*")]

Цитата для документации по AssemblyVersionAttribute . (Я выделил некоторые важные детали)

Вы можете указать все значения или вы может принять номер сборки по умолчанию, номер ревизии или оба с использованием звездочка (). Например, [Сборка: AssemblyVersion ( "2.3.25.1")] обозначает 2 как основную версию, 3 как минорная версия, 25 как сборка номер, и 1 как номер редакции. Номер версии, такой как [Сборка: AssemblyVersion ( "1.2. ")] указывает 1 как основную версию, 2 как минорная версия, и принимает номера сборки и ревизии по умолчанию. A номер версии, такой как [Сборка: AssemblyVersion ( "1.2.15 *")] указывает 1 как основную версию, 2 как минорная версия, 15 как сборка номер, и принимает по умолчанию номер ревизии. Сборка по умолчанию число увеличивается ежедневно. По умолчанию номер редакции является случайным.

Как вы можете видеть, если вы можете установить номер сборки по умолчанию с этим. Номер сборки по умолчанию - это значение, которое увеличивается каждый день.

Затем можно получить номер сборки с помощью свойства AssemblyName.Version . Приведенные MSDN примеры должны помочь вам.

Номер сборки по умолчанию - это количество дней с 1 января 2000 года.

Этот вопрос также содержит четкое объяснение того, как его использовать.

0 голосов
/ 07 января 2009

Директивы препроцессора __TIME__ нет, но есть и другие вещи, которые вы можете использовать, например время создания сборки. Вы также можете использовать подстановку ключевых слов из системы контроля версий ($ Date $ в subversion).

0 голосов
/ 07 января 2009

Я не думаю, что есть способ сделать это в C # - определения макросов в стиле C ++ явно запрещены.

Вы можете обойти это, используя либо дату последнего изменения сборки, либо потенциально включить текстовый файл в качестве встроенного ресурса и добавить настраиваемое действие сборки, которое записывает в него текущую дату / время.

...