none
My Visual Studio Addin causes "operation is blocking user input" dialog on exit RRS feed

  • Question

  • Hi

    I am writing an Addin that needs to show a dialog window.  The dialog window is a complex workflow window which displays steps of a complex process.   Workflow is performed on worker threads and state is communicated back to the view via a WPF view model.

    I'd like to have this dialog modal.  If I have it modal, however, it often causes Visual Studio where it's running to get into a strange state. In this state I cannot use backspace or a few other keys in the text editor, and if I shutdown visual studio, I am presented with a dialog which says:

    ---------------------------

    Microsoft Visual Studio
    ---------------------------
    Microsoft Visual Studio has detected that an operation is blocking user input.  This can be caused by an active modal dialog or a task that needs to block user interaction.  Would you like to shut down anyway?
    ---------------------------
    Yes   No   
    ---------------------------


    How can I troubleshoot this? What are the rules here?  It's definitely my add-in that's causing this, but I am unsure how or why.  Any help?

    Monday, July 16, 2012 6:42 PM

Answers

  • No, it is from IVsUIShell, which is a shell interface, it is not related to DTE. You retrieve it by using your service provider to QueryService for SVsUIShell and casting it to IVsUIShell.

    Ryan

    Monday, July 16, 2012 11:12 PM
    Moderator

All replies

  • The only general rule around modal dialogs in VS is that you *must* call IVsUIShell::EnableModeless(FALSE) before showing one (to put the shell into a modal state) and then IVsUIShell::EnableModeless(TRUE) after your dialog exits to exit the modal state.  There are also parenting issues that can be dealt with via IVsUIShell::GetDialogOwnerHWND.  Though this can all be made much easier if you just derive your dialog window from DialogWindow and call ShowModal to display it. DialogWindow will take care of both the parenting to the proper parent window as well as the calls to EnableModeless.

    Ryan

    Monday, July 16, 2012 8:30 PM
    Moderator
  • Thanks, Ryan.

    Is this  IVsUIShell::EnableModeless() method accessible from EnvDTE?  

    Monday, July 16, 2012 10:29 PM
  • No, it is from IVsUIShell, which is a shell interface, it is not related to DTE. You retrieve it by using your service provider to QueryService for SVsUIShell and casting it to IVsUIShell.

    Ryan

    Monday, July 16, 2012 11:12 PM
    Moderator
  • Found this helpful link on how to do this.

    http://msdn.microsoft.com/en-us/library/bb166423.aspx

    I could not find a way to pick additional reference from the "Add Reference dialog" so I modified the my csproj file, adding these lines:


        <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
        <Reference Include="Microsoft.VisualStudio.OlE.Interop" />

    Afterwards everything worked

                var sp = Context.Application as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
                Guid SID = typeof(SVsUIShell).GUID;
                Guid IID = typeof(IVsUIShell).GUID;
                IntPtr ifacePtr;
                sp.QueryService(ref SID, ref IID, out ifacePtr);
                UIShell = (IVsUIShell)Marshal.GetObjectForIUnknown(ifacePtr);


    Tuesday, July 17, 2012 12:18 PM
  • Using DialogWindow is probably better, but do make sure you're calling Marshal.Release on iFacePtr above so you aren't leaking it.

    Ryan

    Tuesday, July 17, 2012 2:42 PM
    Moderator
  • Sorry, but what do you mean?  Are you saying there's a better way of getting to the IVsUIShell?

    Thanks for your help.  Works well

    Wednesday, July 18, 2012 3:16 AM
  • Using DialogWindow as your window's base class means you don't have to do anything with IVsUIShell at all, as DialogWindow does all that. You just have to call ShowModal to display the dialog, instead of the WPF ShowDialog method.

    Ryan

    Wednesday, July 18, 2012 4:05 AM
    Moderator
  • That works great with the WPF windows

    How to make this possible for Forms?

    Say, I have been using ShowDialog from "System.Windows.Forms.Form"...

    Should I use GetDialogOwnerHWND and EnableModeless separately in the Forms?

    Thanks,

    Deena


    Friday, March 14, 2014 7:28 AM
  • I don't see why the approach has to change.  There is nothing specific to wpf in the solution presented in the thread, or at least I don't think there is.
    Friday, March 14, 2014 9:40 AM
  • I don't see why the approach has to change.  There is nothing specific to wpf in the solution presented in the thread, or at least I don't think there is.

    That make sense!! But then looking for any clean way to do it

    Say for WPF we can derive the window using DialogWindow and call ShowModal will fix it (instead of enable and disable modeless calls)...Would like to if there are any other clean for Forms (as DialogWindow cannot be used for forms)

    Thanks,

    Deena

    Friday, March 14, 2014 10:50 AM
  • I see what you mean.

    Looks like you are going to have to bite the bullet and reference WPF specific libraries and derive from this WPF specific dialog. It's what Visual Studio wants you to do by providing you with a WPF-based base class.

    Having both, WPF and Winforms in a single project will still work.

    Friday, March 14, 2014 10:57 AM
  • Does using "IUIService" resolve this issue for Windows Forms?
    Monday, March 17, 2014 8:24 AM