2009-01-07 9 views
6

En C# 3.0, tengo una propiedad que se supone que contiene la versión de la clase. El número de versión es simplemente la fecha y hora de la compilación. En este momento, tengo el siguiente código:¿Cómo puedo obtener el DateTime actual del precompilador en C#?

public DateTime Version 
{ 
    get { return DateTime.UtcNow; } 
} 

Obviamente, esto es un error ya que esta propiedad me devuelve la fecha y hora actuales. Entonces, ¿el precompilador puede imprimir el DateTime en tiempo de compilación? En este caso, podría hacer algo similar a la siguiente.

public DateTime Version 
{ 
    get { return new DateTime("PRECOMPILER DATE"); } 
} 

Respuesta

7

C# no tiene el concepto de macros; sin embargo, puede usar otras herramientas en su secuencia de comandos de construcción (csproj/NANT/etc) para manipular la fuente antes de compilarla. Lo uso, por ejemplo, para establecer el número de revisión en la revisión SVN actual.

Una opción económica es un evento previo a la construcción (puede hacerlo a través del cuadro de diálogo de propiedades del proyecto en VS): esencialmente un archivo bat que se ejecuta antes de compilar; a continuación, puede programar cualquier cambio que necesite. Una opción más sofisticada es construir tareas.

Por ejemplo, la biblioteca de utilidades here incluye una tarea Time y una tarea FileUpdate; debería (en teoría) ser posible encadenar los dos juntos para emular lo que necesita.

Personalmente, usaría los detalles de [AssemblyVersion] en lugar de la hora; si vincula esto al sistema de control de fuente, esto hace que sea muy fácil encontrar la versión ofensiva; por lo que para mi versión SVN, yo utilizo a continuación (en mi construcción proy):

<!-- See http://msbuildtasks.tigris.org --> 
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 
... 
<SvnInfo LocalPath="."> 
    <Output TaskParameter="Revision" PropertyName="BuildRev" /> 
</SvnInfo> 
... 
<FileUpdate Files="Path\To\My\AssemblyInfo.cs" 
    Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])' 
    ReplacementText='$1.$2.$(BuildRev)$5' /> 
<FileUpdate Files="Path\To\My\AssemblyInfo.cs" 
    Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])' 
    ReplacementText='$1.$2.$(BuildRev)$5' /> 

Y ahora mi versión de montaje es correcta, incluido el archivo de la versión eso se difundió por el sistema operativo.

+0

hago algo similar a esto en MSBuild utilizando las tareas de Microsoft SDC en: http://www.codeplex.com/sdctasks –

3

No existe un equivalente para la directiva de preprocesador __TIME__ en C#. Lo mejor que puede hacer es obtener el ensamblado actual y obtener la fecha de creación, que contendrá el tiempo de compilación. Ver here

0

No creo que haya una manera de hacer esto en C# - las definiciones de macro de estilo C++ son explícitamente prohibidas.

Podría solucionarlo usando la última fecha de modificación del ensamblado, o incluir potencialmente un archivo de texto como un recurso incrustado y agregar una acción de compilación personalizada que escriba la fecha/hora actual en él.

0

No hay una directiva de preprocesador __TIME__, pero hay otras cosas que podría usar, como la hora de creación del ensamblaje. También podría considerar el uso de la sustitución de palabras clave de su sistema de control de origen ($ Date $ in subversion).

8

Usted puede retreive desde el DLL propio (Source: codinghorror)

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

Enlace de interés ... gracias. –

+0

De nada :) – Stormenet

+1

Lo que es aún mejor que esto funcione incluso en Monotouch. –

-1

El número Build se puede recuperar de los metadatos de un montaje, y se puede configurar para que coincida con la fecha de la construcción.

Normalmente encontrará o creará una entrada en el archivo AssemblyInfo.cs. Cuando su proyecto se crea usando Visual Studio.Un ejemplo:

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

una cotización para la documentación sobre AssemblyVersionAttribute. (He en negrita algunas partes importantes)

Puede especificar todos los valores o puede aceptar el número por defecto de construcción, número de revisión, o ambas cosas mediante el uso de un asterisco (). Por ejemplo, [assembly: AssemblyVersion ("2.3.25.1")] indica 2 como la versión principal, 3 como la versión secundaria, 25 como el número de compilación y 1 como número de revisión. Un número de versión tal como [assembly: AssemblyVersion ("1.2")] especifica 1 como la versión principal, 2 como la versión de menor importancia, y acepta los números de compilación y revisión predeterminados. Un número de versión como [assembly: AssemblyVersion ("1.2.15. *")] especifica 1 como la versión principal, 2 como la versión menor, 15 como la acumulación número, y acepta la revisión por defecto número. El número predeterminado de compilación se incrementa diariamente. El número de revisión predeterminado es aleatorio.

Como puede ver, si puede establecer un número de compilación predeterminado con esto. El número de compilación predeterminado es un valor que se incrementa cada día.

Puede recuperar el número de compilación utilizando la propiedad AssemblyName.Version. Los ejemplos proporcionados por MSDN deberían ayudarlo.

El número de compilación predeterminado es el número de días desde el 1/1/2000.

This question también tiene una explicación clara sobre cómo usar esto.

+0

Esto no es cierto, el número de compilación puede ser cualquier cosa que desee y probablemente cambiaría al hacer las versiones. No puede confiar en su número de compilación para saber cuándo ocurrió la compilación. –

+0

Sí, el número de compilación puede ser el que desee, pero el número de compilación predeterminado, el que se genera con el "*" en la versión es el número de días desde 1/1/2000 – GvS

+0

He respondido más claro. Espero que ahora no haya confusión entre el número de compilación del conjunto de usuarios y el número de compilación predeterminado generado. – GvS

-1

¿Te buscando algo como esto:
(Get es la fecha de construcción de la Asamblea a través de Versión-Info; urbanizado Número es días desde el 1.1.2000)

  var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; 
     DateTime versionsDatum = new DateTime(2000, 1, 1); 
     versionsDatum = versionsDatum.AddDays(version.Build); 
Cuestiones relacionadas