305 votes

Affichage de la date de construction

J'ai actuellement une application affichant le numéro de version dans le titre de la fenêtre. C'est bien beau, sauf que ça ne veut rien dire pour la plupart des utilisateurs, qui veulent savoir si ils ont la dernière version - ils ont tendance à se référer à elle comme "jeudi dernier," plutôt que de construire des 1.0.8.4321.

Le plan est de mettre la date de réalisation de là, au lieu - Donc "App construit sur 21/10/2009" par exemple.

J'ai du mal à trouver des programmes de façon à tirer la date de fabrication comme une chaîne de texte pour une utilisation de ce genre.

Pour le numéro de build, j'ai utilisé:

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

après la définition de la manière dont ceux-ci venaient.

Je voudrais quelque chose comme ça pour la date de compilation (et le temps, pour les points de bonus).

Les pointeurs ici beaucoup apprécié (excusez le jeu de mots est si approprié), ou plus propres solutions...

Marque

376voto

mdb Points 20629

Jeff Atwood avait quelques choses à dire à propos de ce problème dans Déterminer la date de construction à la dure .

La méthode la plus fiable s'avère récupérer l'horodatage de l'éditeur de liens à partir de l'en- tête PE intégré dans le fichier exécutable - du code C # (par Joe Spivey) pour cela des commentaires à l'article de Jeff:

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

141voto

Abdurrahim Points 171

Ajoutez ci-dessous la ligne de commande de l'événement de pré-construction:

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

Ajoutez ce fichier en tant que ressource, vous avez maintenant la chaîne 'BuildDate' dans vos ressources.

97voto

John Leidegren Points 21951

La nouvelle façon

J'ai changé d'avis à ce sujet, et actuellement utiliser cette astuce pour trouver la bonne date de création.

#region Gets the build date and time (by reading the COFF header)

// http://msdn.microsoft.com/en-us/library/ms680313

struct _IMAGE_FILE_HEADER
{
    public ushort Machine;
    public ushort NumberOfSections;
    public uint TimeDateStamp;
    public uint PointerToSymbolTable;
    public uint NumberOfSymbols;
    public ushort SizeOfOptionalHeader;
    public ushort Characteristics;
};

static DateTime GetBuildDateTime(Assembly assembly)
{
    if (File.Exists(assembly.Location))
    {
        var buffer = new byte[Math.Max(Marshal.SizeOf(typeof(_IMAGE_FILE_HEADER)), 4)];
        using (var fileStream = new FileStream(assembly.Location, FileMode.Open, FileAccess.Read))
        {
            fileStream.Position = 0x3C;
            fileStream.Read(buffer, 0, 4);
            fileStream.Position = BitConverter.ToUInt32(buffer, 0); // COFF header offset
            fileStream.Read(buffer, 0, 4); // "PE\0\0"
            fileStream.Read(buffer, 0, buffer.Length);
        }
        var pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            var coffHeader = (_IMAGE_FILE_HEADER)Marshal.PtrToStructure(pinnedBuffer.AddrOfPinnedObject(), typeof(_IMAGE_FILE_HEADER));

            return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1) + new TimeSpan(coffHeader.TimeDateStamp * TimeSpan.TicksPerSecond));
        }
        finally
        {
            pinnedBuffer.Free();
        }
    }
    return new DateTime();
}

#endregion

L'ancienne

Eh bien, comment voulez-vous générer des numéros de build? Visual Studio (ou le compilateur C#) permet réellement de construction automatique et que les numéros de révision si vous modifiez le AssemblyVersion attribut, par exemple 1.0.*

Ce qui va arriver, c'est que c'est que la construction sera égal au nombre de jours depuis le 1er janvier 2000, heure locale, et pour la révision à être égal au nombre de secondes depuis minuit, heure locale, divisé par 2.

voir le Contenu de la Communauté, de construction Automatique et que les numéros de Révision

par exemple, AssemblyInfo.cs

[assembly: AssemblyVersion("1.0.*")] // important: use wildcard for build and revision numbers!

SampleCode.cs

var version = Assembly.GetEntryAssembly().GetName().Version;
var buildDateTime = new DateTime(2000, 1, 1).Add(new TimeSpan(
TimeSpan.TicksPerDay * version.Build + // days since 1 January 2000
TimeSpan.TicksPerSecond * 2 * version.Revision))); // seconds since midnight, (multiply by 2 to get original)

65voto

brewmanz Points 89

Ajoutez ci-dessous la ligne de commande de l'événement de pré-construction:

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

Ajoutez ce fichier en tant que ressource, vous avez maintenant la chaîne 'BuildDate' dans vos ressources.

Après avoir inséré le fichier dans la ressource (en tant que fichier texte public), j'y ai accédé via

 string strCompTime = Properties.Resources.BuildDate;
 

18voto

Zalek Bloom Points 81

Je suis juste C# débutant peut-être que ma réponse paraître idiot - je afficher la date de création à partir de la date à laquelle le fichier exécutable de dernière écriture:

string w_file = "MyProgram.exe"; 
string w_directory = Directory.GetCurrentDirectory();

DateTime c3 =  File.GetLastWriteTime(System.IO.Path.Combine(w_directory, w_file));
RTB_info.AppendText("Program created at: " + c3.ToString());

J'ai essayé d'utiliser le Fichier.GetCreationTime méthode, mais a obtenu des résultats étranges: la date de la commande a été 2012-05-29, mais la date à partir de la Fenêtre de l'Explorateur a montré 2012-05-23. Après la recherche de cet écart, j'ai trouvé que le fichier a probablement été créé sur 2012-05-23 (comme indiqué par l'Explorateur Windows), mais copié dans le dossier en cours sur 2012-05-29 (comme indiqué par Fichier.GetCreationTime de commande) - donc, pour être sur le côté sûr, je suis en utilisant le Fichier.GetLastWriteTime de commande.

Zalek

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X