Visual Studio Macros on 64 bit fail with COM error
I'm doing some javascript development and found a cool macro to region my code ("Using #region Directive With JavaScript Files in Visual Studio"). I used this on my 32 bit box, and it worked first time. (Visual Studio 2008 SP1, Win7)
For easy of reference the macro is:
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
I then t开发者_StackOverflow中文版ried to use the same macro on two separate 64 bit machines (Win7 x64), identical other than the 64 bit OS version and it fails to work. Stepping through it with the Visual Studio Macros IDE, it fails the first time on the DTE.ExecuteCommand("Edit.StopOutlining") line with a COM error (Error HRESULT E_FAIL has been returned from a call to a COM component).
If I attempt to run it a second time, I can run it from the Macro Editor with no issue, but not from within Visual Studio with the macro explorer 'run macro' command.
I have reviewed the following articles without finding anything helpful:
- Stackoverflow: Visual Studio 2008 macro only works from the Macro IDE, not the Macro Explorer
- Recorded macro does not run; Failing on DTE.ExecuteCommand
Am I missing something dumb?
just wrap the line
DTE.ExecuteCommand("Edit.StopOutlining")
in a try catch block and squelch the exception - i had a script for doing exactly this but the one i had didnt work - after trying yours and changing the above line to
Try
DTE.ExecuteCommand("Edit.StopOutlining")
Catch ex As Exception
End Try
and making the method public, i then went tools, options, keyboard and assigned the keyboard combo Ctrl M, Ctrl O to the macro MyMacros.OutLineRegions and it works like a dream come true :)
Using Windows 7 64-bit, Visual Studio 2010.. YMMV
I had a similar problem and found out by looking at every commands in the _applicationObject that a command existed twice (in my case it was Debug.SaveDumpAs) One was available and not the other. "Unluckily" enough, I always retrieved the wrong one when I executed the command.
You have to retrieve the guid and the id of the command you want and of course, you want the one available. Here's an example in 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);
Cheers ! :)
精彩评论