2010-07-12 22 views
4

J'ai un add-in Visual Studio 2008 qui quand j'appuie sur un certain raccourci-clavier, il ouvre un fichier spécifique (différent basé sur le contexte du raccourci-clavier), puis recherche ce fichier pour une chaîne spécifique (encore dépendante du contexte). La plupart du temps, cela fonctionne parfaitement, mais parfois, si le fichier est trop grand, la recherche échouera.Comment bloquer sur un OpenFile dans un add-in Visual Studio

Voici un extrait de code:

Window xmlWindow = Commands.Application.ItemOperations.OpenFile(objectFilename, EnvDTE.Constants.vsViewKindPrimary); 
Find find = xmlWindow.Document.DTE.Find; 
find.Action = vsFindAction.vsFindActionFind; 
find.FindWhat = String.Format("Name=\"{0}\"", objectLocalName); 
if (find.Execute() == vsFindResult.vsFindResultFound) { 
    MessageBox.Show("Found!"); 
} 



1. Y at-il un moyen de faire fonctionner toujours (par exemple en bloquant le OpenFile)? 2. Sur une note moins importante, existe-t-il un moyen de faire une telle recherche sans que les résultats ne se retrouvent dans le volet Résultats de la recherche (cela entraîne l'effacement de mes anciens résultats par cette recherche qui n'est utilisée que pour déplacez le curseur sur cette partie du fichier)?


+0

Lorsque vous dites "la recherche échoue" ... Cela signifie qu'il ne renvoie pas le résultat attendu, ou il provoque une erreur msg? –

+0

Il ne renvoie pas le résultat attendu car la recherche s'exécute réellement sur l'onglet actuellement ouvert, pas celui qu'il essaie d'ouvrir. –

Répondre

11

Si OpenFile se comporte de manière asynchrone, je vous suggère de considérer changer la logique de compter sur un événement différent, celui qui repose sur le document en cours d'activation.

Par exemple, avez-vous essayé de déclencher OpenFile avec votre touche de raccourci, puis de mettre en file d'attente la recherche afin qu'elle soit gérée plus tard par un événement VS? (Le code ci-dessous provient d'un addin Visual Studio 2010, mais je crois que les événements sont les mêmes.)

// assurez-vous que ce sont des variables de classe, sinon elles risquent d'être incorrectement GC'd et de rompre l'interaction COM WindowEvents privés _winEvents = null; private DTE2 _applicationObject;

dans la connexion:

_events = _applicationObject.Events; 
_winEvents = _events.get_WindowEvents(); 

_winEvents.WindowActivated += new _dispWindowEvents_WindowActivatedEventHandler(WindowActivated); 

Ensuite, vous mettriez un code dans le WindowActivated:

void WindowActivated(Window GotFocus, Window LostFocus) 
     { 
      Document gotFocusDoc = GotFocus.Document; 
      if (gotFocusDoc != null) 
      { 
       string fileExt = Path.GetExtension(gotFocusDoc.Name); 

Là, vous voulez regarder le fichier que vous vouliez scanner (vous Peut-être besoin de garder une liste, etc.).

Pour le deuxième numéro, vous pouvez simplement parcourir le document vous-même une fois que vous avez accédé comme je l'ai suggéré ci-dessus.

+0

Merci :) Profitez de la générosité. –

0

Je pense que la méthode DTE.ItemOperations.OpenFile() est synchrone. Essayez d'utiliser un extrait de code suivant pour VS2008.

using EnvDTE; 

Window win = _applicationObject.ItemOperations.OpenFile(@"path-to-xml-file", Constants.vsViewKindPrimary); 
TextDocument doc = win.Document.Object("TextDocument") as TextDocument; 
if (doc != null) 
{ 
    EditPoint searchStart = doc.StartPoint.CreateEditPoint(); 
    EditPoint endOfFoundText = null; 
    TextRanges ranges = null; 

    bool result = searchStart.FindPattern("Text-to-search", (int)vsFindOptions.vsFindOptionsNone, ref endOfFoundText, ref ranges); 
    if (result) 
    { 
     // Result is bounded by searchStart and endOfFoundText points. 
     System.Windows.Forms.MessageBox.Show("BINGO! Found at " + searchStart.Line.ToString()); 
    } 
} 

Si vous avez un problème avec la capture d'une fenêtre ouverte, je suggère de vérifier un code source de mon extension WordLight: il y a une classe WindowWatcher, qui suit la création de vues de texte.