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