Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OpenOffice, how do I check if my XComponentContext has been closed?

I have a small application that generates three different template documents in OOo Writer. When one of the three "generate" buttons is clicked, this is part of the code that is executed (in C#):

// Connect to OOo
if (componentContext == null)
    componentContext = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory multiServiceFactory =
    (XMultiServiceFactory) componentContext.getServiceManager();
XComponentLoader loader = (XComponentLoader)
    multiServiceFactory.createInstance
        ("com.sun.star.frame.Desktop");

// Initialize class members document, text, and cursor
document = (XTextDocument) loader.loadComponentFromURL
    ("private:factory/swriter", "_blank", 0,
     new PropertyValue[0]);
text = document.getText();
cursor = text.createTextCursor();

The following steps cause a crash:

  1. The user generates a document.
  2. The user closes the document (closing OOo).
  3. The user tries to generate another document.

This exception is thrown:

unoidl.com.sun.star.lang.DisposedException: URP-Bridge: disposed(tid=4) Unexpected connection closure

How do I check to make sure the connection is still open before trying to generate another chart? And how do I reconnect if it has been closed?

Edit: More specifically, this is the complete error message:

Marshaling clicked signal
Exception in Gtk# callback delegate
  Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> unoidl.com.sun.star.lang.DisposedException: URP-Bridge: disposed(tid=4) Unexpected connection closure
  at com.sun.star.bridges.mono_uno.UnoInterfaceProxy.ConstructReturnMessage (Any result, System.Object[] args, uno.Typelib.InterfaceMethodTypeDescription* methodTD, IMethodCallMessage callmsg, Any exception) [0x00000] 
  at com.sun.star.bridges.mono_uno.UnoInterfaceProxy.Invoke (IMessage request) [0x00000] 
  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x00000] 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] 
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x00000] 
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00000] 
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] 
  at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00000] 
  at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x00000] 
  at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00000] 
   at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal)
   at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
   at Gtk.Application.gtk_main()
   at Gtk.Application.Run()
   at TestDrive.MainClass.Main(System.String[] args) in /home/matthew/Dropbox/OpenSBS-mono/TestDrive/Main.cs:line 28

The application was terminated by a signal: SIGHUP

If I get rid of the line if (componentContext == null) (i.e., always try to connect, even when we have already connected), I get a stacktrace accompanied by this message:

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================
  • Discussion on OOoForum.org
like image 889
Matthew Avatar asked Oct 15 '22 12:10

Matthew


2 Answers

This is just a guess. You could use XComponent.addEventListener and listen for the disposing event.

eg:

class App :  XEventListener
{
    private XComponentLoader m_loader;

    private XComponentLoader Loader
    {
        get
        {
            if (m_loader == null)
            {
                m_loader = (XComponentLoader)multiServiceFactory.createInstance("com.sun.star.frame.Desktop");
                XComponent comp = (XComponent)m_loader;
                comp.addEventListener(this);
            }
            return m_loader;
        }
    }

    private void disposing(EventObject Source)
    {
        m_loader = null;
    }
}
like image 57
Foole Avatar answered Oct 21 '22 04:10

Foole


I have discovered that this bug doesn't occur if the OpenOffice Quickstarter application is running (located at C:\Program Files (x86)\OpenOffice.org 3\program\quickstart.exe). quickstart.exe appears to call soffice.exe, and it will remaining running even after the user closes the last document window.

If quickstart.exe is missing, it can be installed via the OpenOffice setup program. Your application can make sure that soffice.exe is running by launchingquickstart.exe using the System.Diagnostics.Process.Start(). It won't duplicate the process if it is already running.

like image 39
Dan Stevens Avatar answered Oct 21 '22 02:10

Dan Stevens