Макросы Visual Studio в 64-разрядной системе завершаются с ошибкой COM - PullRequest
0 голосов
/ 04 декабря 2009

Я занимаюсь разработкой javascript и нашел классный макрос для регионализации моего кода («Использование директивы #region с файлами JavaScript в Visual Studio»). Я использовал это на своей 32-битной коробке, и это сработало в первый раз. (Visual Studio 2008 SP1, Win7)

Для удобства использования макрос выглядит так:

Option Strict Off
Option Explicit Off

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Imports System.Collections

Public Module JsMacros

    Sub OutlineRegions()
        Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection

        Const REGION_START As String = "//#region"
        Const REGION_END As String = "//#endregion"

        DTE.ExecuteCommand("Edit.StopOutlining")

        selection.SelectAll()
        Dim text As String = selection.Text
        selection.StartOfDocument(True)

        Dim startIndex As Integer
        Dim endIndex As Integer
        Dim lastIndex As Integer = 0
        Dim startRegions As Stack = New Stack()

        Do
            startIndex = text.IndexOf(REGION_START, lastIndex)
            endIndex = text.IndexOf(REGION_END, lastIndex)

            If startIndex = -1 AndAlso endIndex = -1 Then
                Exit Do
            End If

            If startIndex <> -1 AndAlso startIndex < endIndex Then
                startRegions.Push(startIndex)
                lastIndex = startIndex + 1
            Else
                ' Outline region ...
                selection.MoveToLineAndOffset(CalcLineNumber(text, CInt(startRegions.Pop())), text.Length)
                selection.MoveToLineAndOffset(CalcLineNumber(text, endIndex) + 1, 1, True)
                selection.OutlineSection()

                lastIndex = endIndex + 1
            End If
        Loop

        selection.StartOfDocument()
    End Sub

    Private Function CalcLineNumber(ByVal text As String, ByVal index As Integer)
        Dim lineNumber As Integer = 1
        Dim i As Integer = 0

        While i < index
            If text.Chars(i) = vbCr Then
                lineNumber += 1
                i += 1
            End If

            i += 1
        End While

        Return lineNumber
    End Function

End Module

Затем я попытался использовать один и тот же макрос на двух отдельных 64-разрядных компьютерах (Win7 x64), идентичных, кроме 64-разрядной версии ОС, и он не работает. Проходя через нее с помощью Visual Studio Macros IDE, в первый раз происходит сбой в строке DTE.ExecuteCommand ("Edit.StopOutlining") с ошибкой COM (ошибка HRESULT E_FAIL возвращена из вызова COM компонент).

Если я попытаюсь запустить его во второй раз, я смогу запустить его из редактора макросов без проблем, но не из Visual Studio с помощью команды «Выполнить макрос» проводника макросов.

Я просмотрел следующие статьи, но ничего полезного не нашел:

Я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2015

У меня была похожая проблема, и по каждой команде в _applicationObject я обнаружил, что команда существовала дважды (в моем случае это был Debug.SaveDumpAs) Один был доступен, а другой нет. Достаточно «к несчастью», я всегда получал неправильный, когда выполнял команду.

Вы должны получить guid и id команды, которую хотите, и, конечно, вы хотите, чтобы она была доступна. Вот пример на C #

        string guid ="";
        int ID = 0;
        string NAMEOFCOMMAND = "Edit.StopOutLining";

        try
        {
            foreach (Command command in _applicationObject.Commands)
            {                    
                if (command.Name == NAMEOFCOMMAND)
                {
                    if(command.IsAvailable)
                    {
                        guid = command.Guid;
                        ID = command.ID;
                    }
                }
            }
            //The ExecuteCommand method cannot be used to have the right guid and id. I believe though that there is a format you can use to use it anyway. In doubt: use the Raise command which is most likely the same with additional parameters which you can set to null if you don't need them
            ((DTE)_applicationObject).Commands.Raise(guid, ID, null, null);

Ура! :)

0 голосов
/ 25 апреля 2010

просто оберните строку

DTE.ExecuteCommand("Edit.StopOutlining")

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

Try

  DTE.ExecuteCommand("Edit.StopOutlining")

Catch ex As Exception

 End Try

и, сделав метод общедоступным, я затем выбрал инструменты, параметры, клавиатуру и назначил комбинацию клавиш Ctrl M, Ctrl O для макроса MyMacros.OutLineRegions, и он работает как мечта:)

Использование Windows 7 64-разрядная версия Visual Studio 2010 .. YMMV

...