Como posso obter o atual DateTime do Precompiler em C #?
-
03-07-2019 - |
Pergunta
Em C # 3.0, eu tenho uma propriedade que é supor para conter a versão da classe. O número da versão é simplesmente a data e hora da compilação. Agora, eu tenho o seguinte código:
public DateTime Version
{
get { return DateTime.UtcNow; }
}
Obviamente, isso é errado desde que esta propriedade me retorna a data e hora atual. Então, é o pré-compilador pode print o DateTime em tempo de compilação? Neste caso, eu poderia fazer algo semelhante ao abaixo.
public DateTime Version
{
get { return new DateTime("PRECOMPILER DATE"); }
}
Solução
C # não tem o conceito de macros; no entanto, você pode usar outras ferramentas em seu script de construção (csproj / NANT / etc) para manipular a fonte antes que compila. Eu uso este, por exemplo, para definir o número de revisão da revisão SVN atual.
A opção mais barata é um evento de pré-compilação (você pode fazer isso através do diálogo de propriedades do projeto no VS): essencialmente um arquivo bat que é executado antes de construção; Você pode, então, roteiro quaisquer mudanças que você precisa. Uma opção mais sofisticada é tarefas de construção.
Por exemplo, a biblioteca de utilitários aqui inclui uma tarefa Time
e uma tarefa FileUpdate
; deve (em teoria) ser possível cadeia os dois juntos para emular o que você precisa.
Pessoalmente, eu usaria os detalhes [AssemblyVersion]
em vez do tempo - se você ligar este ao seu sistema de controle de origem, o que torna muito fácil de encontrar a versão de ofensa; para a minha versão SVN, eu, em seguida, usar (no meu construir proj):
<!-- 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' />
E agora minha montagem de versão é correta, incluindo o arquivo-versão que é reportado pelo sistema operacional.
Outras dicas
Você pode recuperá-la a partir da própria dll ( Fonte: 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;
}
Não há equivalente para o pré-processador diretiva __TIME__
em C #, O melhor que você pode fazer é começar a montagem atual e obter a data de criação, ele conterá o tempo de compilação. Consulte aqui
Eu não acho que há uma maneira de fazer isso em C # -. Estilo C ++ definições de macro são explicitamente anulado
Você poderia trabalhar em torno dele usando a data da última modificação do conjunto, ou potencialmente incluir um arquivo de texto como um recurso incorporado e adicionar uma ação de compilação personalizado que escreve a data / hora atual nele.
Não há nenhuma directiva __TIME__
pré-processador, mas há outras coisas que você poderia usar, como o tempo de criação do conjunto. Você também pode considerar o uso de substituição de palavras-chave do seu sistema de controle de origem ($ Date $ na subversão).
O Desenvolver podem ser recuperados a partir de os metadados de uma montagem, e pode ser ajustado para coincidir com a data da compilação.
Normalmente, você vai encontrar, ou criar uma entrada no arquivo AssemblyInfo.cs. Quando o projeto é criado usando Visual Studio. Um exemplo:
[assembly: AssemblyVersion("1.0.*")]
A cotação para a documentação sobre AssemblyVersionAttribute . (Eu negrito algumas partes importantes)
Você pode especificar todos os valores ou você pode aceitar o número de compilação padrão, número de revisão, ou ambos, utilizando uma asterisco (). Por exemplo, [Montagem: AssemblyVersion ( "2.3.25.1")] indica 2 como a versão principal, como três a versão menor, 25 como a construção número, e 1 como o número de revisão. Um número de versão, como [Assembly: AssemblyVersion ( "1.2 ")] especifica uma como a versão principal, como dois a versão secundária, e aceita a números de compilação e revisão padrão. A número da versão, como [Montagem: AssemblyVersion ( "1.2.15 *")] especifica uma como a versão principal, como dois a versão menor, 15 como a construção número, e aceita o padrão número de revisão. A construção padrão incrementos número diário. O padrão número de revisão é aleatória.
Como você pode ver, se você pode definir um número de compilação padrão com este. O número de compilação padrão é um valor que é incrementado a cada dia.
Você pode então recuperar o número de compilação usando a AssemblyName.Version propriedade. Os exemplos fornecidos pelo MSDN deve você ir.
O número de compilação padrão é o número de dias desde 1/1/2000.
Esta questão também tem uma explicação clara sobre como usar isso.
Você está procurando algo como isto:
(Get é a Data de construção da Assembléia via Versão-Info; Build-N é dias desde 1.1.2000)
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime versionsDatum = new DateTime(2000, 1, 1);
versionsDatum = versionsDatum.AddDays(version.Build);