Writing Client Programs
To build a client program it must reference at least
cli_cppuhelper.dll. Also cli_ure can be referenced when one of its classes is used. These libraries are installed in the GAC and the program folder of the office installation. The referencing is done by certain compiler switches, for example /AI for C++ (with managed extensions) or /reference for the C# compiler. C++ also requires dlls to be specified by using the #using:
#using <mscorlib.dll> #using <cli_types.dll>
In c# with Visual Studio mscorlib is included when you create your project. If you want to see it in your references, edit your .csproj file and add:
<ItemGroup> <Reference Include="mscorlib" /> <Reference Include="System" />
For cli_basetypes, cli_cppuhelper, cli_oootypes, cli_ure, and cli_uretypes .dll files, I add them in the Visual Studio project References. I found cli_cppuhelper here C:\WINDOWS\assembly\GAC_32\cli_cppuhelper\126.96.36.199__ce2cb7e279207b9e\cli_cppuhelper.dll and the others in GAC_MSIL near here C:\WINDOWS\assembly\GAC_MSIL\cli_basetypes\188.8.131.52__ce2cb7e279207b9e\cli_basetypes.dll. Then add the following in my source when one of their classes is used:
using unoidl.com.sun.star.lang; using unoidl.com.sun.star.uno; using unoidl.com.sun.star.bridge; using unoidl.com.sun.star.frame; using unoidl.com.sun.star.util;
The following example discusses how to use services provided by a running office process:
The starting point of every remote client program is a component context. It is created by a static function
defaultBootstrap_InitialComponentContext, which is provided by the class
uno.util.Bootstrap. The context provides the service manager by which UNO components can be created. However, these components would still be local to the client process, that is, they are not from a running office and therefore cannot affect the running office. What is actually needed is a service manager of a running office. To achieve that, the component com.sun.star.bridge.UnoUrlResolver is used, which is provided by the local service manager. The UnoUrlResolver connects to the remote office and creates a proxy of the office's service manager in the client process. The example code (OOo 2.x) is as follows:
//C# example System.Collections.Hashtable ht = new System.Collections.Hashtable(); ht.Add("SYSBINDIR", "file:///<office-dir>/program"); unoidl.com.sun.star.uno.XComponentContext xLocalContext = uno.util.Bootstrap.defaultBootstrap_InitialComponentContext( "file:///<office-dir>/program/uno.ini", ht.GetEnumerator()); unoidl.com.sun.star.bridge.XUnoUrlResolver xURLResolver = (unoidl.com.sun.star.bridge.XUnoUrlResolver) xLocalContext.getServiceManager(). createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", xLocalContext); unoidl.com.sun.star.uno.XComponentContext xRemoteContext = (unoidl.com.sun.star.uno.XComponentContext) xURLResolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext"); unoidl.com.sun.star.lang.XMultiServiceFactory xRemoteFactory = (unoidl.com.sun.star.lang.XMultiServiceFactory) xRemoteContext.getServiceManager();
For OOo 3.x the code is this:
//C# example for OOo 3.x //Workaround which is needed when using a socket connection //This will initialize the Windows socket library. System.Net.Sockets.Socket s = new System.Net.Sockets.Socket( AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); // String sUnoIni = "file:///d:/OpenOffice.org%203/URE/bin/uno.ini"; XComponentContext xLocalContext = uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(sUnoIni, null); XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager(); XUnoUrlResolver xUrlResolver = (XUnoUrlResolver)xLocalServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xLocalContext); XMultiServiceFactory multiServiceFactory = (XMultiServiceFactory)xUrlResolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
Alternatively one could use pipe connection, in which case, no socket needs to be created beforehand.
//C# example for OOo 3.x String sUnoIni = "file:///d:/OpenOffice.org%203/URE/bin/uno.ini"; XComponentContext xLocalContext = uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(sUnoIni, null); XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager(); XUnoUrlResolver xUrlResolver = (XUnoUrlResolver)xLocalServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xLocalContext); XMultiServiceFactory multiServiceFactory = (XMultiServiceFactory)xUrlResolver.resolve( "uno:pipe,name=some_unique_pipe_name;urp;StarOffice.ServiceManager");
Usually one would provide a path to the uno.ini (URE/bin folder) in the office installation. In that case and if one does not want to provide particular bootstrap variables (the second parameter of defaultBootstrap_InitialComponentContext) then one can use the version of defaultBootstrap_InitialComponentContext which does not take arguments:
XComponentContext xLocalContext = uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(); XMultiServiceFactory fac = (XMultiServiceFactory) m_xContext.getServiceManager();
With the factory of the running office at hand, all components of the remote office are accessible.
For a client to connect to a running office, the office must have been started with the proper parameters. In this case, the command line looks like this:
or using a pipe connection
Other useful command line options for Apache OpenOffice are: -minimized -invisible -nologo -nolockcheck -nodefault
See also UNO Interprocess Connections.
As of OOo 3.0 it is necessary to provide an ini file which contains the path to the fundamental.ini when using the defaultBootstrap_InitialComponentContext functions. The ini file must have the same name as the client program (without extension). For example, the program is named client.exe then there must be also a client.ini in the same folder. The path to the fundamental.ini must be a file URL. That is special characters need to be encoded. For example, a space is represented as %20. An example:
Another, simpler way of starting and connection to Apache OpenOffice is to use the function
uno.util.Bootstrap.bootstrap. The function finds Apache OpenOffice by using the registry (
HKEY_LOCAL_MACHINE\Software\OpenOffice.org\UNO\InstallPath) or the environment variable
UNO_PATH. The function uses the key in
HKEY_CURRENT_USER first, and if it does not exists it uses the key in
HKEY_LOCAL_MACHINE. In case the office does not start, check these keys. Also make sure that the PATH environment variable does not contain the program path to a different office.
//C# example. OOo is started automatically. XComponentContext xContext = uno.util.Bootstrap.bootstrap();
This method of getting the context no even require an ini file. The limitation is, that it always uses a pipe connection. In other word, it is suitable for a local Apache OpenOffice but not for one on a different machine.
It is possible to write UNO applications that do not depend on a running office. Then, you would typically provide an own database of registered services. For more information, see Manual Component Installation.
The CLI-UNO language binding does not support UNO components that are written in a CLI language. Instead, it acts as a liaison between a CLI client program and an office. The client program usually obtains UNO objects from the office and performs operations on them. Therefore, it is rarely necessary to implement UNO interfaces.
To receive notifications from UNO objects, it is necessary to implement the proper interfaces. Also, interfaces can be implemented in order to use the objects as arguments to UNO methods.
Interfaces are implemented by declaring a class that derives from one or more interfaces, and which provides implementations for the interface methods. How this is done is covered by the respective documentation of the various CLI languages.
|Content on this page is licensed under the Public Documentation License (PDL).|