2009-07-21 5 views
0

Maintenant, j'écris VS 2008 Macro pour remplacer la version d'assemblage dans le fichier AssemblyInfo.cs. À partir de MSDN, la version d'assembly doit être écrite en utilisant le modèle suivant.Quelle est l'expression régulière pour mettre à jour le numéro de build de l'assembly dans le fichier AssemblyInfo.cs?

major.minor [.build [.revision]]

Exemple

  • 1,0
  • 1.0.1234
  • 1.0.1234.0

Je dois générer dynamiquement le numéro de build pour le fichier 'AssemblyInfo.cs' et utiliser Regular Expression pour remplacer l'ancien numéro de build par le nouveau numéro de build généré.

Avez-vous des Expressions Régulières pour résoudre cette question? De plus, le numéro de build ne doit pas être contenu dans une déclaration commentée comme ci-dessous. Enfin, n'oubliez pas de vérifier votre regex pour le commentaire en ligne.

Ne remplacez aucun numéro de build a commenté

//[assembly: AssemblyVersion("0.1.0.0")] 

/*[assembly: AssemblyVersion("0.1.0.0")]*/ 

/* 
[assembly: AssemblyTrademark("")] 
[assembly: AssemblyCulture("")] 
[assembly: ComVisible(false)] 
[assembly: AssemblyVersion("0.1.0.0")] 
*/ 

Remplacer le numéro de build qui ne sont pas commenté

[assembly: AssemblyVersion("0.1.0.0")] // inline comment 
/* inline comment */ [assembly: AssemblyVersion("0.1.0.0")] 
[assembly: /*inline comment*/AssemblyVersion("0.1.0.0")] 

Conseil.

S'il vous plaît essayer votre regex à Online Regular Expression Testing Tool

Répondre

0

Je trouve juste réponse à ma question. Mais la réponse est très très compliquée: très longue regex. En passant, j'utilise cette syntaxe seulement 1 fois par solution. Donc, cela n'affecte pas les performances globales. S'il vous plaît regardez mon code source complet.

Module EnvironmentEvents.vb

Public Module EnvironmentEvents 
    Private Sub BuildEvents_OnBuildBegin(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildBegin 
     If DTE.Solution.FullName.EndsWith(Path.DirectorySeparatorChar & "[Solution File Name]") Then 
      If Scope = vsBuildScope.vsBuildScopeSolution And Action = vsBuildAction.vsBuildActionRebuildAll Then 
       AutoGenerateBuildNumber() 
      End If 
     End If 
    End Sub 
End Module 

Module AssemblyInfoHelp.vb

Public Module AssemblyInfoHelper 

    ReadOnly AssemblyInfoPath As String = Path.Combine("Common", "GlobalAssemblyInfo.cs") 

    Sub AutoGenerateBuildNumber() 

     'Declear required variables 
     Dim solutionPath As String = Path.GetDirectoryName(DTE.Solution.Properties.Item("Path").Value) 
     Dim globalAssemblyPath As String = Path.Combine(solutionPath, AssemblyInfoPath) 
     Dim globalAssemblyContent As String = ReadFileContent(globalAssemblyPath) 
     Dim rVersionAttribute As Regex = New Regex("\[[\s]*(\/\*[\s\S]*?\*\/)?[\s]*assembly[\s]*(\/\*[\s\S]*?\*\/)?[\s]*:[\s]*(\/\*[\s\S]*?\*\/)?[\s]*AssemblyVersion[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\([\s]*(\/\*[\s\S]*?\*\/)?[\s]*\""([0-9]+)\.([0-9]+)(.([0-9]+))?(.([0-9]+))?\""[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\)[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\]") 
     Dim rVersionInfoAttribute As Regex = New Regex("\[[\s]*(\/\*[\s\S]*?\*\/)?[\s]*assembly[\s]*(\/\*[\s\S]*?\*\/)?[\s]*:[\s]*(\/\*[\s\S]*?\*\/)?[\s]*AssemblyInformationalVersion[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\([\s]*(\/\*[\s\S]*?\*\/)?[\s]*\""([0-9]+)\.([0-9]+)(.([0-9]+))?[\s]*([^\s]*)[\s]*(\([\s]*Build[\s]*([0-9]+)[\s]*\))?\""[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\)[\s]*(\/\*[\s\S]*?\*\/)?[\s]*\]") 

     'Find Version Attribute for Updating Build Number 
     Dim mVersionAttributes As MatchCollection = rVersionAttribute.Matches(globalAssemblyContent) 
     Dim mVersionAttribute As Match = GetFirstUnCommentedMatch(mVersionAttributes, globalAssemblyContent) 
     Dim gBuildNumber As Group = mVersionAttribute.Groups(9) 
     Dim newBuildNumber As String 

     'Replace Version Attribute for Updating Build Number 
     If (gBuildNumber.Success) Then 
      newBuildNumber = GenerateBuildNumber(gBuildNumber.Value) 
      globalAssemblyContent = globalAssemblyContent.Substring(0, gBuildNumber.Index) + newBuildNumber + globalAssemblyContent.Substring(gBuildNumber.Index + gBuildNumber.Length) 
     End If 

     'Find Version Info Attribute for Updating Build Number 
     Dim mVersionInfoAttributes As MatchCollection = rVersionInfoAttribute.Matches(globalAssemblyContent) 
     Dim mVersionInfoAttribute As Match = GetFirstUnCommentedMatch(mVersionInfoAttributes, globalAssemblyContent) 
     Dim gBuildNumber2 As Group = mVersionInfoAttribute.Groups(12) 

     'Replace Version Info Attribute for Updating Build Number 
     If (gBuildNumber2.Success) Then 
      If String.IsNullOrEmpty(newBuildNumber) Then 
       newBuildNumber = GenerateBuildNumber(gBuildNumber2.Value) 
      End If 

      globalAssemblyContent = globalAssemblyContent.Substring(0, gBuildNumber2.Index) + newBuildNumber + globalAssemblyContent.Substring(gBuildNumber2.Index + gBuildNumber2.Length) 
     End If 

     WriteFileContent(globalAssemblyPath, globalAssemblyContent) 

    End Sub 

    Function GenerateBuildNumber(Optional ByVal oldBuildNumber As String = "0") As String 

     oldBuildNumber = Int16.Parse(oldBuildNumber) + 1 

     Return oldBuildNumber 

    End Function 

    Private Function GetFirstUnCommentedMatch(ByRef mc As MatchCollection, ByVal content As String) As Match 
     Dim rSingleLineComment As Regex = New Regex("\/\/.*$") 
     Dim rMultiLineComment As Regex = New Regex("\/\*[\s\S]*?\*\/") 

     Dim mSingleLineComments As MatchCollection = rSingleLineComment.Matches(content) 
     Dim mMultiLineComments As MatchCollection = rMultiLineComment.Matches(content) 

     For Each m As Match In mc 
      If m.Success Then 
       For Each singleLine As Match In mSingleLineComments 
        If singleLine.Success Then 
         If m.Index >= singleLine.Index And m.Index + m.Length <= singleLine.Index + singleLine.Length Then 
          GoTo NextAttribute 
         End If 
        End If 
       Next 

       For Each multiLine As Match In mMultiLineComments 
        If multiLine.Success Then 
         If m.Index >= multiLine.Index And m.Index + m.Length <= multiLine.Index + multiLine.Length Then 
          GoTo NextAttribute 
         End If 
        End If 
       Next 

       Return m 
      End If 
NextAttribute: 
     Next 

     Return Nothing 

    End Function 

End Module 

Merci vous tous les corps

PS. Spécial Merci à [RegExr: Outil de test d'expression régulière en ligne] [1]. Le meilleur outil regex en ligne que j'ai jamais joué. [1]: http://gskinner.com/RegExr/

3

C'est un peu brut, mais vous pouvez faire ce qui suit.

Rechercher:

^{\[assembly\: :w\(\"0\.1\.}\* 

Remplacer par:

\1#### 

Où est votre chaîne #### de remplacement.

Ce travail regex comme suit:

  1. Il commence par la recherche de lignes commençant par \ [assembly \:, (^ indique le début fo une ligne, antislashs échapper à des caractères spéciaux) suivi ...
  2. ... autre identificateur alphabétique : w, suivi par ...
  3. ... une accolade d'ouverture \ (, suivi par ...
  4. ... Le début de la chaîne de version, entre guillemets \ "0 \ .1 \., enfin suivi de ...
  5. ...un astérisque \ *.
  6. Les étapes 1 à 4 sont capturées en tant que première expression marquée en utilisant les accolades {} qui les entourent.
  7. La chaîne de remplacement supprime l'expression étiquetée verbatim, afin de ne pas nuire à: \ 1, suivi de votre chaîne de remplacement, ####.

Les lignes commentées sont ignorées car elles ne commencent pas par [assembly: .Les commentaires en ligne subséquents sont laissés intacts car ils ne sont pas capturés par la regex.

Si ce n'est pas exactement ce dont vous avez besoin, il est assez simple d'expérimenter avec l'expression régulière pour capturer et/ou remplacer différentes parties de la ligne.

+0

Cette expression régulière ne corrige pas parce que j'ai besoin de détecter le commentaire de cet attribut. Mais votre regex ne peut pas le détecter. –

+0

Pouvez-vous clarifier? voulez-vous que l'astérisque soit remplacé dans le commentaire ou non? Si vous souhaitez que le remplacement se produise à l'intérieur des lignes commentées, vous pouvez supprimer le caractère^au début de l'expression régulière. Cela supprimera l'exigence que la correspondance se produise au début d'une ligne. –

+0

Veuillez lire ma question de réécriture. –

0

Je doute que l'utilisation d'expressions régulières vous fera beaucoup de bien ici. Bien qu'il soit possible de formuler une expression qui corresponde aux attributs de la version d'assemblage "non commentée", il sera difficile à maintenir et à comprendre.

Vous faites très très dur sur vous-même avec la syntaxe que vous présentez. Qu'en est-il de l'application d'une norme de codage dans votre fichier AssemblyInfo.cs qui dit que les lignes doivent toujours être commentées avec // un début et interdisent les commentaires en ligne? Ensuite, il devrait être assez facile de l'analyser en utilisant un StreamReader.

Si vous ne pouvez pas faire cela alors il n'y a qu'un seul analyseur qui est garanti pour gérer tous vos cas de bord et c'est le compilateur C#. Que diriez-vous juste de compiler votre assembly et ensuite le refléter pour détecter le numéro de version?

var asm = Assembly.LoadFile("foo.dll"); 
var version = Assembly.GetExecutingAssembly().GetName().Version; 

Si vous êtes simplement intéressé à incrémenter votre numéro de build vous devriez jeter un oeil à cette question: Can I automatically increment the file build version when using Visual Studio?

+0

Je dois lire le numéro de build avant que VS le compile. Donc, je ne peux pas utiliser votre code ci-dessus. De plus, je peux utiliser une simple fonction Substring (pour détecter l'emplacement de l'attribut AssemblyVersion) et une simple fonction Regex (pour supprimer un commentaire) pour le lire. Mais je ne peux pas utiliser seulement regex pour le lire (ou le remplacer). –

0

Vous pouvez obtenir même effet beaucoup plus facilement, en téléchargeant et installant MS Build Extension Pack et en ajoutant la ligne suivante en haut de votre fichier .csproj:

<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.VersionNumber.targets"/> 

Cela utilisera automatiquement la date actuelle (MMdd) comme numéro de build, et incrémenter le numéro de révision pour vous. Maintenant, pour remplacer les versions mineures et majeures, qui sont définies à 1.0 par défaut, il suffit d'ajouter le suivant partout dans le fichier.fichier csproj:

<PropertyGroup> 
<AssemblyMajorVersion>2</AssemblyMajorVersion> 
<AssemblyFileMajorVersion>1</AssemblyFileMajorVersion> 
</PropertyGroup> 

Vous pouvez personnaliser la façon dont le nombre et la révision de construire sont générés, et l'entreprise a même établi, le droit d'auteur, etc. en définissant d'autres propriétés, see this page pour la liste des propriétés.

+0

Si cela m'aide seulement pour spécifier l'assemblage majeur verion & assemblyfilemajorverion. Ce n'est pas mon exigence. Actuellement, j'utilise AssemblyInfo.cs unique pour tous les projets. En outre, votre pack d'extension ne peut pas aider à générer dynamiquement le numéro de build. Merci pour une autre solution. –

+0

En fait, il génère des numéros de build et de révision. Je mets à jour la réponse, vérifie-la. – zvolkov

+0

Est-il possible de changer la règle de génération automatique? –

Questions connexes