我怎样才能得到最后修改过的装配日期?

时间:2023-01-26 16:16:55

I want to render (for internal debugging/info) the last modified date of an assembly, so I'll know when a certain website was deployed.

我想呈现(内部调试/信息)一个程序集的最后修改日期,这样我就知道某个网站何时被部署。

Is it possible to get it through reflection?

有可能通过反射得到它吗?

I get the version like this:

我得到的版本是这样的:

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

I'm looking for something similar -- I don't want to open the physical file, get its properties, or something like that, as I'll be rendering it in the master page, and don't want that kind of overhead.

我在寻找类似的东西——我不希望打开物理文件,获取它的属性,或者类似的东西,因为我将在母版页面中呈现它,并且不希望这样的开销。

6 个解决方案

#1


45  

I'll second pYrania's answer:

我将第二个pYrania的回答:

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

But add this:

但添加:

You mention you don't want to access the file system since it's in your master page and you don't want to make that extra file system hit for every page. So don't, just access it once in the Application load event and then store it as an application-level variable.

您提到您不希望访问文件系统,因为它在您的母版页中,并且您不希望对每个页面都执行额外的文件系统。因此,不要只在应用程序加载事件中访问它一次,然后将其存储为应用程序级变量。

#2


14  

If you default the Revision and Build Numbers in AssemblyInfo:

如果您在程序集信息中默认修改和构建数字:

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

You can get the an approximate build date with:

您可以通过以下方式获得大致的构建日期:

Version version = typeof(MyType).Assembly.GetName().Version;
DateTime date = new DateTime(2000, 1, 1)
    .AddDays(version.Build)
    .AddSeconds(version.Revision * 2);

#3


12  

How about this?

这个怎么样?

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

#4


4  

Some people think that Assembly doesn't holds build date but you know what they are wrong, you can be retrieve the linker timestamp from the PE header embedded in the executable file, like following may work (i havn't tested the code myself)

有些人认为程序集不包含构建日期,但是您知道它们有什么问题,您可以从嵌入可执行文件的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;
}

or if assembly is your's own better you use following approach simple and easy

或者,如果程序集是你自己的,那么你使用下面的方法简单易行。

Add below to pre-build event command line:

在预构建事件命令行中添加以下内容:

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

Add this file as resource, now you have 'BuildDate' string in your resources.

添加这个文件作为资源,现在您的资源中有了“BuildDate”字符串。

I have taken both answers from this question

我从这个问题中得到了两个答案

#5


2  

I don't believe the assembly holds last modified information as that is an operating system attribute. I believe the only way to get this information is through a file handle.

我不认为程序集保存最后修改的信息,因为这是一个操作系统属性。我认为获得这些信息的唯一方法是通过文件句柄。

#6


2  

The RetrieveLinkerTimestamp solution will not work after the year 2038 dues to the use of int32 from 1970. I suggest using the following (although this probably has its limitations too):

RetrieveLinkerTimestamp解决方案在2038年之后将无法使用1970年开始的int32。我建议使用以下方法(尽管这可能也有其局限性):

IO.File.GetLastWriteTime(Reflection.Assembly.GetExecutingAssembly().Location)

#1


45  

I'll second pYrania's answer:

我将第二个pYrania的回答:

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

But add this:

但添加:

You mention you don't want to access the file system since it's in your master page and you don't want to make that extra file system hit for every page. So don't, just access it once in the Application load event and then store it as an application-level variable.

您提到您不希望访问文件系统,因为它在您的母版页中,并且您不希望对每个页面都执行额外的文件系统。因此,不要只在应用程序加载事件中访问它一次,然后将其存储为应用程序级变量。

#2


14  

If you default the Revision and Build Numbers in AssemblyInfo:

如果您在程序集信息中默认修改和构建数字:

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

You can get the an approximate build date with:

您可以通过以下方式获得大致的构建日期:

Version version = typeof(MyType).Assembly.GetName().Version;
DateTime date = new DateTime(2000, 1, 1)
    .AddDays(version.Build)
    .AddSeconds(version.Revision * 2);

#3


12  

How about this?

这个怎么样?

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

#4


4  

Some people think that Assembly doesn't holds build date but you know what they are wrong, you can be retrieve the linker timestamp from the PE header embedded in the executable file, like following may work (i havn't tested the code myself)

有些人认为程序集不包含构建日期,但是您知道它们有什么问题,您可以从嵌入可执行文件的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;
}

or if assembly is your's own better you use following approach simple and easy

或者,如果程序集是你自己的,那么你使用下面的方法简单易行。

Add below to pre-build event command line:

在预构建事件命令行中添加以下内容:

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

Add this file as resource, now you have 'BuildDate' string in your resources.

添加这个文件作为资源,现在您的资源中有了“BuildDate”字符串。

I have taken both answers from this question

我从这个问题中得到了两个答案

#5


2  

I don't believe the assembly holds last modified information as that is an operating system attribute. I believe the only way to get this information is through a file handle.

我不认为程序集保存最后修改的信息,因为这是一个操作系统属性。我认为获得这些信息的唯一方法是通过文件句柄。

#6


2  

The RetrieveLinkerTimestamp solution will not work after the year 2038 dues to the use of int32 from 1970. I suggest using the following (although this probably has its limitations too):

RetrieveLinkerTimestamp解决方案在2038年之后将无法使用1970年开始的int32。我建议使用以下方法(尽管这可能也有其局限性):

IO.File.GetLastWriteTime(Reflection.Assembly.GetExecutingAssembly().Location)