locked
addin that shows WPF window is failing mysteriously RRS feed

  • Question

  • In the Exec method of my addin I new up a WPF window, then call ShowDialog on that window. In the WPF window I run code in the Loaded event. Problem is, the loaded event is never being called. Also the ShowDialog window quickly is overlayed by Visual Studio. Then when I bring the showdialog window to the foreground and click on its elements to do stuff, Visual Studio crashes.

    my questions:
      - when visual studio crashes like this, presumably because of an addin throwing an unhandled exception, how do I determine what happened?

    - what could be causing the ShowDialog from the Exec method of the addin to not trigger the Loaded event of the WPF window?

    The WPF window I am ShowDialog'ing on works fine from test when I run the code that the Exec method runs.

    thanks,

    	public void Exec(
       string commandName, vsCommandExecOption executeOption, ref object varIn, 
       ref object varOut, ref bool handled)
    		{
    			handled = false;
       if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
       {
    
        if (commandName == "AddinManager.Connect.AddinManager")
        {
         AddinManagerWpf.MainWindow mw = new AddinManagerWpf.MainWindow( ) ;
         mw.ShowDialog();
        }
    
        return;
       }
    		}
    
    --------------------------------
    
      public MainWindow()
      {
       InitializeComponent();
       this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
       this.Closed += new EventHandler(MainWindow_Closed);
    
    // this runs when the addin exec method runs ShowDialog.
       MessageBox.Show("MainWindow constructor");
      }
    
    
      private void MainWindow_Loaded(object sender, RoutedEventArgs e)
      {
    
     // this statement is never run. Don't know why.
       MessageBox.Show("MainWindow_Loaded");
    
      }
    
    
    

     

     

    Monday, December 6, 2010 12:39 AM

Answers

  • 2008 or 2010?  As for debugging the crash, attach a debugger to Visual Studio, either Visual Studio itself or an external one like WinDbg.  Set it to debug in mixed mode (native + managed), turn of the 'Enable just my code' option and point it at the Microsoft public symbol servers in the debug dialog.

    Ryan

    • Marked as answer by Steve Richter Monday, December 6, 2010 3:56 PM
    Monday, December 6, 2010 2:31 AM

All replies

  • 2008 or 2010?  As for debugging the crash, attach a debugger to Visual Studio, either Visual Studio itself or an external one like WinDbg.  Set it to debug in mixed mode (native + managed), turn of the 'Enable just my code' option and point it at the Microsoft public symbol servers in the debug dialog.

    Ryan

    • Marked as answer by Steve Richter Monday, December 6, 2010 3:56 PM
    Monday, December 6, 2010 2:31 AM
  • 2008 or 2010?

     

    visual studio  2010.

     

    Monday, December 6, 2010 12:36 PM
  • As for debugging the crash, attach a debugger to Visual Studio ...

     

    ok, got the debugger working. My addin was crashing VS2010 because of a null reference in my code. The loaded event handler is not being called. Objects the addin expects to be created are null, hence the exception.

    I am coding for the possibility the loaded event is not called.  Would like to know why that would happen. In all other settings when I ShowDialog a WPF window, the Loaded event is fired. Why would this event not occur when ShowDialog a WPF window from a VS2010 addin?

    thanks,

     

    Monday, December 6, 2010 1:43 PM
  • >Also the ShowDialog window quickly is overlayed by Visual Studio.

    There is far more involved in making VS go modal than WPF could possibly know about / accomplish.  VS is not a typical WPF application in that WPF is NOT running the main message loop, VS is.  Therefore things that may work just fine in a normal WPF app (like ShowDialog making the application modal) will NOT work in VS.  There is a helper type in Shell.10.0, DialogWindow which derives from WPF's Window and has a ShowModal method that can be used to accomplish correct modal showing inside of VS.

    >Would like to know why that would happen. In all other settings when I ShowDialog a WPF window, the Loaded event is fired. Why would this event not occur when ShowDialog a WPF window from a VS2010 addin?

    I wouldn't be able to tell without further debugging.  Running a 'normal' WPF application on VS 2010 and putting a breakpoint into my windows Loaded event shows it firing from the rendering pass WPF makes.  This (the rendering pass) is certainly still being made or else there would be no visible UI for your window.  It is unclear how it decides it has to raise the Loaded event (obviously the presence of listeners is one factor, but it also needs to ensure it doesn't call it multiple times, though it actually says on MSDN that may happen in some scenarios).  It could be an artifact of WPF not running the main message loop, or it could be that the ShowDialog call, which is setting up a nested message loop, causes issues. 

    I would try a repro on my 2010 instance but it isn't cooperating with me at the moment and it won't create AddIn projects :(  I will try later today after I have installed a new drop of Visual Studio, since I am working with internal builds (post 2010 release) sometimes I get surprises like this :)

    Ryan

    Monday, December 6, 2010 6:19 PM
  • >Also the ShowDialog window quickly is overlayed by Visual Studio.

    There is far more involved in making VS go modal than WPF could possibly know about / accomplish.  VS is not a typical WPF application in that WPF is NOT running the main message loop, VS is.  Therefore things that may work just fine in a normal WPF app (like ShowDialog making the application modal) will NOT work in VS.  There is a helper type in Shell.10.0, DialogWindow which derives from WPF's Window and has a ShowModal method that can be used to accomplish correct modal showing inside of VS.

     I really appreciate the help.  My code is throwing an exception in the Loaded event handler itself. When I comment out that code the WPF windows shows as it should.  But when the error does occur in Loaded there seems to be all sorts of odd effects. The debugger does not seem to break in the loaded event code, even before the error. That makes no sense, but believe me, it has been very confusing.   Thanks for the link to the helper type. 

     

    Monday, December 6, 2010 6:41 PM
  • Yes, exceptions thrown in the middle of layout (which is where the Loaded event firing happens) cause WPF to go 'very wacky'.  Specifically there are normally lots and lots of frames on the stack between the layout 'root' (which is guarded against exceptions) and the code that throws.  The problem is lots and lots of managed code in general is NOT exception safe in the sense that it is VERY easy to get objects that are in the middle of some internal state transition when an exception occurs and they end up in a half changed state since when the exception tore through the frame they didn't roll-back the already made state updates, but they also didn't complete the rest of the ones they needed to do.

    This isn't bad coding per-se, since most people expect exceptions to be exceptional and assume that the application will probably be crashing/terminating very soon.  Of course some people (and frameworks) think that application stability means catch(Exception) { } and then log/ignore and continue running, which means your objects all all in a wacky state.  VS generally tends to prefer crashing in that it leads to immediate indication that something is very wrong so someone can investigate / fix that something, also it minimizes getting into these wacky states and then getting unsolveable bugs filed like 'after I do 'some stuff' (there is normally no clear repro as you can't tell at what exact point things went wrong) I don't see any errors but VS starts acting very strangely, the UI doesn't look right, it stops reacting to mouse input in some areas, it corrupts my documents, etc...')

    WPF is VERY sensitive to exceptions thrown during layout and basically is NOT hardened against getting into these kind of wacky states.  Once in this state it is pointless to try and figure out why things 'don't work' because who knows how many internal invariants are now violated because of the exception tearing through the frames while they were in the middle of updating their state.

    Ryan

    Monday, December 6, 2010 7:13 PM