Actualmente tengo una aplicación que muestra el número de compilación en su ventana de título. Eso está muy bien, excepto que no significa nada para la mayoría de los usuarios, que quieren saber si tienen la última compilación; tienden a referirse a ella como "el jueves pasado" en lugar de compilar 1.0.8.4321.
El plan es poner la fecha de compilación allí, por lo tanto, "Aplicación creada el 21/10/2009".
Estoy luchando por encontrar una forma programática para extraer la fecha de compilación como una cadena de texto para usar de esta manera.
Para el número de compilación, utilicé:
Assembly.GetExecutingAssembly().GetName().Version.ToString()
después de definir cómo surgieron esos.
Me gustaría algo así para la fecha de compilación (y la hora, para los puntos de bonificación).
Los punteros aquí son muy apreciados (disculpen el juego de palabras si corresponde), o soluciones más ordenadas ...
fuente
Respuestas:
Jeff Atwood tenía algunas cosas que decir sobre este problema en Determinar la fecha de compilación de la manera difícil .
Resulta que el método más confiable es recuperar la marca de tiempo del enlazador desde el encabezado PE incrustado en el archivo ejecutable: algún código C # (por Joe Spivey) para eso de los comentarios al artículo de Jeff:
Ejemplo de uso:
ACTUALIZACIÓN: El método estaba funcionando para .Net Core 1.0, pero dejó de funcionar después de la versión .Net Core 1.1 (da años aleatorios en el rango 1900-2020)
fuente
.AddHours()
es bastante hack y (creo) no tendrá en cuenta el horario de verano. Si lo desea en la hora local, debe usar el limpiador en sudt.ToLocalTime();
lugar. La parte central también podría simplificarse enormemente con unusing()
bloque.Agregue a continuación la línea de comando del evento previo a la compilación:
Agregue este archivo como recurso, ahora tiene la cadena 'BuildDate' en sus recursos.
Para crear recursos, vea Cómo crear y usar recursos en .NET .
fuente
La manera
Como señaló @ c00000fd en los comentarios . Microsoft está cambiando esto. Y aunque muchas personas no usan la última versión de su compilador, sospecho que este cambio hace que este enfoque sea indudablemente malo. Y aunque es un ejercicio divertido, recomendaría a las personas que simplemente incorporen una fecha de compilación en su binario a través de cualquier otro medio necesario si es importante rastrear la fecha de compilación del propio binario.
Esto se puede hacer con una generación de código trivial que probablemente ya sea el primer paso en su script de compilación. Eso y el hecho de que las herramientas ALM / Build / DevOps ayudan mucho con esto y deberían preferirse a cualquier otra cosa.
Dejo el resto de esta respuesta aquí solo con fines históricos.
La nueva forma
Cambié de opinión sobre esto, y actualmente uso este truco para obtener la fecha de compilación correcta.
La vieja manera
Bueno, ¿cómo generas números de compilación? Visual Studio (o el compilador de C #) en realidad proporciona números de compilación y revisión automáticos si cambia el atributo AssemblyVersion a, p. Ej.
1.0.*
Lo que sucederá es que la compilación será igual a la cantidad de días desde el 1 de enero de 2000, hora local, y que la revisión sea igual a la cantidad de segundos desde la medianoche, hora local, dividida por 2.
ver Contenido de la comunidad, Números automáticos de compilación y revisión
eg AssemblyInfo.cs
SampleCode.cs
fuente
TimeZone.CurrentTimeZone.IsDaylightSavingTime(buildDateTime) == true
IMAGE_FILE_HEADER::TimeDateStamp
campo se establece en un número aleatorio y ya no es una marca de tiempo.Agregue a continuación la línea de comando del evento previo a la compilación:
Agregue este archivo como recurso, ahora tiene la cadena 'BuildDate' en sus recursos.
Después de insertar el archivo en el Recurso (como archivo de texto público), accedí a él a través de
Para crear recursos, vea Cómo crear y usar recursos en .NET .
fuente
Un enfoque que me sorprende que nadie haya mencionado todavía es usar las plantillas de texto T4 para la generación de código.
Pros:
Contras:
fuente
Constants.CompilationTimestampUtc
. Si VS no está generando un archivo C # con la clase, entonces debe descubrir cómo hacerlo, pero la respuesta depende (al menos) de la versión de VS y el tipo de archivo csproj, por lo que es demasiados detalles para esta publicación.Con respecto a la técnica de extraer información de la fecha / versión de compilación de los bytes de un encabezado PE de ensamblaje, Microsoft ha cambiado los parámetros de compilación predeterminados a partir de Visual Studio 15.4. El nuevo valor predeterminado incluye una compilación determinista, que hace que una marca de tiempo válida y los números de versión incrementados automáticamente sean cosa del pasado. El campo de marca de tiempo todavía está presente, pero se llena con un valor permanente que es un hash de algo u otro, pero no es una indicación del tiempo de construcción.
Algunos antecedentes detallados aquí
Para aquellos que priorizan una marca de tiempo útil sobre la compilación determinista, hay una manera de anular el nuevo valor predeterminado. Puede incluir una etiqueta en el archivo .csproj del conjunto de interés de la siguiente manera:
Actualización: Respaldo la solución de plantilla de texto T4 descrita en otra respuesta aquí. Lo usé para resolver mi problema limpiamente sin perder el beneficio de la compilación determinista. Una advertencia al respecto es que Visual Studio solo ejecuta el compilador T4 cuando se guarda el archivo .tt, no en el momento de la compilación. Esto puede ser incómodo si excluye el resultado .cs del control de código fuente (ya que espera que se genere) y otro desarrollador comprueba el código. Sin volver a guardar, no tendrán el archivo .cs. Hay un paquete en nuget (creo que se llama AutoT4) que hace que la compilación T4 sea parte de cada compilación. Todavía no he confrontado la solución a esto durante el despliegue de producción, pero espero que algo similar lo haga bien.
fuente
Solo soy un novato de C #, así que tal vez mi respuesta suene tonta: muestro la fecha de compilación a partir de la fecha en que se escribió por última vez el archivo ejecutable:
Traté de usar el método File.GetCreationTime pero obtuve resultados extraños: la fecha del comando fue 2012-05-29, pero la fecha del Explorador de ventanas mostró 2012-05-23. Después de buscar esta discrepancia, descubrí que el archivo probablemente se creó el 23/05/2012 (como se muestra en el Explorador de Windows), pero se copió a la carpeta actual el 29/05/2012 (como se muestra en el comando File.GetCreationTime). para estar seguro, estoy usando el comando File.GetLastWriteTime.
Zalek
fuente
LastWriteTime
, ya que eso refleja con precisión el tiempo en que el archivo ejecutable se actualizó realmente.Muchas respuestas geniales aquí, pero siento que puedo agregar las mías debido a la simplicidad, el rendimiento (en comparación con las soluciones relacionadas con los recursos) multiplataforma (también funciona con Net Core) y eludir cualquier herramienta de terceros. Simplemente agregue este objetivo de msbuild al csproj.
y ahora lo tienes
Builtin.CompileTime
onew DateTime(Builtin.CompileTime, DateTimeKind.Utc)
si lo necesitas de esa manera.A ReSharper no le va a gustar. Puede ignorarlo o agregar una clase parcial al proyecto también, pero funciona de todos modos.
fuente
Builtin.CompileTime
desde una vista Razor.BeforeTargets="RazorCoreCompile"
pero solo mientras esto esté en el mismo proyectoPara los proyectos .NET Core, adapté la respuesta de Postlagerkarte para actualizar el campo Copyright de ensamblado con la fecha de compilación.
Editar directamente csproj
Lo siguiente se puede agregar directamente al primero
PropertyGroup
en csproj:Alternativa: Propiedades del proyecto de Visual Studio
O pegue la expresión interna directamente en el campo Copyright en la sección Paquete de las propiedades del proyecto en Visual Studio:
Esto puede ser un poco confuso, porque Visual Studio evaluará la expresión y mostrará el valor actual en la ventana, pero también actualizará el archivo del proyecto de manera adecuada detrás de escena.
Toda la solución a través de Directory.Build.props
Puede colocar el
<Copyright>
elemento anterior en unDirectory.Build.props
archivo en la raíz de su solución y aplicarlo automáticamente a todos los proyectos dentro del directorio, suponiendo que cada proyecto no proporcione su propio valor de Copyright.Directory.Build.props: personaliza tu construcción
Salida
La expresión de ejemplo le dará un copyright como este:
Recuperación
Puede ver la información de copyright de las propiedades del archivo en Windows, o tomarla en tiempo de ejecución:
fuente
El método anterior se puede ajustar para ensamblajes ya cargados dentro del proceso mediante el uso de la imagen del archivo en la memoria (en lugar de volver a leerlo desde el almacenamiento):
fuente
Para cualquiera que necesite obtener el tiempo de compilación en Windows 8 / Windows Phone 8:
Para cualquiera que necesite obtener el tiempo de compilación en Windows Phone 7:
NOTA: en todos los casos, se está ejecutando en un entorno limitado, por lo que solo podrá obtener el tiempo de compilación de los ensamblados que implementa con su aplicación. (es decir, esto no funcionará en nada en el GAC).
fuente
var assembly = typeof (AnyTypeInYourAssembly).GetTypeInfo().Assembly;
En 2018, algunas de las soluciones anteriores ya no funcionan o no funcionan con .NET Core.
Utilizo el siguiente enfoque, que es simple y funciona para mi proyecto .NET Core 2.0.
Agregue lo siguiente a su .csproj dentro del PropertyGroup:
Esto define una función de propiedad que puede acceder en su comando de compilación previa.
Su precompilación se ve así
Establezca la propiedad de BuildTimeStamp.txt en Recurso incorporado.
Ahora puedes leer la marca de tiempo como esta
fuente
"$(ProjectDir)BuildTimeStamp.txt"
) o se romperá cuando haya espacios en los nombres de las carpetas.$([System.DateTime]::Now.tostring("MM/dd/yyyy HH:mm:ss"))
lugar de$([System.DateTime]::Now)
La opción que no se discute aquí es insertar sus propios datos en AssemblyInfo.cs, el campo "AssemblyInformationalVersion" parece apropiado: tenemos un par de proyectos en los que estábamos haciendo algo similar como un paso de compilación (sin embargo, no estoy completamente satisfecho con el que funciona así que no quiero reproducir lo que tenemos).
Hay un artículo sobre el tema en codeproject: http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx
fuente
Necesitaba una solución universal que funcionara con un proyecto NETStandard en cualquier plataforma (iOS, Android y Windows). Para lograr esto, decidí generar automáticamente un archivo CS a través de un script de PowerShell. Aquí está el script de PowerShell:
Guarde el archivo PowerScript como GenBuildDate.ps1 y agréguelo a su proyecto. Finalmente, agregue la siguiente línea a su evento Pre-Build:
Asegúrese de que BuildDate.cs esté incluido en su proyecto. Funciona como un campeón en cualquier sistema operativo!
fuente
Solamente lo hago:
fuente
Puede usar este proyecto: https://github.com/dwcullop/BuildInfo
Aprovecha T4 para automatizar la marca de tiempo de la fecha de compilación. Hay varias versiones (diferentes ramas), incluida una que le proporciona el Git Hash de la rama actualmente desprotegida, si le gusta ese tipo de cosas.
Divulgación: escribí el módulo.
fuente
Un enfoque diferente y compatible con PCL sería utilizar una tarea en línea de MSBuild para sustituir el tiempo de compilación en una cadena que devuelve una propiedad de la aplicación. Estamos utilizando este enfoque con éxito en una aplicación que tiene proyectos Xamarin.Forms, Xamarin.Android y Xamarin.iOS.
EDITAR:
Simplificado moviendo toda la lógica al
SetBuildDate.targets
archivo y usando enRegex
lugar de una simple sustitución de cadena para que el archivo pueda ser modificado por cada compilación sin un "reinicio".La definición de tarea en línea de MSBuild (guardada en un archivo SetBuildDate.targets local para el proyecto Xamarin.Forms para este ejemplo):
Invocando la tarea en línea anterior en el archivo csproj Xamarin.Forms en Target BeforeBuild:
La
FilePath
propiedad se establece en unBuildMetadata.cs
archivo en el proyecto Xamarin.Forms que contiene una clase simple con una propiedad de cadenaBuildDate
, en la que se sustituirá el tiempo de compilación:Agregue este archivo
BuildMetadata.cs
al proyecto. Será modificado por cada compilación, pero de una manera que permita compilaciones repetidas (reemplazos repetidos), por lo que puede incluirlo u omitirlo en el control de origen según lo desee.fuente
Puede usar un evento posterior a la compilación del proyecto para escribir un archivo de texto en su directorio de destino con la fecha y hora actual. Luego puede leer el valor en tiempo de ejecución. Es un poco hacky, pero debería funcionar.
fuente
No estoy seguro, pero tal vez el Build Incrementer ayuda.
fuente
Una pequeña actualización de la respuesta "New Way" de Jhon.
Debe crear la ruta en lugar de usar la cadena CodeBase cuando trabaje con ASP.NET/MVC
fuente
Puede iniciar un paso adicional en el proceso de compilación que escribe una marca de fecha en un archivo que luego se puede mostrar.
En la pestaña de propiedades del proyecto, mira la pestaña de eventos de construcción. Hay una opción para ejecutar un comando de compilación previa o posterior.
fuente
Usé la sugerencia de Abdurrahim. Sin embargo, parecía dar un formato de tiempo extraño y también agregó la abreviatura para el día como parte de la fecha de compilación; ejemplo: dom 24/12/2017 13: 21: 05.43. Solo necesitaba la fecha, así que tuve que eliminar el resto usando la subcadena.
Después de agregar el
echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"
al evento previo a la compilación, acabo de hacer lo siguiente:La buena noticia aquí es que funcionó.
fuente
Si se trata de una aplicación de Windows, puede usar la ruta ejecutable de la aplicación: nuevo System.IO.FileInfo (Application.ExecutablePath) .LastWriteTime.ToString ("aaaa.MM.dd")
fuente
podría ser
Assembly execAssembly = Assembly.GetExecutingAssembly(); var creationTime = new FileInfo(execAssembly.Location).CreationTime; // "2019-09-08T14:29:12.2286642-04:00"
fuente