在OpenOffice中,如何检查我的XComponentContext是否已关闭?

时间:2009-11-08 19:44:36

标签: c# openoffice.org openoffice-writer uno

我有一个小应用程序,可以在OOo Writer中生成三个不同的模板文档。当单击三个“生成”按钮中的一个时,这是执行的代码的一部分(在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();

以下步骤导致崩溃:

  1. 用户生成文档。
  2. 用户关闭文档(关闭OOo)。
  3. 用户尝试生成另一个文档。
  4. 抛出此异常:

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

    在尝试生成另一个图表之前,如何检查以确保连接仍处于打开状态?如果它已关闭,我该如何重新连接?

    编辑:更具体地说,这是完整的错误消息:

    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 (componentContext == null)(即,即使我们已经连接,也总是尝试连接),我会得到一个伴随此消息的堆栈跟踪:

    =================================================================
    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.
    =================================================================
    

2 个答案:

答案 0 :(得分:2)

这只是猜测。您可以使用XComponent.addEventListener并收听disposing事件。

例如:

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;
    }
}

答案 1 :(得分:2)

我发现如果OpenOffice Quickstarter应用程序正在运行(位于C:\Program Files (x86)\OpenOffice.org 3\program\quickstart.exe),则不会发生此错误。 quickstart.exe似乎会调用soffice.exe,即使用户关闭了最后一个文档窗口,它也会继续运行。

如果缺少quickstart.exe,可以通过OpenOffice安装程序安装它。您的应用可以通过使用soffice.exe启动quickstart.exe来确保System.Diagnostics.Process.Start()正在运行。如果进程已在运行,它将不会复制该进程。