Отображение даты сборки - PullRequest
       66

Отображение даты сборки

240 голосов
/ 21 октября 2009

В настоящее время у меня есть приложение, отображающее номер сборки в окне заголовка. Это хорошо, за исключением того, что это ничего не значит для большинства пользователей, которые хотят знать, есть ли у них последняя сборка - они склонны называть ее "прошлой четвергой", а не сборкой 1.0.8.4321.

Вместо этого планируется указать дату сборки - например, «Приложение построено 21/10/2009».

Я изо всех сил пытаюсь найти программный способ извлечения даты сборки в виде текстовой строки для такого использования.

Для номера сборки я использовал:

Assembly.GetExecutingAssembly().GetName().Version.ToString()

после определения, как они возникли.

Я бы хотел что-то подобное для даты компиляции (и времени, для бонусных баллов).

Здесь очень ценятся указатели (извините за каламбур, если необходимо) или более аккуратные решения ...

Ответы [ 23 ]

8 голосов
/ 30 мая 2018

Для проектов .NET Core я адаптировал ответ Postlagerkarte, чтобы обновить поле Copyright для сборки с датой сборки.

Прямое редактирование csproj

Следующее может быть добавлено непосредственно к первому PropertyGroup в csproj:

<Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>

Альтернатива: свойства проекта Visual Studio

Или вставьте внутреннее выражение непосредственно в поле Copyright в разделе Package свойств проекта в Visual Studio:

Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))

Это может немного сбивать с толку, поскольку Visual Studio оценит выражение и отобразит текущее значение в окне, но также соответствующим образом обновит файл проекта за кулисами.

для всего решения через Directory.Build.props

Вы можете добавить указанный выше элемент <Copyright> в файл Directory.Build.props в корне вашего решения и автоматически применить его ко всем проектам в каталоге, предполагая, что каждый проект не имеет своего собственного значения Copyright.

<Project>
 <PropertyGroup>
   <Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>
 </PropertyGroup>
</Project>

Directory.Build.props: Настройка сборки

выход

Пример выражения даст вам авторское право, подобное этому:

Copyright © 2018 Travis Troyer (2018-05-30T14:46:23)

индексирование

Вы можете просмотреть информацию об авторских правах в свойствах файла в Windows или получить ее во время выполнения:

var version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);

Console.WriteLine(version.LegalCopyright);
7 голосов
/ 18 июня 2018

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

<Target Name="Date" BeforeTargets="CoreCompile">
    <WriteLinesToFile File="$(IntermediateOutputPath)gen.cs" Lines="static partial class Builtin { public static long CompileTime = $([System.DateTime]::UtcNow.Ticks) %3B }" Overwrite="true" />
    <ItemGroup>
        <Compile Include="$(IntermediateOutputPath)gen.cs" />
    </ItemGroup>
</Target>

и теперь у вас есть Builtin.CompileTime или new DateTime(Builtin.CompileTime, DateTimeKind.Utc), если вам это нужно.

ReSharper это не понравится. Вы можете игнорировать его или добавить частичный класс в проект, но он все равно работает.

6 голосов
/ 12 января 2018

В 2018 году некоторые из вышеперечисленных решений больше не работают или не работают с .NET Core.

Я использую следующий подход, который прост и работает для моего проекта .NET Core 2.0.

Добавьте следующее в ваш .csproj внутри PropertyGroup:

    <Today>$([System.DateTime]::Now)</Today>

Это определяет PropertyFunction , к которой вы можете получить доступ в вашей команде предварительной сборки.

Ваша предварительная сборка выглядит так

echo $(today) > $(ProjectDir)BuildTimeStamp.txt

Установите свойство BuildTimeStamp.txt для встроенного ресурса.

Теперь вы можете читать отметку времени следующим образом

public static class BuildTimeStamp
    {
        public static string GetTimestamp()
        {
            var assembly = Assembly.GetEntryAssembly(); 

            var stream = assembly.GetManifestResourceStream("NamespaceGoesHere.BuildTimeStamp.txt");

            using (var reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
    }
4 голосов
/ 21 февраля 2018

Мне нужно было универсальное решение, которое работало с проектом NETStandard на любой платформе (iOS, Android и Windows). Для этого я решил автоматически сгенерировать файл CS с помощью скрипта PowerShell. Вот скрипт PowerShell:

param($outputFile="BuildDate.cs")

$buildDate = Get-Date -date (Get-Date).ToUniversalTime() -Format o
$class = 
"using System;
using System.Globalization;

namespace MyNamespace
{
    public static class BuildDate
    {
        public const string BuildDateString = `"$buildDate`";
        public static readonly DateTime BuildDateUtc = DateTime.Parse(BuildDateString, null, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
    }
}"

Set-Content -Path $outputFile -Value $class

Сохраните файл PowerScript как GenBuildDate.ps1 и добавьте его в свой проект. Наконец, добавьте следующую строку в событие Pre-Build:

powershell -File $(ProjectDir)GenBuildDate.ps1 -outputFile $(ProjectDir)BuildDate.cs

Убедитесь, что BuildDate.cs включен в ваш проект. Работает как чемпион на любой ОС!

4 голосов
/ 31 января 2019

Я просто делаю:

File.GetCreationTime(GetType().Assembly.Location)
3 голосов
/ 22 августа 2018

Вы можете использовать этот проект: https://github.com/dwcullop/BuildInfo

Он использует T4 для автоматизации отметки даты сборки. Есть несколько версий (разных веток), в том числе одна, которая дает вам Git Hash ветки, которую вы в данный момент извлекли, если вы любите подобные вещи.

Раскрытие: я написал модуль.

2 голосов
/ 24 января 2018

Небольшое обновление ответа "Новый путь" от Джона.

Вам нужно построить путь вместо использования строки CodeBase при работе с ASP.NET/MVC

    var codeBase = assembly.GetName().CodeBase;
    UriBuilder uri = new UriBuilder(codeBase);
    string path = Uri.UnescapeDataString(uri.Path);
2 голосов
/ 21 октября 2009

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

2 голосов
/ 09 мая 2016

Другой, дружественный к PCL подход заключается в использовании встроенной задачи MSBuild для замены времени сборки в строку, возвращаемую свойством приложения. Мы успешно используем этот подход в приложении с проектами Xamarin.Forms, Xamarin.Android и Xamarin.iOS.

EDIT:

Упрощается путем перемещения всей логики в файл SetBuildDate.targets и использования Regex вместо простой замены строки, так что файл может быть изменен каждой сборкой без «перезагрузки».

Определение встроенной задачи MSBuild (для этого примера сохранено в файле SetBuildDate.targets, локальном для проекта Xamarin.Forms):

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="12.0">

  <UsingTask TaskName="SetBuildDate" TaskFactory="CodeTaskFactory" 
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
    <ParameterGroup>
      <FilePath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs"><![CDATA[

        DateTime now = DateTime.UtcNow;
        string buildDate = now.ToString("F");
        string replacement = string.Format("BuildDate => \"{0}\"", buildDate);
        string pattern = @"BuildDate => ""([^""]*)""";
        string content = File.ReadAllText(FilePath);
        System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(pattern);
        content = rgx.Replace(content, replacement);
        File.WriteAllText(FilePath, content);
        File.SetLastWriteTimeUtc(FilePath, now);

   ]]></Code>
    </Task>
  </UsingTask>

</Project>

Вызов указанной выше встроенной задачи в файле csproj Xamarin.Forms в target BeforeBuild:

  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.  -->
  <Import Project="SetBuildDate.targets" />
  <Target Name="BeforeBuild">
    <SetBuildDate FilePath="$(MSBuildProjectDirectory)\BuildMetadata.cs" />
  </Target>

Свойство FilePath установлено в файл BuildMetadata.cs в проекте Xamarin.Forms, который содержит простой класс со строковым свойством BuildDate, в который будет подставлено время сборки:

public class BuildMetadata
{
    public static string BuildDate => "This can be any arbitrary string";
}

Добавить этот файл BuildMetadata.cs в проект. Он будет изменяться при каждой сборке, но таким образом, чтобы допускались повторные сборки (повторные замены), поэтому вы можете включить или опустить его в системе контроля версий по своему усмотрению.

2 голосов
/ 21 октября 2009

Я не уверен, но, возможно, Build Incrementer помогает.

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