27#include <osl/diagnose.h>
28#include <osl/mutex.hxx>
29#include <osl/conditn.hxx>
31#include <rtl/process.h>
37#include <com/sun/star/lang/XMain.hpp>
38#include <com/sun/star/lang/XInitialization.hpp>
39#include <com/sun/star/lang/XComponent.hpp>
40#include <com/sun/star/lang/XSingleComponentFactory.hpp>
41#include <com/sun/star/lang/XSingleServiceFactory.hpp>
42#include <com/sun/star/lang/XEventListener.hpp>
43#include <com/sun/star/loader/XImplementationLoader.hpp>
44#include <com/sun/star/registry/XRegistryKey.hpp>
45#include <com/sun/star/connection/Acceptor.hpp>
46#include <com/sun/star/connection/XConnection.hpp>
47#include <com/sun/star/bridge/XBridgeFactory.hpp>
48#include <com/sun/star/bridge/XBridge.hpp>
55using namespace com::sun::star::loader;
66static void out(
const char * pText )
69 fputs( pText, stderr );
72static void out( std::u16string_view rText )
77 fputs( aText.getStr(), stderr );
83"uno [-c ComponentImplementationName -l LocationUrl | -s ServiceName]\n"
84" [-u uno:(socket[,host=HostName][,port=nnn]|pipe[,name=PipeName]);<protocol>;Name\n"
85" [--singleaccept] [--singleinstance]]\n"
87" [-- Argument1 Argument2 ...]\n";
90static bool readOption( OUString * pValue,
const char * pOpt,
91 sal_uInt32 * pnIndex,
const OUString & aArg)
93 static constexpr OUStringLiteral dash(
u"-");
94 if(!aArg.startsWith(dash))
97 OUString aOpt = OUString::createFromAscii( pOpt );
99 if (aArg.getLength() < aOpt.getLength())
102 if (aOpt.equalsIgnoreAsciiCase( aArg.subView(1, aArg.getLength()-1) ))
107 rtl_getAppCommandArg(*pnIndex, &pValue->pData);
108 if (*pnIndex >= rtl_getAppCommandArgCount() || pValue->subView(1) == dash)
112 SAL_INFO(
"cpputools.unoexe",
"> identified option -" << pOpt <<
" = " << aArg);
116 else if (aArg.indexOf(aOpt) == 1)
118 *pValue = aArg.copy(1 + aOpt.getLength());
119 SAL_INFO(
"cpputools.unoexe",
"> identified option -" << pOpt <<
" = " << aArg);
128 sal_uInt32 * pnIndex, std::u16string_view aArg)
130 OUString aOpt = OUString::createFromAscii(pOpt);
136 SAL_INFO(
"cpputools.unoexe",
"> identified option --" << pOpt);
147 const OUString & rServiceName )
154 throw RuntimeException(
"cannot get service instance \"" + rServiceName +
"\"!" );
157 rxOut.set(
x.get(), UNO_QUERY_THROW );
163 const OUString & rImplName,
const OUString & rLocation )
166 sal_Int32 nDot = rLocation.lastIndexOf(
'.' );
167 if (nDot <= 0 || nDot >= rLocation.getLength())
170 "location \"" + rLocation +
"\" has no extension! Cannot determine loader to be used!" );
175 std::u16string_view aExt( rLocation.subView( nDot +1 ) );
177 if (aExt ==
u"dll" || aExt ==
u"exe" || aExt ==
u"dylib" || aExt ==
u"so")
180 xLoader, xContext,
"com.sun.star.loader.SharedLibrary" );
182 else if (aExt ==
u"jar" || aExt ==
u"class")
185 xLoader, xContext,
"com.sun.star.loader.Java" );
190 "unknown extension of \"" + rLocation +
"\"! No loader available!" );
203 xInstance = xCFac->createInstanceWithContext( xContext );
210 out(
"\n> warning: ignoring context for implementation \"" );
213 xInstance = xSFac->createInstance();
218 if (! xInstance.is())
221 "activating component \"" + rImplName +
"\" from location \"" + rLocation +
"\" failed!" );
229class OInstanceProvider
230 :
public WeakImplHelper< XInstanceProvider >
250 OUString aImplName, OUString aLocation,
252 bool bSingleInstance, OUString aInstanceName )
294 OSL_ASSERT( rName ==
"uno.ComponentContext" );
317 catch (Exception & rExc)
319 out(
"\n> error: " );
322 throw NoSuchElementException(
323 "no such element \"" + rName +
"\"!" );
328struct ODisposingListener :
public WeakImplHelper< XEventListener >
333 virtual void SAL_CALL disposing(
const EventObject & rEvt )
override;
340void ODisposingListener::disposing(
const EventObject & )
349 xComp->addEventListener( xListener );
350 xListener->cDisposed.wait();
359 sal_uInt32
nCount = rtl_getAppCommandArgCount();
372 OUString aImplName, aLocation, aServiceName, aUnoUrl;
374 bool bSingleAccept =
false;
375 bool bSingleInstance =
false;
385 rtl_getAppCommandArg(
nPos, &arg.pData);
402 "unexpected argument \"" + arg +
"\"" );
406 if (!(aImplName.isEmpty() || aServiceName.isEmpty()))
408 if (aImplName.isEmpty() && aServiceName.isEmpty())
410 if (! aUnoUrl.endsWithIgnoreAsciiCase(
";uno.ComponentContext" ))
412 "expected UNO-URL with instance name uno.ComponentContext!" );
415 "unexpected option --singleinstance!" );
417 if (!aImplName.isEmpty() && aLocation.isEmpty())
419 if (!aServiceName.isEmpty() && !aLocation.isEmpty())
420 out(
"\n> warning: service name given, will ignore location!" );
424 OUString * pParams = aParams.getArray();
426 sal_uInt32 nOffset =
nPos;
436 if (!aUnoUrl.isEmpty())
438 if (aUnoUrl.getLength() < 10 || !aUnoUrl.startsWithIgnoreAsciiCase(
"uno:" ))
444 bool bTooFewTokens {
false};
445 const OUString aConnectDescr{ aUnoUrl.getToken( 0,
';',
nIndex ) };
446 if (
nIndex<0) bTooFewTokens =
true;
447 const OUString aUnoUrlToken{ aUnoUrl.getToken( 0,
';',
nIndex ) };
448 if (
nIndex<0) bTooFewTokens =
true;
449 const OUString aInstanceName{ aUnoUrl.getToken( 0,
';',
nIndex ) };
452 if (bTooFewTokens ||
nIndex>0)
461 const OUString *
p = aParams.getConstArray();
462 Any * pInitParams = aInitParams.getArray();
463 for ( sal_Int32
i = aParams.getLength();
i--; )
465 pInitParams[
i] <<=
p[
i];
470 xContext, aImplName, aLocation, aServiceName, aInitParams,
471 bSingleInstance, aInstanceName ) );
477 out(
"\n> accepting " );
478 out( aConnectDescr );
481 out(
"connection established." );
485 xBridgeFactory, xContext,
486 "com.sun.star.bridge.BridgeFactory" );
490 OUString(), aUnoUrlToken,
491 xConnection, xInstanceProvider ) );
496 ODisposingListener::waitFor( xComp );
508 if (!aImplName.isEmpty())
517 nRet = xMain->run( aParams );
524 throw RuntimeException(
"component does not export interface \"com.sun.star.lang.XMain\"!" );
530 out(
"\n> error: " );
532 out(
"\n> dying..." );
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
Reference< XSingleServiceFactory > xFactory
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
CPPUHELPER_DLLPUBLIC css::uno::Reference< css::uno::XComponentContext > SAL_CALL defaultBootstrap_InitialComponentContext()
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
static bool readOption(bool *pbOpt, const char *pOpt, sal_uInt32 *pnIndex, std::u16string_view aArg)
static bool readOption(OUString *pValue, const char *pOpt, sal_uInt32 *pnIndex, const OUString &aArg)
static void createInstance(Reference< T > &rxOut, const Reference< XComponentContext > &xContext, const OUString &rServiceName)
static void out(std::u16string_view rText)
static Reference< XInterface > loadComponent(const Reference< XComponentContext > &xContext, const OUString &rImplName, const OUString &rLocation)
static void out(const char *pText)
Sequence< Any > _aInitParams
Reference< XComponentContext > _xContext
std::mutex _aSingleInstanceMutex
Reference< XInterface > _xSingleInstance