OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Problem with terminating soffice.exe
Goto page 1, 2  Next
 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
heffalump
General User
General User


Joined: 15 Jan 2004
Posts: 21
Location: Germany, Pliezhausen

PostPosted: Mon Jan 19, 2004 1:17 am    Post subject: Problem with terminating soffice.exe Reply with quote

Within a VB ActiveX-DLL I'm controlling OO via OLE-Automation.
In order to quit the application (soffice.exe) - that means remove it from memory - I use the OO-API function terminate() of my desktop-object
Code:

Set objServiceManager = CreateObject("com.sun.star.ServiceManager")
'Create the Desktop
Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")
objDesktop.Terminate

If I do so the (WIN32-) soffice.exe gives an ugly application error message (it's not a VB error message) regarding an unhandled exception (something like "reading from memory at 0x00000038 was not possible").
I assume that my simply terminating the desktop ist too "rough". Does anybody know how to shutdown the OO-services the right way?
Before that I have closed all my open documents
Code:
Dim oComponents As Object
Dim oComponentWalker As Object
Dim oDoc As Object

Set oComponents = objDesktop.getComponents()
Set oComponentWalker = oComponents.createEnumeration()

'alle Dokumente schließen ohne speichern
Do While oComponentWalker.hasMoreElements()
    Set oDoc = oComponentWalker.nextElement()
    oDoc.dispose
Loop


Last edited by heffalump on Mon Jan 19, 2004 11:36 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Jan 19, 2004 10:08 am    Post subject: Reply with quote

This was discussed in the past here...
http://www.oooforum.org/forum/viewtopic.php?t=3763

I seem to remember being able to successfully terminating OOo by calling terminate() on the desktop.

Doesn't seem to work in current version though?

In your loop you call "dispose()" on each document. If you are using OOo 1.1, there is a new com.something.....XClosable interface available. From this you could call like...

oDoc.close( True )

instead of calling dispose() which is much lower level.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Jan 19, 2004 11:31 am    Post subject: Reply with quote

Here is more information about closing a document...

http://www.oooforum.org/forum/viewtopic.php?t=3898
http://www.oooforum.org/forum/viewtopic.php?t=3620



Past discussions on how to terminate OOo.....

http://www.oooforum.org/forum/viewtopic.php?t=2888
http://www.oooforum.org/forum/viewtopic.php?t=3763
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
heffalump
General User
General User


Joined: 15 Jan 2004
Posts: 21
Location: Germany, Pliezhausen

PostPosted: Mon Jan 19, 2004 11:33 pm    Post subject: Reply with quote

If I use the close() method in my loop (I'm using OOo 1.1.0)
Code:
Dim oComponents As Object
Dim oComponentWalker As Object
Dim oDoc As Object

Set oComponents = objDesktop.getComponents()
Set oComponentWalker = oComponents.createEnumeration()

'alle Dokument schließen ohne speichern
Do While oComponentWalker.hasMoreElements()
    Set oDoc = oComponentWalker.nextElement()
    oDoc.Close true
Loop

I get an runtime error "method does not exist"
The close() method only works if I apply it on my document object "objDocument"
Code:
Set objDocument = objDesktop.loadComponentFromURL(url, "_blank", 0, args)
objDocument.Close true
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Tue Jan 20, 2004 9:39 am    Post subject: Reply with quote

kenanja wrote:
I get an runtime error "method does not exist"
The close() method only works if I apply it on my document object "objDocument"


There are several different objects here. The model, the controller and the frame. I believe that your loop walking through the enumeration of components is getting the frame. (I could be wrong.)

Try getting the model by calling getModel() on it.
Code:
Set oComponents = objDesktop.getComponents()
Set oComponentWalker = oComponents.createEnumeration()

'alle Dokument schließen ohne speichern
Do While oComponentWalker.hasMoreElements()
    Set oDocFrame = oComponentWalker.nextElement()
    Set oDocModel = oDocFrame.getModel()
    oDocModel.Close true
Loop

(I sure hope that works!)

The call to loadComponentFromURL() always returns the model. From the model you can call getController() or getFrame(). See this post for more details....
http://www.oooforum.org/forum/viewtopic.php?t=5057

I still do not know if you can terminate the office application.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
heffalump
General User
General User


Joined: 15 Jan 2004
Posts: 21
Location: Germany, Pliezhausen

PostPosted: Wed Jan 21, 2004 12:49 am    Post subject: Reply with quote

Accessing the getModel() method with this code is not possible in VB (runtime error "method unknown" occurs):
Code:
Public Sub AppQuit()

Dim oComponents As Object
Dim oComponentWalker As Object
Dim oDocFrame As Object
Dim oDocModel As Object

Set oComponents = objDesktop.getComponents()
Set oComponentWalker = oComponents.createEnumeration()

'alle Dokumente schließen ohne speichern
Do While oComponentWalker.hasMoreElements()
    Set oDocFrame = oComponentWalker.nextElement()
    Set oDocModel = oDocFrame.getModel()
    oDocModel.Close True
Loop

'kill soffice.exe and remove it from memory
objDesktop.Terminate

The Terminate() method only works if I do not execute the document-close-loop above and - that's amazing - if I have more than one document opened. But before the app's quitting I have to answer the File-Save-dialog. With only one opened document the ugly error thing occurs (see first post). The very same thing happens if I close the documents (opened by OLE automation) "by hand" (e.g. File-->Exit). Two or more documents no problem, only one it crashes.
Any ideas about that?
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Jan 21, 2004 8:46 am    Post subject: Reply with quote

See this message I wrote in the past....
http://www.oooforum.org/forum/viewtopic.php?p=14057#14057

Notice that I am using a similar technique of getting all components from the desktop. OOo Basic has a convenient variable StarDesktop which contains the desktop object.

I call getComponents() on it. Just as you do.

I then call createEnumaration() to create an enumeration of all open components. Just as you do.

On the enumeration, I then have a While loop, calling hasMoreElements() and nextElement(). Just as you do.

Then, you'll notice that I test the component to see if it supports the interface XModel. So apparently the "components", at least some of them, are directly the document model objects. The Developer's Guide does say somewhere that components do not have to support the OfficeDocument service (and thus do not need to be a document model).

I wasn't sure. But now I can see I steered you wrong. You do not need to call getModel(). You may already have a document model in hand. The real test is if it supports the XClosable interface. (See above messages about closing documents.) If XClosable is supported, it is better to call close( True ). If XClosable is not supported, then you probably have to call dispose().

You'll notice that I'm using an OOo Basic function called HasUnoInterfaces(). This function lets you test any object to see if it supports a particular interface. I have developed a similar function that can be implemented in any language, including VB. See this...
http://www.oooforum.org/forum/viewtopic.php?t=3758

So, you could write a HasUnoInterfaces() type of function.
You could then test each component to see if it is a XModel, and if it supports XClosable.
But at this point, maybe it is just plain easier to unconditionally call dispose() on each component.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
MikeL
General User
General User


Joined: 12 Nov 2003
Posts: 41
Location: Little Rock, Arkansas, USA

PostPosted: Wed Jan 21, 2004 10:02 am    Post subject: Reply with quote

I'm incorporating the Officebean into my Java application on Windows XP.
I have been needing a way to kill the soffice.exe process as well for some time now.

I thumbed my way around previous posts and had no luck. But, based on info I gathered here and from the other posts, for the first time I saw the "soffice.exe" disappear from my Task Manager when I closed the Dialog window with my Officebean inside...Woo-hoo!

I've got to run at the moment, I will be back later to post my code.

Okay, I was gonna post my code this afternoon but I got sidetracked and now I've got to take care of some other things now. When I get home this evening, I will test my code again and then post my results. I'm still in euphoria that it is possible to kill the soffice.exe process and that it works....from Java!

Very Happy
Mike
Back to top
View user's profile Send private message Send e-mail Visit poster's website
heffalump
General User
General User


Joined: 15 Jan 2004
Posts: 21
Location: Germany, Pliezhausen

PostPosted: Wed Jan 21, 2004 10:57 pm    Post subject: Reply with quote

1. What would be the benefit of using the close() method instead of dispose()?
2. Is there in the OOo API a method provided to get the number of elements for the createEnumeration() method. Danny, in topic http://www.oooforum.org/forum/viewtopic.php?p=14057#14057 you used a loop with a counter so I assume there isn't such a method available
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Thu Jan 22, 2004 8:32 am    Post subject: Reply with quote

kenanja wrote:
1. What would be the benefit of using the close() method instead of dispose()?


The Developer's Guide somewhere under section 6.1.5 discusses closing documents. The new com.sun.star.util.XClosable interface is introduced.

Sometimes it is necessary to exercise more control over the closing process, therefore a new, optional interface com.sun.star.util.XCloseable has been introduced whichis supported in versions beyond 641


I'm not sure if using the close( True ) method of the XClosable interface would be beneficial to you or not.


kenanja wrote:
2. Is there in the OOo API a method provided to get the number of elements for the createEnumeration() method. Danny, in topic http://www.oooforum.org/forum/viewtopic.php?p=14057#14057 you used a loop with a counter so I assume there isn't such a method available


I do not believe so now. I did not believe so then. But I would love to be proven wrong. Please.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Jan 22, 2004 8:51 am    Post subject: Reply with quote

Okay, sorry for the delay. Here is how I got the soffice.exe process to terminate.

Note: I am using OpenOffice.org 1.1.0 and the OpenOffice.org 1.1rc4 SDK. Windows XP with Java2 SDK 1.4.1 SE.

I use a Java Dialog object to display an OfficeWriter instance, so in my Dialog object, I have added a WindowListener to catch when the user closes the window by not using the "Close" button I provide.

Code:

    addWindowListener(new java.awt.event.WindowAdapter() {
      public void windowClosing(java.awt.event.WindowEvent evt) {
        closeDialog(evt);
      }
    });


Here is my closeDialog() method:
Code:

    private void closeDialog(java.awt.event.WindowEvent evt) {
      log.pushMethodName(this, "closeDialog");
      shutdownDialog();
      log.popMethodName();
    }


And here is the shutdownDialog() method:
Code:

    private void shutdownDialog() {
      log.pushMethodName(this, "shutdownDialog");
      mOfficeWriter.disposeComponents();
      this.dispose();
      log.popMethodName();
    }

Note: mOfficeWriter is an instance of OfficeBean.OfficeWriterBean.OfficeWriter, from the examples in the OOo SDK. I have added the disposeComponents() method.

The reason I call shutdownDialog() from closeDialog() and ignore the WindowEvent is because I also have a "Close" button on the dialog which calls shutdownDialog(), so the user can close the dialog by either clicking the "X" button at top right of window, or click the "Close" button. I don't care about the WindowEvent since I call this.dispose() in the Dialog.

Now here is my code for disposeComponents():
Code:

  public synchronized void disposeComponents() {
    log.pushMethodName(this, "disposeComponents");
   
    log.finer("try to dispose components");
   
    try {
      XDesktop xDesktop = (XDesktop)UnoRuntime.queryInterface(
      XDesktop.class, mDesktop);
     
      XEnumerationAccess xComponentsAccess = xDesktop.getComponents();
      XEnumeration xComponents = xComponentsAccess.createEnumeration();
     
      while (xComponents.hasMoreElements()) {
        Object oComp = xComponents.nextElement();
        //debugServiceNames(oComp);
        log.finer("component found");
       
        XServiceInfo xInfo = (XServiceInfo) UnoRuntime.queryInterface(
        XServiceInfo.class, oComp);
       
        if (xInfo != null) {
          if (xInfo.supportsService("com.sun.star.document.OfficeDocument")) {
            log.finer("OfficeDocument found");
            XModel xModel = (XModel) UnoRuntime.queryInterface(
            XModel.class, oComp);
            if (xModel != null) {
              log.finer("XModel found");
              try {
                xModel.dispose();
                log.finer("XModel disposed");
              }
              catch (Exception e) {
                log.warning(e.toString() + ":unabled to dispose XModel");
              }
            }
            else {
              log.finer("XModel null");
            }
          }
        }
      }
      if (xDesktop != null) {
        xDesktop.terminate();
        log.finer("desktop terminated.");
      }
      else {
        log.finer("desktop null.");
      }
    }
    catch (Exception e) {
      log.warning(e.toString() + ": unable to close all components.");
    }
   
    log.popMethodName();
  }



Here is the stdout after I close the Dialog with either the "X" or the close button:
Code:

Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:try to dispose components
Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:component found
Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:OfficeDocument found
Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:XModel found
Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:XModel disposed
Jan 22, 2004 10:18:51 AM OfficeBean.OfficeWriterBean.OfficeWriter disposeComponents
FINER: MIKEL:LIFEBOOK:desktop terminated.


It seemed that even if I commented out the code to xModel.dispose(), that the soffice.exe process was still terminated. That would indicate that only terminating the desktop was responsible for killing the soffice.exe process. But I included it anyway. I don't recall why terminating the desktop a month ago didn't work.

Now all this feels pretty stable at the moment. After I close the Dialog I am able to open up a OpenOffice.org document outside of my application with no problems. Previously, when the soffice.exe was still running as a result of my app, when I tried to open a document externally, nothing would happen.

Here's another thing. If I open an untitled OOo document, and then run my app, I get 2 soffice.exe processes running. Okay, that's fine. When I close the Dialog in my app, both windows get killed, but both soffice.exe processes are still running. Then if I try to open anotther untitled OOo document, no window apears, but a third soffice.exe process starts. Now if I kill the previous 2 soffice.exe processes, my untitled OOo document window appears. Obviously there's more work to be done here, since my users may eventually be using OOo as an Twisted Evil MS Office Twisted Evil alternative, but for now, it is working better than it was earlier this week.

If anyone has any input or suggestions, jump in. I think I've included everything in this post, so if something doesn't look right or make sense, post it here.

Also thanks to everyone who has been posting on this subject, which has helped me put together something that currently works.

Cheers,
MikeL.
Very Happy
Back to top
MikeL
General User
General User


Joined: 12 Nov 2003
Posts: 41
Location: Little Rock, Arkansas, USA

PostPosted: Thu Jan 22, 2004 8:58 am    Post subject: Reply with quote

Anonymous wrote:
Okay, sorry for the delay. Here is how I got the soffice.exe process to terminate.


Okay, this last post was mine, I just forgot to login.

MikeL.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
joelgr77
General User
General User


Joined: 13 Aug 2003
Posts: 18
Location: Maryland, U.S.A.

PostPosted: Wed Mar 10, 2004 12:42 pm    Post subject: Reply with quote

I've found the only way to be sure soffice is terminated is to start it within my Java app, and destroy the process when done. Something like:
Code:

//build cmd string to start soffice
Process p = Runtime.getRuntime.exec( cmd );
//do stuff
p.destory();


But if a copy of soffice is running before my code runs, then I still may end up with multiple soffice processes in some sort of deadlock.
Back to top
View user's profile Send private message Visit poster's website
jenz
Guest





PostPosted: Wed Mar 17, 2004 7:17 am    Post subject: Reply with quote

hi, i have the same problem. This problem is really bad and drives me crazy. This additional soffice.exe process, which is created by the java officebean, is not dying. As long as it runs, it doesn't allow the user to open new douments in the default windows explorer environment. it's really bad.

I tried MikeL's solutions, but it doesn't work for me, the process is still there. And it closes all documents, which were opened in OpenOffice, not only the document, which was opened by java.

I can't use joelgr77's solution, because i am using MyOfficeBean to open connection.

Any solutions?

thanks,
jenz
Back to top
jenz
Guest





PostPosted: Wed Mar 17, 2004 8:03 am    Post subject: Reply with quote

ok, after some more playing...

it seems to work, if you remove the default openoffice-quickstarter from the autorun-group and replace it with
soffice.exe -bean -accept=pipe,name=<user.name>_Office;urp;StarOffice.NamingService

now there is always only one soffice-process. but i think, it's not the best way, only a workaround.

jenz
Back to top
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group