Что такое регулярное выражение для обновления номера сборки сборки в файле AssemblyInfo.cs? - PullRequest
0 голосов
/ 21 июля 2009

Теперь я пишу VS 2008 Macro для замены версии Assembly в файле AssemblyInfo.cs. Из MSDN версия сборки должна быть записана с использованием следующего шаблона.

MAJOR.MINOR [.build [.revision]]

Пример

  • 1,0
  • 1.0.1234
  • 1.0.1234.0

Мне нужно динамически сгенерировать номер сборки для файла AssemblyInfo.cs и использовать регулярное выражение для замены старого номера сборки новым сгенерированным номером сборки.

У вас есть Регулярное выражение для решения этого вопроса? Кроме того, номер сборки не должен содержаться в комментариях, как показано ниже. Наконец, не забудьте проверить свои регулярные выражения для встроенного комментария.

Не заменять ни одного прокомментированного номера сборки

//[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")]
 */

Заменить номер сборки без комментариев

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

Подсказка.

Пожалуйста, попробуйте регулярное выражение в Онлайн-инструмент тестирования регулярных выражений

Ответы [ 4 ]

3 голосов
/ 21 июля 2009

Это несколько грубо, но вы могли бы сделать следующее.

Поиск:

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

Заменить на:

\1####

Где #### - строка замены.

Это регулярное выражение работает следующим образом:

  1. Он начинается с поиска строк, начинающихся с \ [сборка \: , ( ^ указывает начало строки, обратные косые черты экранируют специальные символы), за которыми следует ...
  2. ... некоторый буквенный идентификатор : w , за которым следует ...
  3. ... открывающая скобка \ (, за которой следует ...
  4. ... Начало строки версии в кавычках \ "0 \ .1 \. , за которой следует ...
  5. ... звездочка \ *.
  6. Шаги 1-4 фиксируются как первое помеченное выражение с использованием фигурных скобок {} , окружающих их.
  7. Строка замены отбрасывает дословно помеченное выражение, так что ему не наносится вред: \ 1 , за ним следует строка замены, некоторые ####.

Закомментированные строки игнорируются, так как они не начинаются с [assembly:. Последующие встроенные комментарии остаются нетронутыми, поскольку они не фиксируются регулярным выражением.

Если это не совсем то, что вам нужно, довольно просто поэкспериментировать с регулярным выражением для захвата и / или замены различных частей строки.

0 голосов
/ 21 июля 2009

Вы можете добиться того же эффекта намного легче, загрузив и установив MS Build Extension Pack и добавив следующую строку в верхней части файла .csproj:

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

Это автоматически использует текущую дату (MMdd) в качестве номера сборки и увеличивает номер редакции для вас. Теперь, чтобы переопределить младшую и основную версии, для которых по умолчанию установлено значение 1.0, просто добавьте следующее в любом месте файла .csproj:

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

Вы можете дополнительно настроить способ создания номера сборки и редакции и даже установить компанию, авторское право и т. Д., Задав другие свойства, см. На этой странице список свойств.

0 голосов
/ 21 июля 2009

Я просто нахожу ответ на свой вопрос. Но ответ очень, очень сложный и очень длинный регулярное выражение. Кстати, я использую этот синтаксис только 1 раз на решение. Таким образом, это не влияет на общую производительность. Пожалуйста, посмотрите мой полный исходный код.

Модуль 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

Модуль 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

Спасибо всем вам

PS. Особая благодарность [RegExr: онлайн-инструмент тестирования регулярных выражений] [1]. Лучший онлайн инструмент для регулярных выражений, в который я когда-либо играл. [1]: http://gskinner.com/RegExr/

0 голосов
/ 21 июля 2009

Я сомневаюсь, что использование регулярных выражений принесет вам большую пользу. Хотя можно было бы сформулировать выражение, которое соответствует «незакомментированным» атрибутам версии сборки, его будет сложно поддерживать и понимать.

Вы очень сильно усложняете себе синтаксис, который вы представляете. Как насчет применения стандарта кодирования в вашем файле AssemblyInfo.cs, который говорит, что строки всегда должны быть закомментированы с началом // и запрещать встроенные комментарии? Тогда это должно быть достаточно просто, чтобы разобрать его с помощью StreamReader.

Если вы не можете этого сделать, то есть только один парсер, который гарантированно обрабатывает все ваши крайние случаи, и это компилятор C #. Как насчет того, чтобы просто скомпилировать сборку и затем отразить ее для определения номера версии?

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

Если вы просто заинтересованы в увеличении номера сборки, вам следует взглянуть на этот вопрос: Можно ли автоматически увеличивать версию сборки файла при использовании Visual Studio?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...