How to determine and use Process IDs of the different LibreOffice programs?

Hello,

I have a requirement to open office documents from one application at a time and provide this for the formats:

  • Word document
  • Excel spreadsheet
  • PowerPoint presentation
  • OpenOffice Writer document
  • OpenOffice Calc spreadsheet
  • OpenOffice Impress presentation
  • LibreOffice Writer document
  • LibreOffice Calc spreadsheet
  • LibreOffice Impress presentation

After my application opens the file, the associated program determines its Process ID and monitors it. When the user wants to stop editing, my program sends a WM_CLOSE command to that Process ID, where the associated application then asks if it should save. This works fine with Microsoft Office, and a separate Process ID is assigned to each of the programs Word, Excel and PowerPoint.

With LibreOffice this looks completely different. Here there is only the soffice.exe Process and below it the soffice.bin Process. Both have a separate Process ID, but this state does not change even if I have 10 Writer, Calc and Impress files open. Therefore, my previous approach is obviously not suitable for LibreOffice, because I don’t want to close all documents, but only selected ones.

How can I still achieve my goal and close each of the edited documents? Is this only possible via the UNO API or would it also be possible via the Windows-based Process IDs?

Thanks for your answers…

This wouldn’t be possible using process id, unless you use separate user profiles when starting each instance. (Which implies that there would be slower opening of the following instances, and clipboard operations across instances would be sub-optimal, not using internal richer clipboard).

LibreOffice is “monolithic”. You can close every component (or otherwise interfere with it) using the StarDesktop object which knows (e.g.) a RuntimeID for every component and can easily determine what kind of document there is loaded. If you describe your actual intentions a bit more detailed, best without refering to the ways you are used to due to your experience with MS software, you may get useful suggestions.
What you already mentioned should be simple, imo.

Okay thanks for your answers.

If I move away from the previous way of thinking, and move away from handling the use of ProcessIDs, the only thing that seems to remain is the use of the UNO bridge.

For OpenOffice, I already have an OLE binding ready to go, using

  • ServiceManager = CreateOleObject(‘com.sun.star.ServiceManager’)
  • Desktop = ServiceManager.CreateInstance(‘com.sun.star.frame.Desktop’)
  • Desktop.LoadComponentFromURL(…)

and this works and can open any OpenOffice documents.

However, this approach doesn’t seem to work with LibreOffice because I can only control OpenOffice with it. Is the UNO approach so clearly different here or what could the commands be if I simply want to open, save and close an existing document?

Would appreciate any tips… thanks.

This creates a COM object registered in system. Indeed, there can only be one com.sun.star.ServiceManager system registration, and on your system, the two suites that implement that class compete for that registration; that would likely depend on the installation order (last installed wins). But that doesn’t mean that you “can only control OpenOffice with it” - just you only can control the registered application with it :slight_smile:

The problem may be that both suites implement the same version of the class, which makes it impossible to e.g. explicitly instantiate specific version of several installed. You could want to file respective feature request if that is important to you.

Ahh I understand.

Would the order of my calls still be the same if I want to do this with LibreOffice instead of OpenOffice?

We try to not break API compatibility. Basically everything working with OOo should work with LO. AOO is also based on OOo, so shares the same inherited API - and that extends the above to “most things working with AOO should work with LO”. Yet, there are things that don’t:

  1. There may be API changes in LO (we publish each such change in our release notes) - but most often, such changes are for some unused, deprecated or even unimplemented APIs;
  2. There may be some things newly implemented in AOO that are implemented differently in LO (an API for accessing sheet-local named ranges comes to mind, that was implemented in AOO in such a convoluted way, long after we implemented it - and macros using that AOO API will not work in LO);
  3. There may be bugs, that need to be fixed.

Having said that for completeness, I should now answer in a simpler way: yes, I expect that your code would most likely work with LO as is.

Thanks for the answer and explanation.

Is there any way I can find out which office suite the “com.sun.star.ServiceManager” system registration is associated with and bend that registration to another office suite installed in parallel? Is this even possible?

Or is this done with the respective office installers and the last installed office suite then gets the system registration?

Yes that is what installers do; I mentioned above that “that would likely depend on the installation order (last installed wins)”.

Search for com.sun.star.ServiceManager in registry. Indeed, making edits in registry could help you (to make it work as you need, or to ruin your OS if you are unlucky :wink:)

@mikekaganski , silly question: is it possible to do this (VBS):

Set oSM = GetObject("New:{82154420-0FBF-11d4-8313-005004526AB4}") 

Or is the CLSID the same in AOO and LO?

Yes it’s the same, and is hardcoded:

https://opengrok.libreoffice.org/xref/core/udkapi/com/sun/star/bridge/oleautomation/ApplicationRegistration.idl?r=3bf4af8d

which is why I suggested to file a request to implement another version of the class, to allow having several registrations co-exist on the same system.

Thanks a lot!