Как найти текущее время и дату во время компиляции в приложении .net / C #? - PullRequest
8 голосов
/ 09 июня 2009

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

например.

Добро пожаловать в ApplicationX. Это было построено день-месяц-год в время .

Ответы [ 7 ]

9 голосов
/ 09 июня 2009

Если вы используете отражение для своего номера сборки, вы можете использовать его, чтобы выяснить, когда сборка была скомпилирована.

Информация о версии для сборки состоит из следующих четырех значений:

  1. Основная версия
  2. Малая версия
  3. Номер сборки
  4. Редакция

Вы можете указать все значения или принять номер сборки по умолчанию, номер редакции или оба, используя звездочку (*). Номер сборки и ревизия основаны на 1 января 2000 года по умолчанию.

Следующий атрибут устанавливает Major и minor, но затем увеличивает номер сборки и ревизию.

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

Тогда вы можете использовать что-то вроде этого:

public static DateTime CompileTime
{
   get
   {
      System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
      // MyVersion.Build = days after 2000-01-01
      // MyVersion.Revision*2 = seconds after 0-hour  (NEVER daylight saving time)
      DateTime compileTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);                
      return compileTime;
   }
}
3 голосов
/ 09 июня 2009

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

У вас может быть событие перед сборкой, которое запускает небольшое приложение, которое генерирует исходный код на лету. Простой способ сделать это - просто перезаписать очень маленький файл, который включает в себя класс (или частичный класс), в котором день / месяц / год жестко закодированы как строковая константа.

Если вы установите его как событие перед сборкой, он будет перезаписывать этот файл перед каждой сборкой.

2 голосов
/ 09 июня 2009

В make-файлах для программ на C обычно можно увидеть что-то вроде этого:

echo char * gBuildSig ="%DATE% %TIME%"; > BuildTimestamp.c

И затем полученный исходный файл C компилируется в изображение. Вышеописанное работает в Windows, потому что переменные% date% и% time% известны в cmd.exe, но аналогичная вещь будет работать в Unix с использованием cat.

Вы можете сделать то же самое, используя C #. Еще раз, это будет выглядеть так, если вы используете make-файл. Вам нужен класс и публичное статическое свойство.

BuildTimestamp.cs: 
    echo public static class Build { public static string Timestamp = "%DATE% %TIME%";} > BuildTimestamp.cs 

И затем для вещи, которую вы строите, зависимость и удаление:

MyApp.exe: BuildTimestamp.cs MyApp.cs
    $(_CSC)  /target:exe /debug+ /optimize- /r:System.dll /out:MyApp.exe MyApp.cs BuildTimestamp.cs
    -del  BuildTimestamp.cs

Обязательно удалите файл BuildTimestamp.cs после его компиляции; Вы не хотите использовать это снова. Затем, в вашем приложении, просто сослаться на Build.Timestamp.

Используя MSBuild или Visual Studio, это сложнее. Я не могу получить% date% или% time% для разрешения. Эти вещи являются псевдо-переменными среды, я думаю, именно поэтому. Поэтому я прибег к косвенному способу получения метки времени, используя задачу Touch с AlwaysCreate = true. Это создает пустой файл. Следующий шаг записывает исходный код в тот же файл, ссылаясь на временную метку файла. Один поворот - мне пришлось избежать точки с запятой.

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

<ItemGroup>
  <StampFile   Include="BuildTimestamp.cs"/>
</ItemGroup>

<Target Name="BuildTimestamp" 
        Outputs="@(StampFile)">
  <Message Text="Building timestamp..." />

  <Touch
        AlwaysCreate="true"
        Files="@(StampFile)" />

  <WriteLinesToFile
        File="@(StampFile)"
        Lines='public static class Build { public static string Timestamp = "%(StampFile.CreatedTime)" %3B }'
        Overwrite="true" />

</Target>
2 голосов
/ 09 июня 2009

Вы можете использовать PostSharp, чтобы ткать дату сразу после сборки. PostSharp поставляется с легкой библиотекой аспектно-ориентированного программирования, но она может быть расширена, чтобы переплетаться с любыми нужными способами. Он работает на уровне IL, но API немного вас абстрагирует.

http://www.postsharp.org/

2 голосов
/ 09 июня 2009

Нет ничего встроенного в язык для этого.

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

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

Пример этого см. В файле сборки для MiscUtil , который встраивает текущую версию SVN в атрибут AssemblyFileVersion. Некоторые разные биты файла сборки:

<!-- See http://msbuildtasks.tigris.org -->
<Import 
 Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

<!-- Find out what the latest version is -->
<SvnInfo RepositoryPath="$(SvnUrl)">
  <Output TaskParameter="LastChangedRevision" PropertyName="Revision" />
</SvnInfo>

<!-- Update the AssemblyInfo with the revision number -->
<FileUpdate Files="$(OutputDirectory)\MiscUtil\MiscUtil\Properties\AssemblyInfo.cs"
            Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
            ReplacementText='$1.$2.$(Revision)$5' />
0 голосов
/ 27 января 2010

Привет, я использовал следующий метод для того же ...

private DateTime ExecutableInfo()
{
  System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath.Trim());
  try
  {
    return fi.CreationTime;
  }
  catch (Exception ex)
  {
    throw ex;
  }
  finally
  {
    fi = null;
  }
}
0 голосов
/ 09 июня 2009

Вы можете обновить версию Assembly в AssemblyInfo.cs как часть вашей сборки. Тогда вы могли бы сделать что-то вроде этого

FileVersionInfo lvar = FileVersionInfo.GetVersionInfo(FileName);

FileVersionInfo содержит информацию (сборка / версия и т. Д.), Которую вы ищете. Посмотрите, сработает ли это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...