c# - 如何在 C# 中访问 dll 构建日期时间

标签 c# datetime dll build

有什么方法可以从 C# 访问 dll 的构建日期时间吗?

在 dll 的正式发布之间,我希望能够以某种方式存储 DLL 的构建时间/日期,以便我可以检查当前正在执行的构建是否是我期望的构建。我正在处理一个插件的调试和发布版本,我很容易忘记我当前使用的是哪一个——尤其是在一些开发、测试和预生产机器上。我希望能够转到我的“关于”框并在那里显示它。

TIA, 保罗

最佳答案

您可以使用 IMAGE_FILE_HEADERTimeDateStamp 字段表示链接器创建图像的日期和时间。该值很有用,因为它独立于文件系统中文件的日期/时间。

对应的.NET 4.0代码可以大概是这样的:

using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.IO;

namespace GetPeLinkTime {
    class Program {
        static void Main (string[] args) {
            if (args.Length != 1) {
                Console.WriteLine ("Usage:" + Environment.NewLine + "    GetPeLinkTime ExePathToExamine");
                return;
            }
            string filePath = args[0];

            FileStream file = File.OpenRead (filePath);
            using (var mmf = MemoryMappedFile.CreateFromFile (file, null, 
                                                              file.Length,
                                                              MemoryMappedFileAccess.Read,
                                                              null, HandleInheritability.None, false)) {
                NativeMethods.IMAGE_DOS_HEADER dosHeader = new NativeMethods.IMAGE_DOS_HEADER ();
                using (var accessor = mmf.CreateViewAccessor (0,
                                                              Marshal.SizeOf (dosHeader),
                                                              MemoryMappedFileAccess.Read)) {
                    accessor.Read<NativeMethods.IMAGE_DOS_HEADER>(0, out dosHeader);
                    if (dosHeader.e_magic != NativeMethods.IMAGE_DOS_SIGNATURE) {
                        Console.WriteLine ("The input file is not an Executable file.");
                        return;
                    }
                }
                int signature = 0;
                NativeMethods.IMAGE_FILE_HEADER imageFileHeader = new NativeMethods.IMAGE_FILE_HEADER();
                using (var accessor = mmf.CreateViewAccessor (dosHeader.e_lfanew,
                                                              Marshal.SizeOf (signature) + Marshal.SizeOf (imageFileHeader),
                                                              MemoryMappedFileAccess.Read)) {
                    signature = accessor.ReadInt32 (0);
                    if (signature != NativeMethods.IMAGE_NT_SIGNATURE) {
                        Console.WriteLine ("The input file is not a Program Executable file.");
                        return;
                    }
                    accessor.Read<NativeMethods.IMAGE_FILE_HEADER> (Marshal.SizeOf (signature), out imageFileHeader);
                }
                // convert a Unix timestamp to DateTime
                DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
                TimeSpan localOffset = TimeZone.CurrentTimeZone.GetUtcOffset (origin);
                DateTime originUTC = origin.AddHours(localOffset.Hours);
                DateTime linkTime = originUTC.AddSeconds ((double)imageFileHeader.TimeDateStamp);
                Console.WriteLine ("Link time of the file '{0}' is: {1}", filePath, linkTime);
            }
        }
    }
    internal static class NativeMethods {
        internal const int IMAGE_DOS_SIGNATURE = 0x5A4D;    // MZ
        internal const int IMAGE_NT_SIGNATURE = 0x00004550; // PE00

        [StructLayout (LayoutKind.Sequential)]
        internal struct IMAGE_DOS_HEADER {  // DOS .EXE header
            internal short e_magic;         // Magic number
            internal short e_cblp;          // Bytes on last page of file
            internal short e_cp;            // Pages in file
            internal short e_crlc;          // Relocations
            internal short e_cparhdr;       // Size of header in paragraphs
            internal short e_minalloc;      // Minimum extra paragraphs needed
            internal short e_maxalloc;      // Maximum extra paragraphs needed
            internal short e_ss;            // Initial (relative) SS value
            internal short e_sp;            // Initial SP value
            internal short e_csum;          // Checksum
            internal short e_ip;            // Initial IP value
            internal short e_cs;            // Initial (relative) CS value
            internal short e_lfarlc;        // File address of relocation table
            internal short e_ovno;          // Overlay number
            internal short e_res1;          // Reserved words
            internal short e_res2;          // Reserved words
            internal short e_res3;          // Reserved words
            internal short e_res4;          // Reserved words
            internal short e_oemid;         // OEM identifier (for e_oeminfo)
            internal short e_oeminfo;       // OEM information; e_oemid specific
            internal short e_res20;         // Reserved words
            internal short e_res21;         // Reserved words
            internal short e_res22;         // Reserved words
            internal short e_res23;         // Reserved words
            internal short e_res24;         // Reserved words
            internal short e_res25;         // Reserved words
            internal short e_res26;         // Reserved words
            internal short e_res27;         // Reserved words
            internal short e_res28;         // Reserved words
            internal short e_res29;         // Reserved words
            internal int e_lfanew;          // File address of new exe header
        }
        [StructLayout (LayoutKind.Sequential)]
        internal struct IMAGE_FILE_HEADER {
            internal short Machine;
            internal short NumberOfSections;
            internal int TimeDateStamp;
            internal int PointerToSymbolTable;
            internal int NumberOfSymbols;
            internal short SizeOfOptionalHeader;
            internal short Characteristics;
        }
        //struct _IMAGE_NT_HEADERS {
        //    DWORD Signature;
        //    IMAGE_FILE_HEADER FileHeader;
        //    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
        //}
        //struct _IMAGE_NT_HEADERS64 {
        //    DWORD Signature;
        //    IMAGE_FILE_HEADER FileHeader;
        //    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
        //}
    }
}

关于c# - 如何在 C# 中访问 dll 构建日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4283333/

相关文章:

.net - 如何判断 DLL 是否为 ComVisible?

c# - 如何获取已更改的复选框项目的对象名称?

c# - 如何通过 XmlElement 名称从序列化中排除类字段?

php - 当给出日期时如何在 php 中获取该周星期一的日期

django - 在 Django 1.9 表单中验证日期时间本地输入

c++ - 将一个 DLL 链接到另一个 DLL 的正确步骤

c++ - 使用带有 Ruby 1.9.2 的 SWIG 2.0.4 来运行 SWIG 类示例

c# - 如何创建 ASP.NET 网站来搜索 MLS 或 IDX 列表?

c# - ILogger.Log 方法 declaringType 参数

mysql - 获取两个日期时间段之间的数据库搜索结果