Как смириться с отсутствием макросов в Visual Studio 2012

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

Наши макросы не из тех, что вы записываете какие-то движения мыши; все они зависят от объектов автоматизации EnvDTE* VS. С VS 2012, отбрасывающим макросы, мы не знаем, сможем ли мы вообще обновиться, не оказывая существенного влияния на команду.

Я знаю, что Microsoft движется в направлении VS Addins, и я готов исследовать этот путь, но у меня возникли проблемы с поиском примеров кода или документации о том, как надстройка VS может взаимодействовать с активным файлом кода в Visual Studio.

Например, вот макрос, который мы используем все время, который применяет наш шаблон проектирования оболочки Try ко всем методам, способным генерировать необработанные исключения.

''' <summary>
'''  Wraps active method in Try* access wrappers.
''' </summary>
Sub InsertSingleMethodTryWrappers()
    Dim textSelection As TextSelection
    Dim codeElement As CodeElement

    textSelection = DTE.ActiveWindow.Selection

    DTE.UndoContext.Open("Generate Try Wrappers")  'Allow for single Undo operation to rollback all changes

    Try
        codeElement = textSelection.ActivePoint.CodeElement(vsCMElement.vsCMElementFunction)
        If Not (codeElement Is Nothing) Then
            Dim textSelection2 As TextSelection
            Dim codeFunction As CodeFunction
            'Dim codeFunction2 As CodeFunction2
            Dim editPoint As EditPoint
            Dim codeParameter As CodeParameter
            Dim parameters As CodeElements
            Dim codeElement2 As CodeElement
            Dim isVirtual As Boolean = False
            Dim strVirtual As String = String.Empty
            Dim strTypeName As String = String.Empty

            '' Cast the codeElement to codeFunction object
            codeFunction = codeElement

            '' Move cursor to the start of the method
            textSelection.MoveToPoint(codeFunction.GetStartPoint(vsCMPart.vsCMPartHeader))

            '' Should be able to use codeFunction.Kind.ToString to retrieve the function type
            '' vsCMFunctionVirtual if the method is virtual but there is a bug in the API
            '' that returns vsCMFunctionFunction even if the function is virtual (C# parsing bug?)
            ''
            '' vsCMFunction Type
            '' http://msdn.microsoft.com/en-us/library/envdte.vscmfunction(v=vs.80).aspx
            ''
            '' This frustrating bug means that we have to parse the header to determine if virtual
            textSelection.EndOfLine(True)
            If (textSelection.Text.IndexOf("virtual") > 0) Then
                isVirtual = True
                strVirtual = " virtual"
            End If
            textSelection.StartOfLine()

            '' Try not to screw up comments and attributes
            editPoint = GetNoneCommentOrAttribHeaderEditPoint(textSelection)
            If editPoint Is Nothing Then
                MsgBox("Could not find a line above the method that isn't a comment or attribute", _
                       MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Error")
                Exit Sub
            End If

            '' Create an EditPoint to inject Try* methods
            'editPoint = textSelection.TopPoint.CreateEditPoint()
            'editPoint.LineUp()  'Move up 1 line
            editPoint.EndOfLine()   'Go to end of line above signature
            editPoint.Insert(Environment.NewLine)   'Insert blank line for cleanliness
            editPoint.Insert(Environment.NewLine)   'Insert blank line for cleanliness
            editPoint.LineUp()  'Move up 1 line

            parameters = codeFunction.Parameters

            Dim strAccess As String : strAccess = GetAccessModifierString(codeFunction.Access) 'Access Modifier
            Dim strName As String : strName = codeElement.Name  'Member Name
            Dim strType As String : strType = codeFunction.Type.AsString    'Type Name

            '' Get the un-qualified object name
            If (strType.IndexOf(".") > 0) Then
                Dim arrType() As String = strType.Split(".")
                strTypeName = arrType(arrType.Length - 1)
            Else
                strTypeName = strType
            End If

            ''' Create parameter type/name arrayList
            Dim arrParams As System.Collections.ArrayList
            arrParams = New System.Collections.ArrayList()

            For Each codeElement2 In parameters
                codeParameter = codeElement2
                arrParams.Add(codeParameter.Type.AsString.Trim & " " & codeParameter.Name.Trim & ", ")
            Next

            Dim strParams As String
            Dim strParamNames As String

            '' Capture a string with parameter names and types and one just of names
            For Each strParam As String In arrParams
                strParams += strParam
                strParamNames += strParam.Split(" ")(1)
            Next

            '' Trim excess comma for members of type void
            If strType = "void" Then
                If Not String.IsNullOrEmpty(strParams) Then
                    If strParams.TrimEnd.EndsWith(",") Then
                        strParams = strParams.TrimEnd()
                        strParams = strParams.Remove(strParams.Length - 1, 1)
                    End If
                End If
            End If

            '' -- Try* swallow methods --
            '' we don't care what the exception is, we just want to know success or failure
            Dim strTrySwallowSignature As String
            Dim strTrySwallowBody As String
            Dim strTryOutParams As String
            Dim strOutDef As String
            Dim strOutSig As String

            '' Members of type 'void' get no out parameters
            If Not strType = "void" Then
                strTryOutParams = "out " & strTypeName & " outObjType"
                strOutDef = "outObjType = null;"
                strOutSig = " out outObjType,"
            End If

            strTrySwallowSignature = vbTab & vbTab & strAccess & strVirtual & " bool Try" & strName & "(" & strParams & strTryOutParams & ")"
            strTrySwallowBody = vbCrLf & vbTab & vbTab & "{" _
                              & vbCrLf & vbTab & vbTab & vbTab & "Exception exception;" _
                              & vbCrLf & vbTab & vbTab & vbTab & strOutDef _
                              & vbCrLf & vbTab & vbTab & vbTab & "return Try" & strName & "(" & strParamNames & strOutSig & " out exception);" _
                              & vbCrLf & vbTab & vbTab & "}"


            '' -- Try* re-throw methods --
            '' We want to know success or failure as well as the exception if it failed
            Dim strTryReThrowSignature As String
            Dim strTryReThrowBody As String

            '' Members of type 'void' only get out exception parameter
            If Not strType = "void" Then
                strTryOutParams = "out " & strTypeName & " outObjType, out Exception exception"
                'strOutDef = "outObjType = new " & strTypeName & "();"
                strOutDef = "outObjType = null;"
            Else
                strTryOutParams = "out Exception exception"
            End If

            strTryReThrowSignature = vbTab & vbTab & strAccess & strVirtual & " bool Try" & strName & "(" & strParams & strTryOutParams & ")"
            strTryReThrowBody = vbCrLf & vbTab & vbTab & "{" _
                              & vbCrLf & vbTab & vbTab & vbTab & "bool result = false;" _
                              & vbCrLf & vbTab & vbTab & vbTab & "exception = null;" _
                              & vbCrLf & vbTab & vbTab & vbTab & strOutDef _
                              & vbCrLf & vbTab & vbTab & vbTab & "try" _
                              & vbCrLf & vbTab & vbTab & vbTab & "{" _
                              & vbCrLf & vbTab & vbTab & vbTab & vbTab & "// insert code here " _
                              & vbCrLf & vbTab & vbTab & vbTab & vbTab & "//result = true; " _
                              & vbCrLf & vbTab & vbTab & vbTab & vbTab & "throw new NotImplementedException();" _
                              & vbCrLf & vbTab & vbTab & vbTab & "}" _
                              & vbCrLf & vbTab & vbTab & vbTab & "catch (Exception e)" _
                              & vbCrLf & vbTab & vbTab & vbTab & "{" _
                              & vbCrLf & vbTab & vbTab & vbTab & vbTab & "exception = e;" _
                              & vbCrLf & vbTab & vbTab & vbTab & "}" _
                              & vbCrLf & vbTab & vbTab & vbTab & "return result;" _
                              & vbCrLf & vbTab & vbTab & "}"

            editPoint.Insert(strTrySwallowSignature)
            editPoint.Insert(strTrySwallowBody)
            editPoint.Insert(vbCrLf & vbCrLf)
            editPoint.Insert(strTryReThrowSignature)
            editPoint.Insert(strTryReThrowBody)
            editPoint.Insert(vbCrLf)

        End If
    Catch Ex As Exception
        MsgBox(Ex.Message)
    Finally
        DTE.UndoContext.Close()
    End Try
End Sub

Может ли кто-нибудь указать мне, как надстройка VS 2012 может манипулировать активным/открытым файлом кода (используя EnvDTE * или любую другую объектную модель, доступную для 2012 года)?


person Neal Bailey    schedule 19.10.2012    source источник
comment
проблема решена... Макрообъектная модель является частью объектной модели VS, которая доступна непосредственно в надстройках   -  person Neal Bailey    schedule 19.10.2012


Ответы (1)


Ну это оказалось очень просто. Оказывается, объектная модель Macro является частью модели VS, поэтому проблем нет.

http://msdn.microsoft.com/en-us/library/za2b25t3%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/ms228776.aspx

Я должен был знать, что Microsoft не оставила бы нас, разработчиков, зависящих от макросов, вот так!

person Neal Bailey    schedule 19.10.2012
comment
Как начать писать макросы в vs2012? Ссылки или подобное? - person LosManos; 17.12.2012
comment
@LosManos Ознакомьтесь с stackoverflow.com /вопросы/12027485/ - person Daemin; 28.06.2013