1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 30 #include "dp_misc.h" 31 #include "unopkg_main.h" 32 #include "unopkg_shared.h" 33 #include "dp_identifier.hxx" 34 #include "sal/main.h" 35 #include "tools/extendapplicationenvironment.hxx" 36 #include "rtl/ustrbuf.hxx" 37 #include "rtl/uri.hxx" 38 #include "rtl/bootstrap.hxx" 39 #include "osl/thread.h" 40 #include "osl/process.h" 41 #include "osl/conditn.hxx" 42 #include "osl/file.hxx" 43 #include "cppuhelper/implbase1.hxx" 44 #include "cppuhelper/exc_hlp.hxx" 45 #include "comphelper/anytostring.hxx" 46 #include "comphelper/sequence.hxx" 47 #include "com/sun/star/deployment/ExtensionManager.hpp" 48 49 #include "com/sun/star/deployment/ui/PackageManagerDialog.hpp" 50 #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp" 51 #include "com/sun/star/lang/DisposedException.hpp" 52 #include "boost/scoped_array.hpp" 53 #include "com/sun/star/ui/dialogs/XDialogClosedListener.hpp" 54 #include "com/sun/star/bridge/XBridgeFactory.hpp" 55 #include <stdio.h> 56 #include <vector> 57 58 59 using namespace ::com::sun::star; 60 using namespace ::com::sun::star::uno; 61 using namespace ::unopkg; 62 using ::rtl::OUString; 63 namespace css = ::com::sun::star; 64 namespace { 65 66 struct ExtensionName 67 { 68 OUString m_str; 69 ExtensionName( OUString const & str ) : m_str( str ) {} 70 bool operator () ( Reference<deployment::XPackage> const & e ) const 71 { 72 if (m_str.equals(dp_misc::getIdentifier(e)) 73 || m_str.equals(e->getName())) 74 return true; 75 return false; 76 } 77 }; 78 79 //------------------------------------------------------------------------------ 80 const char s_usingText [] = 81 "\n" 82 "using: " APP_NAME " add <options> extension-path...\n" 83 " " APP_NAME " validate <options> extension-identifier...\n" 84 " " APP_NAME " remove <options> extension-identifier...\n" 85 " " APP_NAME " list <options> extension-identifier...\n" 86 " " APP_NAME " reinstall <options>\n" 87 " " APP_NAME " gui\n" 88 " " APP_NAME " -V\n" 89 " " APP_NAME " -h\n" 90 "\n" 91 "sub-commands:\n" 92 " add add extension\n" 93 " validate checks the prerequisites of an installed extension and" 94 " registers it if possible\n" 95 " remove remove extensions by identifier\n" 96 " reinstall expert feature: reinstall all deployed extensions\n" 97 " list list information about deployed extensions\n" 98 " gui raise Extension Manager Graphical User Interface (GUI)\n" 99 "\n" 100 "options:\n" 101 " -h, --help this help\n" 102 " -V, --version version information\n" 103 " -v, --verbose verbose output to stdout\n" 104 " -f, --force force overwriting existing extensions\n" 105 " -s, --suppress-license prevents showing the license provided that\n" 106 " the extension allows it\n" 107 " --log-file <file> custom log file; default: <cache-dir>/log.txt\n" 108 " --shared expert feature: operate on shared installation\n" 109 " deployment context;\n" 110 " run only when no concurrent Office\n" 111 " process(es) are running!\n" 112 " --bundled expert feature: operate on bundled extensions. Only\n" 113 " works with list, validate, reinstall;\n" 114 " --deployment-context expert feature: explicit deployment context\n" 115 " <context>\n" 116 "\n" 117 "To learn more about the Extension Manager and extensions, see:\n" 118 "http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n"; 119 120 //------------------------------------------------------------------------------ 121 const OptionInfo s_option_infos [] = { 122 { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false }, 123 { RTL_CONSTASCII_STRINGPARAM("version"), 'V', false }, 124 { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false }, 125 { RTL_CONSTASCII_STRINGPARAM("force"), 'f', false }, 126 { RTL_CONSTASCII_STRINGPARAM("log-file"), '\0', true }, 127 { RTL_CONSTASCII_STRINGPARAM("shared"), '\0', false }, 128 { RTL_CONSTASCII_STRINGPARAM("deployment-context"), '\0', true }, 129 { RTL_CONSTASCII_STRINGPARAM("bundled"), '\0', false}, 130 { RTL_CONSTASCII_STRINGPARAM("suppress-license"), 's', false}, 131 132 { 0, 0, '\0', false } 133 }; 134 135 class DialogClosedListenerImpl : 136 public ::cppu::WeakImplHelper1< ui::dialogs::XDialogClosedListener > 137 { 138 osl::Condition & m_rDialogClosedCondition; 139 140 public: 141 DialogClosedListenerImpl( osl::Condition & rDialogClosedCondition ) 142 : m_rDialogClosedCondition( rDialogClosedCondition ) {} 143 144 // XEventListener (base of XDialogClosedListener) 145 virtual void SAL_CALL disposing( lang::EventObject const & Source ) 146 throw (RuntimeException); 147 148 // XDialogClosedListener 149 virtual void SAL_CALL dialogClosed( 150 ui::dialogs::DialogClosedEvent const & aEvent ) 151 throw (RuntimeException); 152 }; 153 154 // XEventListener (base of XDialogClosedListener) 155 void DialogClosedListenerImpl::disposing( lang::EventObject const & ) 156 throw (RuntimeException) 157 { 158 // nothing to do 159 } 160 161 // XDialogClosedListener 162 void DialogClosedListenerImpl::dialogClosed( 163 ui::dialogs::DialogClosedEvent const & ) 164 throw (RuntimeException) 165 { 166 m_rDialogClosedCondition.set(); 167 } 168 169 // If a package had been installed with a pre OOo 2.2, it could not normally be 170 // found via its identifier; similarly (and for ease of use), a package 171 // installed with OOo 2.2 or later could not normally be found via its file 172 // name. 173 Reference<deployment::XPackage> findPackage( 174 OUString const & repository, 175 Reference<deployment::XExtensionManager> const & manager, 176 Reference<ucb::XCommandEnvironment > const & environment, 177 OUString const & idOrFileName ) 178 { 179 Sequence< Reference<deployment::XPackage> > ps( 180 manager->getDeployedExtensions(repository, 181 Reference<task::XAbortChannel>(), environment ) ); 182 for ( sal_Int32 i = 0; i < ps.getLength(); ++i ) 183 if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName ) 184 return ps[i]; 185 for ( sal_Int32 i = 0; i < ps.getLength(); ++i ) 186 if ( ps[i]->getName() == idOrFileName ) 187 return ps[i]; 188 return Reference<deployment::XPackage>(); 189 } 190 191 } // anon namespace 192 193 194 //workaround for some reason the bridge threads which communicate with the uno.exe 195 //process are not releases on time 196 void disposeBridges(Reference<css::uno::XComponentContext> ctx) 197 { 198 if (!ctx.is()) 199 return; 200 201 Reference<css::bridge::XBridgeFactory> bridgeFac( 202 ctx->getServiceManager()->createInstanceWithContext( 203 OUSTR("com.sun.star.bridge.BridgeFactory"), ctx), 204 UNO_QUERY); 205 206 if (bridgeFac.is()) 207 { 208 const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges(); 209 for (sal_Int32 i = 0; i < seqBridges.getLength(); i++) 210 { 211 Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY); 212 if (comp.is()) 213 { 214 try { 215 comp->dispose(); 216 } 217 catch (css::lang::DisposedException& ) 218 { 219 } 220 } 221 } 222 } 223 } 224 225 //############################################################################## 226 extern "C" int unopkg_main() 227 { 228 tools::extendApplicationEnvironment(); 229 DisposeGuard disposeGuard; 230 bool bNoOtherErrorMsg = false; 231 OUString subCommand; 232 bool option_shared = false; 233 bool option_force = false; 234 bool option_verbose = false; 235 bool option_bundled = false; 236 bool option_suppressLicense = false; 237 bool subcmd_add = false; 238 bool subcmd_gui = false; 239 OUString logFile; 240 OUString repository; 241 OUString cmdArg; 242 ::std::vector<OUString> cmdPackages; 243 244 OptionInfo const * info_shared = getOptionInfo( 245 s_option_infos, OUSTR("shared") ); 246 OptionInfo const * info_force = getOptionInfo( 247 s_option_infos, OUSTR("force") ); 248 OptionInfo const * info_verbose = getOptionInfo( 249 s_option_infos, OUSTR("verbose") ); 250 OptionInfo const * info_log = getOptionInfo( 251 s_option_infos, OUSTR("log-file") ); 252 OptionInfo const * info_context = getOptionInfo( 253 s_option_infos, OUSTR("deployment-context") ); 254 OptionInfo const * info_help = getOptionInfo( 255 s_option_infos, OUSTR("help") ); 256 OptionInfo const * info_version = getOptionInfo( 257 s_option_infos, OUSTR("version") ); 258 OptionInfo const * info_bundled = getOptionInfo( 259 s_option_infos, OUSTR("bundled") ); 260 OptionInfo const * info_suppressLicense = getOptionInfo( 261 s_option_infos, OUSTR("suppress-license") ); 262 263 264 Reference<XComponentContext> xComponentContext; 265 Reference<XComponentContext> xLocalComponentContext; 266 267 try { 268 sal_uInt32 nPos = 0; 269 sal_uInt32 nCount = osl_getCommandArgCount(); 270 if (nCount == 0 || isOption( info_help, &nPos )) 271 { 272 dp_misc::writeConsole(s_usingText); 273 return 0; 274 } 275 else if (isOption( info_version, &nPos )) { 276 dp_misc::writeConsole("\n"APP_NAME" Version 3.3\n"); 277 return 0; 278 } 279 //consume all bootstrap variables which may occur before the subcommannd 280 while(isBootstrapVariable(&nPos)); 281 282 if(nPos >= nCount) 283 return 0; 284 //get the sub command 285 osl_getCommandArg( nPos, &subCommand.pData ); 286 ++nPos; 287 subCommand = subCommand.trim(); 288 subcmd_add = subCommand.equalsAsciiL( 289 RTL_CONSTASCII_STRINGPARAM("add") ); 290 subcmd_gui = subCommand.equalsAsciiL( 291 RTL_CONSTASCII_STRINGPARAM("gui") ); 292 293 // sun-command options and packages: 294 while (nPos < nCount) 295 { 296 if (readArgument( &cmdArg, info_log, &nPos )) { 297 logFile = makeAbsoluteFileUrl( 298 cmdArg.trim(), getProcessWorkingDir() ); 299 } 300 else if (!readOption( &option_verbose, info_verbose, &nPos ) && 301 !readOption( &option_shared, info_shared, &nPos ) && 302 !readOption( &option_force, info_force, &nPos ) && 303 !readOption( &option_bundled, info_bundled, &nPos ) && 304 !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) && 305 !readArgument( &repository, info_context, &nPos ) && 306 !isBootstrapVariable(&nPos)) 307 { 308 osl_getCommandArg( nPos, &cmdArg.pData ); 309 ++nPos; 310 cmdArg = cmdArg.trim(); 311 if (cmdArg.getLength() > 0) 312 { 313 if (cmdArg[ 0 ] == '-') 314 { 315 // is option: 316 dp_misc::writeConsoleError( 317 OUSTR("\nERROR: unexpected option ") + 318 cmdArg + 319 OUSTR("!\n") + 320 OUSTR(" Use " APP_NAME " ") + 321 toString(info_help) + 322 OUSTR(" to print all options.\n")); 323 return 1; 324 } 325 else 326 { 327 // is package: 328 cmdPackages.push_back( 329 subcmd_add || subcmd_gui 330 ? makeAbsoluteFileUrl( 331 cmdArg, getProcessWorkingDir() ) 332 : cmdArg ); 333 } 334 } 335 } 336 } 337 338 if (repository.getLength() == 0) 339 { 340 if (option_shared) 341 repository = OUSTR("shared"); 342 else if (option_bundled) 343 repository = OUSTR("bundled"); 344 else 345 repository = OUSTR("user"); 346 } 347 else 348 { 349 if (repository.equalsAsciiL( 350 RTL_CONSTASCII_STRINGPARAM("shared") )) { 351 option_shared = true; 352 } 353 else if (option_shared) { 354 dp_misc::writeConsoleError( 355 OUSTR("WARNING: explicit context given! ") + 356 OUSTR("Ignoring option ") + 357 toString( info_shared ) + 358 OUSTR("!\n") ); 359 } 360 } 361 362 if (subCommand.equals(OUSTR("reinstall"))) 363 { 364 //We must prevent that services and types are loaded by UNO, 365 //otherwise we cannot delete the registry data folder. 366 OUString extensionUnorc; 367 if (repository.equals(OUSTR("user"))) 368 extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 369 else if (repository.equals(OUSTR("shared"))) 370 extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 371 else if (repository.equals(OUSTR("bundled"))) 372 extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc"); 373 else 374 OSL_ASSERT(0); 375 376 ::rtl::Bootstrap::expandMacros(extensionUnorc); 377 oslFileError e = osl_removeFile(extensionUnorc.pData); 378 if (e != osl_File_E_None && e != osl_File_E_NOENT) 379 throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0); 380 } 381 else if (subCommand.equals(OUSTR("sync"))) 382 { 383 //sync is private!!!! Only to be called from setup!!! 384 //The UserInstallation is diverted to the prereg folder. But only 385 //the lock file is written! This requires that 386 //-env:UNO_JAVA_JFW_INSTALL_DATA is passed to javaldx and unopkg otherwise the 387 //javasettings file is written to the prereg folder. 388 // 389 //For performance reasons unopkg sync is called during the setup and 390 //creates the registration data for the repository of the bundled 391 //extensions. It is then copied to the user installation during 392 //startup of OOo (userdata/extensions/bundled). The registration 393 //data is in the brand installation and must be removed when 394 //uninstalling OOo. We do this here, before UNO is 395 //bootstrapped. Otherwies files could be locked by this process. 396 397 //If there is no folder left in 398 //$BRAND_BASE_DIR/share/extensions 399 //then we can delete the registration data at 400 //$BUNDLED_EXTENSIONS_USER 401 if (hasNoFolder(OUSTR("$BRAND_BASE_DIR/share/extensions"))) 402 { 403 removeFolder(OUSTR("$BUNDLED_EXTENSIONS_PREREG")); 404 //return otherwise we create the registration data again 405 return 0; 406 } 407 //redirect the UserInstallation, so we do not create a 408 //user installation for the admin and we also do not need 409 //to call unopkg with -env:UserInstallation 410 ::rtl::Bootstrap::set(OUSTR("UserInstallation"), 411 OUSTR("$BUNDLED_EXTENSIONS_PREREG/..")); 412 //Setting UNO_JAVA_JFW_INSTALL_DATA causes the javasettings to be written 413 //in the office installation. We do not want to create the user data folder 414 //for the admin. The value must also be set in the unopkg script (Linux, etc.) 415 //when calling javaldx 416 ::rtl::Bootstrap::set(OUSTR("UNO_JAVA_JFW_INSTALL_DATA"), 417 OUSTR("$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")); 418 419 } 420 421 xComponentContext = getUNO( 422 disposeGuard, option_verbose, option_shared, subcmd_gui, 423 xLocalComponentContext ); 424 425 Reference<deployment::XExtensionManager> xExtensionManager( 426 deployment::ExtensionManager::get( xComponentContext ) ); 427 428 Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv( 429 createCmdEnv( xComponentContext, logFile, 430 option_force, option_verbose) ); 431 432 //synchronize bundled/shared extensions 433 //Do not synchronize when command is "reinstall". This could add types and services to UNO and 434 //prevent the deletion of the registry data folder 435 //synching is done in XExtensionManager.reinstall 436 if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall")) 437 && ! subCommand.equals(OUSTR("sync")) 438 && ! dp_misc::office_is_running()) 439 dp_misc::syncRepositories(xCmdEnv); 440 441 if (subcmd_add || 442 subCommand.equalsAsciiL( 443 RTL_CONSTASCII_STRINGPARAM("remove") )) 444 { 445 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 446 { 447 OUString const & cmdPackage = cmdPackages[ pos ]; 448 if (subcmd_add) 449 { 450 beans::NamedValue nvSuppress( 451 OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ? 452 makeAny(OUSTR("1")):makeAny(OUSTR("0"))); 453 xExtensionManager->addExtension( 454 cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1), 455 repository, Reference<task::XAbortChannel>(), xCmdEnv); 456 } 457 else 458 { 459 try 460 { 461 xExtensionManager->removeExtension( 462 cmdPackage, cmdPackage, repository, 463 Reference<task::XAbortChannel>(), xCmdEnv ); 464 } 465 catch (lang::IllegalArgumentException &) 466 { 467 Reference<deployment::XPackage> p( 468 findPackage(repository, 469 xExtensionManager, xCmdEnv, cmdPackage ) ); 470 if ( !p.is()) 471 throw; 472 else if (p.is()) 473 xExtensionManager->removeExtension( 474 ::dp_misc::getIdentifier(p), p->getName(), 475 repository, 476 Reference<task::XAbortChannel>(), xCmdEnv ); 477 } 478 } 479 } 480 } 481 else if (subCommand.equalsAsciiL( 482 RTL_CONSTASCII_STRINGPARAM("reinstall") )) 483 { 484 xExtensionManager->reinstallDeployedExtensions( 485 repository, Reference<task::XAbortChannel>(), xCmdEnv); 486 } 487 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") )) 488 { 489 ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; 490 ::comphelper::sequenceToContainer(vecExtUnaccepted, 491 xExtensionManager->getExtensionsWithUnacceptedLicenses( 492 repository, xCmdEnv)); 493 494 //This vector tells what XPackage in allExtensions has an 495 //unaccepted license. 496 std::vector<bool> vecUnaccepted; 497 std::vector<Reference<deployment::XPackage> > allExtensions; 498 if (cmdPackages.empty()) 499 { 500 Sequence< Reference<deployment::XPackage> > 501 packages = xExtensionManager->getDeployedExtensions( 502 repository, Reference<task::XAbortChannel>(), xCmdEnv ); 503 504 ::std::vector<Reference<deployment::XPackage> > vec_packages; 505 ::comphelper::sequenceToContainer(vec_packages, packages); 506 507 //First copy the extensions with the unaccepted license 508 //to vector allExtensions. 509 allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size()); 510 511 ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext = 512 ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(), 513 allExtensions.begin()); 514 //Now copy those we got from getDeployedExtensions 515 ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext); 516 517 //Now prepare the vector which tells what extension has an 518 //unaccepted license 519 vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size()); 520 ::std::vector<bool>::iterator i_unaccepted = 521 ::std::fill_n(vecUnaccepted.begin(), 522 vecExtUnaccepted.size(), true); 523 ::std::fill_n(i_unaccepted, vec_packages.size(), false); 524 525 dp_misc::writeConsole( 526 OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n")); 527 } 528 else 529 { 530 //The user provided the names (ids or file names) of the extensions 531 //which shall be listed 532 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 533 { 534 Reference<deployment::XPackage> extension; 535 try 536 { 537 extension = xExtensionManager->getDeployedExtension( 538 repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); 539 } 540 catch (lang::IllegalArgumentException &) 541 { 542 extension = findPackage(repository, 543 xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); 544 } 545 546 //Now look if the requested extension has an unaccepted license 547 bool bUnacceptedLic = false; 548 if (!extension.is()) 549 { 550 ::std::vector<Reference<deployment::XPackage> >::const_iterator 551 i = ::std::find_if( 552 vecExtUnaccepted.begin(), 553 vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); 554 if (i != vecExtUnaccepted.end()) 555 { 556 extension = *i; 557 bUnacceptedLic = true; 558 } 559 } 560 561 if (extension.is()) 562 { 563 allExtensions.push_back(extension); 564 vecUnaccepted.push_back(bUnacceptedLic); 565 } 566 567 else 568 throw lang::IllegalArgumentException( 569 OUSTR("There is no such extension deployed: ") + 570 cmdPackages[pos],0,-1); 571 } 572 573 } 574 575 printf_packages(allExtensions, vecUnaccepted, xCmdEnv ); 576 } 577 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") )) 578 { 579 ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted; 580 ::comphelper::sequenceToContainer( 581 vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses( 582 repository, xCmdEnv)); 583 584 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos ) 585 { 586 Reference<deployment::XPackage> extension; 587 try 588 { 589 extension = xExtensionManager->getDeployedExtension( 590 repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv ); 591 } 592 catch (lang::IllegalArgumentException &) 593 { 594 extension = findPackage( 595 repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] ); 596 } 597 598 if (!extension.is()) 599 { 600 ::std::vector<Reference<deployment::XPackage> >::const_iterator 601 i = ::std::find_if( 602 vecExtUnaccepted.begin(), 603 vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos])); 604 if (i != vecExtUnaccepted.end()) 605 { 606 extension = *i; 607 } 608 } 609 610 if (extension.is()) 611 xExtensionManager->checkPrerequisitesAndEnable( 612 extension, Reference<task::XAbortChannel>(), xCmdEnv); 613 } 614 } 615 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") )) 616 { 617 Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog( 618 deployment::ui::PackageManagerDialog::createAndInstall( 619 xComponentContext, 620 cmdPackages.size() > 0 ? cmdPackages[0] : OUString() )); 621 622 osl::Condition dialogEnded; 623 dialogEnded.reset(); 624 625 Reference< ui::dialogs::XDialogClosedListener > xListener( 626 new DialogClosedListenerImpl( dialogEnded ) ); 627 628 xDialog->startExecuteModal(xListener); 629 dialogEnded.wait(); 630 } 631 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync"))) 632 { 633 if (! dp_misc::office_is_running()) 634 { 635 xExtensionManager->synchronizeBundledPrereg( 636 Reference<task::XAbortChannel>(), xCmdEnv); 637 } 638 else 639 { 640 dp_misc::writeConsoleError(OUSTR("\nError: office is running")); 641 } 642 } 643 else 644 { 645 dp_misc::writeConsoleError( 646 OUSTR("\nERROR: unknown sub-command ") + 647 subCommand + 648 OUSTR("!\n") + 649 OUSTR(" Use " APP_NAME " ") + 650 toString(info_help) + 651 OUSTR(" to print all options.\n")); 652 return 1; 653 } 654 655 if (option_verbose) 656 dp_misc::writeConsole(OUSTR("\n"APP_NAME" done.\n")); 657 //Force to release all bridges which connect us to the child processes 658 disposeBridges(xLocalComponentContext); 659 return 0; 660 } 661 catch (ucb::CommandFailedException &e) 662 { 663 dp_misc::writeConsoleError(e.Message + OUSTR("\n")); 664 bNoOtherErrorMsg = true; 665 } 666 catch (ucb::CommandAbortedException &) 667 { 668 dp_misc::writeConsoleError("\n"APP_NAME" aborted!\n"); 669 } 670 catch (deployment::DeploymentException & exc) 671 { 672 OUString cause; 673 if (option_verbose) 674 { 675 cause = ::comphelper::anyToString(exc.Cause); 676 } 677 else 678 { 679 css::uno::Exception e; 680 if (exc.Cause >>= e) 681 cause = e.Message; 682 } 683 684 dp_misc::writeConsoleError( 685 OUSTR("\nERROR: ") + exc.Message + OUSTR("\n")); 686 if (cause.getLength()) 687 dp_misc::writeConsoleError( 688 OUSTR(" Cause: ") + cause + OUSTR("\n")); 689 } 690 catch (LockFileException & e) 691 { 692 if (!subcmd_gui) 693 dp_misc::writeConsoleError(e.Message); 694 bNoOtherErrorMsg = true; 695 } 696 catch (::com::sun::star::uno::Exception & e ) { 697 Any exc( ::cppu::getCaughtException() ); 698 699 dp_misc::writeConsoleError( 700 OUSTR("\nERROR: ") + 701 OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") + 702 ::comphelper::anyToString(exc) : e.Message) + 703 OUSTR("\n")); 704 } 705 if (!bNoOtherErrorMsg) 706 dp_misc::writeConsoleError("\n"APP_NAME" failed.\n"); 707 disposeBridges(xLocalComponentContext); 708 return 1; 709 } 710 711 712