Как получить дату последнего изменения сборки? - PullRequest
33 голосов
/ 30 апреля 2009

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

Можно ли получить это через отражение?

Я получаю такую ​​версию:

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

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

Ответы [ 6 ]

46 голосов
/ 30 апреля 2009

Я буду вторым ответом Пирания:

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location);
DateTime lastModified = fileInfo.LastWriteTime;

Но добавьте это:

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

15 голосов
/ 30 апреля 2009

Если вы по умолчанию используете номера редакций и сборки в AssemblyInfo:

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

Примерную дату постройки вы можете получить с помощью:

Version version = typeof(MyType).Assembly.GetName().Version;
DateTime date = new DateTime(2000, 1, 1)
    .AddDays(version.Build)
    .AddSeconds(version.Revision * 2);
12 голосов
/ 30 апреля 2009

Как насчет этого?

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location);
DateTime lastModified = fileInfo.LastWriteTime;
4 голосов
/ 10 января 2014

Некоторые люди думают, что Ассамблея не держит дату сборки, но вы знаете, что они не правы, Вы можете получить временную метку компоновщика из PE-заголовка , встроенного в исполняемый файл, например, может работать следующее (я сам не проверял код)

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;
}

или если сборка у вас лучше, используйте следующий простой и легкий подход

Добавьте ниже в командную строку события перед сборкой:

echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"

Добавьте этот файл в качестве ресурса, теперь у вас есть строка 'BuildDate' в ваших ресурсах.

Я получил оба ответа от на этот вопрос

2 голосов
/ 01 февраля 2018

Решение RetrieveLinkerTimestamp не будет работать после года 2038 из-за использования int32 с 1970. Я предлагаю использовать следующее (хотя это, вероятно, также имеет свои ограничения):

IO.File.GetLastWriteTime(Reflection.Assembly.GetExecutingAssembly().Location)
2 голосов
/ 30 апреля 2009

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

...