martedì 5 ottobre 2010

Assmbly Build Version...

Mi è capitato di voler sapere la data di build di un assembly (non la data di creazione o la data in cui è stato copiato.. per quello basta leggerle da file sistem...) e non è stato semplice comprendere dove e come reperire l'informazione.

Tuttavia, il linker (in fase di build) si occupa anche di questo... E' necessario fare una premessa, questo codice in parte trovato on line, in parte modificato da me, ha lo scopo nudo e crudo di recuperare una porzione di byte che rappresentano proprio o quasi la data di buil di un assembly.

E' doveroso ricordare che quest'informazione proviene in parte o in toto dall'assembly Version che se compilato con logica (1.0.*) funziona... (nel mio caso funziona anche con (1.0.0.0).

private string GetAssemblyBuildDate()
{
//
// percorso dell'assembly
//
string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
//
// posizione di Offset dell'header..
//
const int c_PeHeaderOffset = 60;
//
// posizione in cui il linker deposita la data durante la sua fase.
//
const int c_LinkerTimestampOffset = 8;
//
// buffer
//
byte[] b = new byte[2048];
//
// stream di byte.
//
System.IO.Stream sAssembly = null;

try
{
//
// operazione ad assembly aperto...
//
sAssembly = new System.IO.FileStream(
filePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read
);
//
// legge dal byte 0 al 2048'esimo
//
sAssembly.Read(b, 0, 2048);
}
finally
{
//
// se non è riuscito nel tentativo di aprire il buffer..
//
if (sAssembly != null)
{
sAssembly.Close();
}
}

//
// legge dal buffer i primi 60 char/byte
//
int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
//
// crea il limite (superiore byte che rappresentano la data di build in secondi...) partendo da ciò che letto
//
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);

//
// si crea la data di comodo a cui sommare il limite
//
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);

//
// li aggiunge alla data di comodo
//
dt = dt.AddSeconds(secondsSince1970);
//
// "aggiunge" il gmt
//
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);

return dt.ToShortDateString() + " " + dt.ToLongTimeString();
}

Come sempre se recuperate questo codice, potrebbe essere necessario verificare l'indentazione dei commenti ...

Nessun commento: