locked
How to make DTE.ExecuteCommand("Edit.FindInFiles") wait for completion in VS2010? RRS feed

  • Question

  • I use a macro like this in Visual Studio 2003, and the postFind routine is not called until the "FindInFiles" completes. Not so in Visual Studio 2010. It seems the ExecuteCommand for "FindInFiles" returns immediately. How do I correct so that postFind is called after the find completes?

    Sub findindocument2()
            preFind()
            DTE.Find.SearchPath = "Current Document"
            DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResults2
            DTE.ExecuteCommand("Edit.FindInFiles")
            postFind()
        End Sub

    Friday, April 1, 2011 10:48 PM

Answers

  • As for the 'tell if a dialog is open', it isn't a dialog, it is a tool window, which is why it isn't blocking (from the sounds of it the dialog was likely modal in 2003 and thus the find command was blocking).

    Yes you can ask the shell to find a toolwindow and then query the frame to see if is open / sync an event to tell when it closes.  Look at IVsUIShell::FindToolWindow, then cast the IVsWindowFrame (if it finds one, meaning the find dialog is open) to IVsWindowFrame2, call Advise and wait for an OnShow callback with a value of FRAMESHOW_WinHidden.

    Ryan

    • Marked as answer by Victor_Chen Monday, April 11, 2011 9:50 AM
    Monday, April 4, 2011 7:48 PM

All replies

  • It looks to me like ExecuteCommand is synchronous in 2010, according to the source code, though FindInFiles is highly likely to be asynchronous itself. 2003 was far before my time but I believe FindInFiles has been async for a long time as doing synchronous, blocking disk I/O on the UI thread is poor form.

    Can you try casting DTE.Find to Find2 and setting WaitForFindToComplete to true before calling ExecuteCommand (and likely setting it back to false after the ExecuteCommand, so as not to leave find in that state)?

    Ryan

    Saturday, April 2, 2011 12:10 AM
  • Ryan,

    Visual Studio 2003 does not return from the "DTE.ExecuteCommand("Edit.FindInFiles")" statement until the "Find in Files" dialog is closed.

    Visual Studio 2010 returns while the "Find in Files" dialog is open.

    I think this happens long before I click the "Find" button on the "Find in Files" dialog, so I don't see how setting WaitForFindToComplete would help.

    Can I tell if a dialog is open in my macro? If so, I could loop until the dialog is closed, then run my postFind() routine.

    Thanks for the help,

    Frank

    Monday, April 4, 2011 2:53 PM
  • ExecuteCommand itself simply fires off the command. Whether the command itself completes synchronously is up to the command handler. In 2003 I assume Find in Files was synchronous, so once we fired it off the handler took over and did all work before returning. Was the Find in Files window modal in 2003? The current code is asynchronous and the dialog itself is not modal, so as soon as it has popped the dialog it is 'done' executing the command from the perspective of the handler. The WaitForFindToComplete looked like it could make the handler synchronous, but I am not an expert in this command which is why I just suggested it instead of stating it would work :)

    Ryan

    Monday, April 4, 2011 3:53 PM
  • As for the 'tell if a dialog is open', it isn't a dialog, it is a tool window, which is why it isn't blocking (from the sounds of it the dialog was likely modal in 2003 and thus the find command was blocking).

    Yes you can ask the shell to find a toolwindow and then query the frame to see if is open / sync an event to tell when it closes.  Look at IVsUIShell::FindToolWindow, then cast the IVsWindowFrame (if it finds one, meaning the find dialog is open) to IVsWindowFrame2, call Advise and wait for an OnShow callback with a value of FRAMESHOW_WinHidden.

    Ryan

    • Marked as answer by Victor_Chen Monday, April 11, 2011 9:50 AM
    Monday, April 4, 2011 7:48 PM