2009-11-08 8 views
4

J'ai une petite application qui génère trois documents modèles différents dans OOo Writer. Lorsque l'un des trois « générer » des boutons est cliqué, cela fait partie du code qui est exécuté (en C#):Dans OpenOffice, comment vérifier si mon XComponentContext a été fermé?

// 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(); 

Les étapes suivantes provoquent un accident:

  1. L'utilisateur génère un document.
  2. L'utilisateur ferme le document (fermeture OOo).
  3. L'utilisateur essaie de générer un autre document.

Cette exception est levée:

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

Comment puis-je vérifier pour vous assurer que la connexion est toujours ouverte avant d'essayer de générer un autre graphique? Et comment puis-je me reconnecter s'il a été fermé?

Edit: Plus précisément, c'est le message d'erreur complète:

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 

Si je me débarrasser de la ligne if (componentContext == null) (c.-à toujours essayer de se connecter, même si nous avons déjà fait), je reçois un STACKTRACE accompagné de ce 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. 
================================================================= 
+0

J'ai le même problème. Avez-vous réussi à trouver une solution ou une solution de contournement par hasard? –

+0

@Doomy: Ma mémoire est un peu brumeuse, mais je crois que cette solution (laide) a fonctionné: j'ai créé un exécutable séparé qui lance OOo et interagit avec lui si nécessaire. Chaque fois que j'ai besoin d'interagir avec OOo, j'appelle cet exécutable d'aide de mon programme principal (en lui passant tous les arguments dont il a besoin). Parce que je n'ouvre jamais OOo une fois dans une invocation de l'exécutable helper, je peux éviter ce bug. –

+0

Merci pour la réponse. Ma solution de contournement consistait à installer la fonction OpenOffice Quickstarter et à m'assurer qu'elle était en cours d'exécution avant d'exécuter mon application. –

Répondre

2

Ceci est juste une supposition. Vous pouvez utiliser XComponent.addEventListener et écouter l'événement disposing.

par exemple:

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

Cela ne semble pas fonctionner. Je reçois mon erreur sur la ligne lors de l'obtention de la multiServiceFactory, pas lors de l'obtention du chargeur, mais modifier votre code pour ajuster cela ne semble pas aider. Une chose intéressante est que "disposer" ne semble pas être appelé pour componentContext, multiServiceFactory ou loader lorsque je ferme OOo. Seuls les appels de documents disposant (et essayant de se reconnecter encore me donne l'erreur). Peut-être que ce qui se passe est que la connexion n'est jamais complètement fermée, et c'est ce qui fait que bootstrap donne l'erreur. Des idées? –

2

J'ai découvert que ce bug ne se produit pas si l'application OpenOffice fonctionne Quickstarter (situé à C:\Program Files (x86)\OpenOffice.org 3\program\quickstart.exe). quickstart.exe semble appeler soffice.exe, et il continuera à fonctionner même après que l'utilisateur ferme la dernière fenêtre de document.

S'il manque quickstart.exe, il peut être installé via le programme d'installation OpenOffice. Votre application peut s'assurer que soffice.exe est en cours d'exécution en lançant quickstart.exe en utilisant le System.Diagnostics.Process.Start(). Il ne dupliquera pas le processus s'il est déjà en cours d'exécution.

Questions connexes