Pregunta

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:

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

Obviamente, esto es incorrecto 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 lo siguiente.

public DateTime Version
{
    get { return new DateTime("PRECOMPILER DATE"); }
}
¿Fue útil?

Solución

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

Una opción barata es un evento previo a la compilació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 la compilación; A continuación, puede escribir cualquier cambio que necesite. Una opción más sofisticada son las tareas de compilación.

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

Personalmente, usaría los detalles de [AssemblyVersion] en lugar de la hora. Si vinculas esto a tu sistema de control de fuente, esto hace que sea muy fácil encontrar la versión ofensiva; así que para mi versión SVN, luego uso (en mi proyecto de compilación):

<!-- 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 ensamblaje es correcta, incluida la versión de archivo que el sistema operativo informa.

Otros consejos

Puede recuperarlo de la dll misma ( Fuente: 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;
    }

No hay equivalente para la directiva del preprocesador __TIME__ en C #. Lo mejor que puedes hacer es obtener el ensamblaje actual y obtener la fecha de creación, contendrá el tiempo de compilación. Consulte aquí

No creo que haya una manera de hacer esto en C #: las definiciones de macro de estilo C ++ están explícitamente deshabilitadas.

Puede evitarlo utilizando la última fecha de modificación del ensamblaje o incluir un archivo de texto como recurso incrustado y agregar una acción de compilación personalizada que escriba la fecha / hora actual en él.

No hay una directiva de preprocesador __TIME__ , pero hay otras cosas que puede 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 $ en subversion).

El número Build se puede recuperar de los metadatos de un ensamblaje, y se pueden configurar para que coincidan con la fecha de la compilación.

Normalmente, encontrará o creará una entrada en el archivo AssemblyInfo.cs. Cuando tu proyecto es creado usando Visual Studio. Un ejemplo:

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

Una cita para la documentación en AssemblyVersionAttribute . (He marcado algunas partes importantes)

  

Puedes especificar todos los valores o tu   puede aceptar el número de compilación predeterminado,   número de revisión, o ambos utilizando un   asterisco (). Por ejemplo,   [ensamblado: AssemblyVersion (" 2.3.25.1 ")]   indica 2 como la versión principal, 3 como   La versión menor, 25 como el build.   número, y 1 como el número de revisión.    Un número de versión como   [ensamblado: AssemblyVersion (" 1.2. ")]   especifica 1 como la versión principal, 2 como   La versión menor, y acepta la   números predeterminados de compilación y revisión. A   número de versión como   [ensamblado: AssemblyVersion (" 1.2.15. * ")]   especifica 1 como la versión principal, 2 como   La versión menor, 15 como la compilación.   número, y acepta el valor predeterminado   número de revisión. La compilación predeterminada   Número de incrementos diarios. El valor por defecto   el número de revisión 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.

Luego puede recuperar el número de compilación utilizando AssemblyName.Version propiedad. Los ejemplos proporcionados por MSDN deberían ponerte en marcha.

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

Esta pregunta También tiene una explicación clara sobre cómo usar esto.

¿Estás buscando algo como esto:
(Obtenga la fecha de creación del ensamblaje a través de Version-Info; Build-Number son días desde 1.1.2000)

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