2012-01-05 7 views
11

Sto scrivendo un file batch per automatizzare una serie di attività. Uno di questi compiti è aggiornare la versione delle DLL nella mia soluzione, modificando il file assemblyinfo.cs nei vari progetti nella mia soluzione; e infine chiamare msbuild.exe per compilare la soluzione.MSbuild per l'aggiornamento del file assemblyinfo

A tale proposito, è possibile scrivere uno script da riga di comando per aggiornare i vari file assemblyinfo.cs nella mia soluzione .net. Preferirei chiamare msbuild dalla linea di comando stessa e non creare un altro file script di msbuild.

Come si fa a utilizzare MSBuild? c'è un altro modo per farlo?

Grazie per il vostro tempo ...

+0

Utilizzare msbuild: http://stackoverflow.com/questions/4562845/how-can-i-change-assembly-version-number-using-assemblyinfotask/4970347#4970347 –

+2

l'down-voter ha un motivo per non funzionare votare o il down-voter ha solo una brutta giornata? – user20358

risposta

9

Modificare file con file batch di DOS cmd è piuttosto peloso senza l'ausilio di altri strumenti. È necessario utilizzare qualcosa come il comando/f per scorrere le righe e quindi elaborare ogni riga. Ad esempio, cerca la riga che inizia: "[assembly: AssemblyVersion" e sostituiscila con qualcos'altro.

Tuttavia, se non hai molto nel tuo AssemblyInfo.cs (e ricorda che è possibile dividere AssemblyInfo.cs in più file CS se si desidera) Suggerisco di creare il file da zero con un paio di echo dichiarazioni.

Se sono disponibili altri strumenti come sed.exe, le modifiche possono essere eseguite facilmente.

La mia preferenza in questi giorni sarebbe quella di andare per un semplice script PowerShell, che potrebbe mangiare questo a colazione e ti dà accesso alle librerie. Net se ne hai bisogno.

Ecco una forma di template di esso:

(Get-Content AssemblyInfo.template.cs) -replace "{version}","1.2.3.4" > AssemblyInfo.cs 

Ecco un modulo che utilizza le espressioni regolari per sostituire qualunque sia il numero di versione è lì:

$x = 'Version("{0}")' -f "1.2.3.4" 
$content = Get-Content AssemblyInfo.cs 
$content -replace 'Version\(".*"\)',$x > AssemblyInfo.cs 
+0

Non conosco le espressioni regolari. Ho provato la linea che hai suggerito sopra e ha pulito il file AssemblyInfo.cs. – user20358

+1

Mi dispiace, la pipeline stava troncando il file originale prima che fosse completato/iniziato a leggerlo. Ho modificato l'esempio con una correzione per leggere il contenuto originale come passaggio separato. – StephenD

7

Non c'è un MS Costruire compito per la modifica le AssemblyInfo.cs

abbiamo qualcosa di simile nel nostro publish.proj

<Target Name="SolutionInfo"> 
    <Message Text="Creating Version File:  $(Major).$(Minor).$(Build).$(Revision)"/> 


<AssemblyInfo 
     CodeLanguage="CS" 
     OutputFile="$(BuildInputDir)\SolutionInfo.cs" 
     AssemblyTitle="$(Company) $(Product)$(ProductAppendix)" 
     AssemblyDescription="$(Company) $(Product)$(ProductAppendix)" 
     AssemblyCompany="$(Company)" 
     AssemblyProduct="$(Product)" 
     AssemblyCopyright="Copyright © $(Company)"  
     ComVisible="false" 
     CLSCompliant="false" 
     Guid="9E77382C-5FE3-4313-B099-7A9F24A4C328" 
     AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)" 
     AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" /> 
</Target> 
+0

posso inserirlo nel mio file batch? Sto cercando qualcosa che posso richiamare dal mio file batch in questo modo ... msbuild {intero gruppo di parametri che seguono qui ..} – user20358

+0

@ user20358 di sicuro basta metterlo in un file .proj e chiamare MSBuild con qualcosa come questo: " % windir% \ Microsoft.NET \ Framework \ v4.0.30319 \ MSBuild.exe "/ nologo/verbosità: normale publish.proj% */property: ReleaseTier = stable – Cilvic

8

Questo è il codice MSBuild di destinazione in cui posso aggiornare tutti i miei file AssemblyInfo.cs (Devi init articoli AssemblyInfoFilesToUpdate collezioni prima di utilizzare questo target):

<!-- Update all the assembly info files with generated version info --> 
    <Target Name="AfterGet" Condition="'$(ServerBuild)'=='true' And '$(BuildVersion)'!=''"> 
    <Message Text="Modifying AssemblyInfo files..." /> 
    <!-- Clear read-only attributes --> 
    <Attrib Files="@(AssemblyInfoFilesToUpdate)" Normal="true" /> 
    <!-- Update AssemblyVersion --> 
    <FileUpdate Files="@(AssemblyInfoFilesToUpdate)" 
      Regex="AssemblyVersion\(&quot;.*&quot;\)\]" 
      ReplacementText="AssemblyVersion(&quot;$(BuildVersion)&quot;)]" /> 
    <!-- Update AssemblyFileVersion --> 
    <FileUpdate Files="@(AssemblyInfoFilesToUpdate)" 
      Regex="AssemblyFileVersion\(&quot;.*&quot;\)\]" 
      ReplacementText="AssemblyFileVersion(&quot;$(BuildVersion)&quot;)]" /> 
    <Message Text="AssemblyInfo files updated to version &quot;$(BuildVersion)&quot;" /> 
    </Target> 

sto usando FileUpdate task from MSBuildCommunityTasks.

+0

In alternativa è possibile utilizzare il task' FileUpdate' una volta specificando ' Argomento Regex' come 'Regex =" (\ d +) \. (\ D +) \. (\ D +) \. (\ D +) "'. –

+0

@DerekW Questo potrebbe avere conseguenze indesiderate. –

+0

@RhysBevilaqua: potresti fornire un esempio (uno dove AssemblyFileVersion e AssemblyVersion devono essere uguali)? –

2

Una domanda abbastanza vecchia con una risposta accettata, ma anch'io (a causa delle limitazioni sul server di compilazione di elementi di configurazione) volevo farlo tramite un file batch invece di powershell o MS Build Tasks. Ecco cosa mi è venuto in mente: presuppone che la directory della soluzione sia la directory corrente:

SetVersion.bat

@echo off 
setlocal enabledelayedexpansion 

if [%1] == [] GOTO :USAGE 
set version=%1 
set fileversion=%1 
set informationalversion=%1 

if [%2] NEQ [] SET fileversion=%2 
if [%3] NEQ [] SET informationalversion=%3 

echo Setting assembly version information 

for /F "delims=" %%f in ('dir /s /b Assemblyinfo.cs') do (
    echo ^> %%f 

    pushd %%~dpf 

    for /F "usebackq delims=" %%g in ("AssemblyInfo.cs") do (
     set ln=%%g 
     set skip=0 

     if "!ln:AssemblyVersion=!" NEQ "!ln!" set skip=1 
     if "!ln:AssemblyFileVersion=!" NEQ "!ln!" set skip=1 
     if "!ln:AssemblyInformationalVersion=!" NEQ "!ln!" set skip=1 

     if !skip!==0 echo !ln! >> AssemblyInfo.cs.versioned 
    ) 

    echo [assembly: AssemblyVersion^("%version%"^)] >> AssemblyInfo.cs.versioned 
    echo [assembly: AssemblyFileVersion^("%fileversion%"^)] >> AssemblyInfo.cs.versioned 
    echo [assembly: AssemblyInformationalVersion^("%informationalversion%"^)] >> AssemblyInfo.cs.versioned 

    copy /y AssemblyInfo.cs AssemblyInfo.cs.orig 
    move /y AssemblyInfo.cs.versioned AssemblyInfo.cs 

    popd 
) 
echo Done^^! 

GOTO:EOF 

:USAGE 
echo Usage: 
echo. 
echo SetVersion.bat Version [FileVersion] [InformationalVersion] 
echo. 

Spiegazione

Fondamentalmente questo sarà ricorsivamente tutte le sottocartelle e identificare i file AssemblyInfo.cs, e poi la linea per linea copiare i file in un nuovo file. Se viene trovata una qualsiasi delle voci della versione dell'assembly, vengono omesse. Quindi, alla fine di ogni file, aggiunge i numeri di versione forniti.

Per i guru del lotto, alcuni potrebbero chiedere perché preferisco usare for /F con dir /s anziché for /R per scorrere i file. Fondamentalmente, è perché trovo il ricorsivo per essere un po 'goffo dal momento che verrà eseguito per tutte le sottodirectory (non solo i file corrispondenti) quando non vengono forniti i caratteri jolly. L'utilizzo del comando dir è più coerente e più facile da prevedere.

Nota: Questo file batch rimuoverà tutte le righe vuote dai AssemblyInfo.cs file

+0

wow. Grazie mille. Questo mi ha salvato da un sacco di lavoro –