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

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

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

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

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

person Martin    schedule 07.01.2009    source источник


Ответы (7)


В C # нет концепции макросов; однако вы можете использовать другие инструменты в вашем сценарии сборки (csproj / NANT / и т. д.) для управления исходным кодом перед его компиляцией. Я использую это, например, чтобы установить номер версии для текущей версии SVN.

Дешевый вариант - это событие перед сборкой (вы можете сделать это через диалоговое окно свойств проекта в VS): по сути, файл bat, который запускается перед сборкой; затем вы можете записать любые изменения, которые вам нужны. Более сложный вариант - задачи сборки.

Например, вспомогательная библиотека здесь включает Time задачу и FileUpdate задачу; должно быть (теоретически) возможно связать их вместе, чтобы подражать тому, что вам нужно.

Лично я бы использовал [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' />

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

person Marc Gravell    schedule 07.01.2009
comment
Я делаю нечто подобное в MSBuild, используя задачи Microsoft SDC по адресу: codeplex.com/sdctasks - person Ray Booysen; 07.01.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;
    }
person Stormenet    schedule 07.01.2009
comment
Устаревшая ссылка на источник (перенаправлена ​​на домашнюю страницу)? - person MattAllegro; 20.06.2018

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

person Jesse Pepper    schedule 07.01.2009
comment
Эта страница удалена. - person Anders Lindén; 03.08.2020

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

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

person Steven Robbins    schedule 07.01.2009

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

person Stewart Johnson    schedule 07.01.2009

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

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

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

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

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

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

Затем вы можете получить номер сборки, используя AssemblyName. Версия собственности. Примеры, предоставленные MSDN, должны вас вдохновить.

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

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

person GvS    schedule 07.01.2009
comment
Это неправда, номер сборки может быть любым, и он, вероятно, изменится при выпуске релизов. Вы не можете полагаться на свой номер сборки, чтобы узнать, когда произошла компиляция. - person Ray Booysen; 07.01.2009
comment
Да, номер сборки может быть любым, но номер сборки по умолчанию, тот, который создается с использованием * в версии, - это количество дней с 01.01.2000. - person GvS; 07.01.2009
comment
Я сделал свой ответ более ясным. Надеюсь, теперь нет путаницы между номером сборки, заданным пользователем, и сгенерированным номером сборки по умолчанию. - person GvS; 07.01.2009
comment
Даже если люди используют номер сборки по умолчанию, ежедневное приращение дает только дату сборки. OP запросил дату и время, - person Reg Edit; 14.08.2016

Вы ищете что-то вроде этого:
(Получить дату сборки сборки через информацию о версии; номер сборки - дни с 1.1.2000)

         var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        DateTime versionsDatum = new DateTime(2000, 1, 1);
        versionsDatum = versionsDatum.AddDays(version.Build);
person Community    schedule 28.08.2009