2009-12-04 2 views
0

Je suis en train de faire du développement javascript et j'ai trouvé une macro sympa pour classer mon code ("Utilisation de la directive #region avec les fichiers JavaScript dans Visual Studio"). J'ai utilisé ceci sur ma boîte de 32 bits, et cela a fonctionné la première fois. (Visual Studio 2008 SP1, Win7)Les macros Visual Studio sur 64 bits échouent avec l'erreur COM

Pour facile de référence de la macro est:

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 

J'ai ensuite essayé d'utiliser la même macro sur deux séparés machines 64 bits (Win7 x64), d'autres identiques que la 64 bits OS version et il ne fonctionne pas. En le parcourant avec l'IDE de Visual Studio Macros, il échoue la première fois sur la ligne DTE.ExecuteCommand ("Edit.StopOutlining") avec une erreur COM (Erreur HRESULT E_FAIL a été renvoyée à partir d'un appel à un composant COM). Si je tente de l'exécuter une deuxième fois, je peux le lancer à partir de l'éditeur de macros sans problème, mais pas depuis Visual Studio avec la commande macro exécuter macro.

J'ai examiné les articles suivants sans rien trouver utile:

Am I manque quelque chose de stupide?

+0

Trouvé également que la fenêtre de code doit également être focalisée. Si vous avez, par exemple, la fenêtre de sortie VS en focus, la macro ne fonctionnera pas ... pas de surprise mais elle jette l'exception. – Bruce

Répondre

0

juste envelopper la ligne

DTE.ExecuteCommand("Edit.StopOutlining") 

dans un bloc catch try et squelch l'exception - i avait un script pour faire exactement cela, mais celui que j'avais travail na pas - après avoir essayé le vôtre et changer la ligne ci-dessus pour

Try 

    DTE.ExecuteCommand("Edit.StopOutlining") 

Catch ex As Exception 

End Try 

et rendre public la méthode, je puis est allé outils, des options, clavier et attribué le combo clavier Ctrl M, Ctrl O aux MyMacros.OutLineRegions macro et il fonctionne comme un rêve devenu réalité :)

Utilisation de Windows 7 64 bits, Visual Studio 2010 .. YMMV

0

J'ai rencontré un problème similaire et j'ai découvert en examinant chaque commande de l'objet _applicationObject qu'une commande existait deux fois (dans mon cas c'était Debug.SaveDumpAs) L'un était disponible et pas l'autre. "Malheureusement" assez, j'ai toujours récupéré le mauvais quand j'ai exécuté la commande.

Vous devez récupérer le guid et l'identifiant de la commande que vous voulez et, bien sûr, vous voulez celui disponible. Voici un exemple en 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! :)

Questions connexes