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__anon6ed6acfe0111::ExtensionName65 ExtensionName( OUString const & str ) : m_str( str ) {}
operator ()__anon6ed6acfe0111::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 "https://wiki.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
143 // XDialogClosedListener
144 virtual void SAL_CALL dialogClosed(
145 ui::dialogs::DialogClosedEvent const & aEvent );
146 };
147
148 // XEventListener (base of XDialogClosedListener)
disposing(lang::EventObject const &)149 void DialogClosedListenerImpl::disposing( lang::EventObject const & )
150 {
151 // nothing to do
152 }
153
154 // XDialogClosedListener
dialogClosed(ui::dialogs::DialogClosedEvent const &)155 void DialogClosedListenerImpl::dialogClosed(
156 ui::dialogs::DialogClosedEvent const & )
157 {
158 m_rDialogClosedCondition.set();
159 }
160
161 // If a package had been installed with a pre OOo 2.2, it could not normally be
162 // found via its identifier; similarly (and for ease of use), a package
163 // installed with OOo 2.2 or later could not normally be found via its file
164 // name.
findPackage(OUString const & repository,Reference<deployment::XExtensionManager> const & manager,Reference<ucb::XCommandEnvironment> const & environment,OUString const & idOrFileName)165 Reference<deployment::XPackage> findPackage(
166 OUString const & repository,
167 Reference<deployment::XExtensionManager> const & manager,
168 Reference<ucb::XCommandEnvironment > const & environment,
169 OUString const & idOrFileName )
170 {
171 Sequence< Reference<deployment::XPackage> > ps(
172 manager->getDeployedExtensions(repository,
173 Reference<task::XAbortChannel>(), environment ) );
174 for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
175 if ( dp_misc::getIdentifier( ps[i] ) == idOrFileName )
176 return ps[i];
177 for ( sal_Int32 i = 0; i < ps.getLength(); ++i )
178 if ( ps[i]->getName() == idOrFileName )
179 return ps[i];
180 return Reference<deployment::XPackage>();
181 }
182
183 } // anon namespace
184
185
186 //workaround for some reason the bridge threads which communicate with the uno.exe
187 //process are not released on time
disposeBridges(Reference<css::uno::XComponentContext> ctx)188 void disposeBridges(Reference<css::uno::XComponentContext> ctx)
189 {
190 if (!ctx.is())
191 return;
192
193 Reference<css::bridge::XBridgeFactory> bridgeFac(
194 ctx->getServiceManager()->createInstanceWithContext(
195 OUSTR("com.sun.star.bridge.BridgeFactory"), ctx),
196 UNO_QUERY);
197
198 if (bridgeFac.is())
199 {
200 const Sequence< Reference<css::bridge::XBridge> >seqBridges = bridgeFac->getExistingBridges();
201 for (sal_Int32 i = 0; i < seqBridges.getLength(); i++)
202 {
203 Reference<css::lang::XComponent> comp(seqBridges[i], UNO_QUERY);
204 if (comp.is())
205 {
206 try {
207 comp->dispose();
208 }
209 catch (css::lang::DisposedException& )
210 {
211 }
212 }
213 }
214 }
215 }
216
217 //##############################################################################
unopkg_main()218 extern "C" int unopkg_main()
219 {
220 tools::extendApplicationEnvironment();
221 DisposeGuard disposeGuard;
222 bool bNoOtherErrorMsg = false;
223 OUString subCommand;
224 bool option_shared = false;
225 bool option_force = false;
226 bool option_verbose = false;
227 bool option_bundled = false;
228 bool option_suppressLicense = false;
229 bool subcmd_add = false;
230 bool subcmd_gui = false;
231 OUString logFile;
232 OUString repository;
233 OUString cmdArg;
234 ::std::vector<OUString> cmdPackages;
235
236 OptionInfo const * info_shared = getOptionInfo(
237 s_option_infos, OUSTR("shared") );
238 OptionInfo const * info_force = getOptionInfo(
239 s_option_infos, OUSTR("force") );
240 OptionInfo const * info_verbose = getOptionInfo(
241 s_option_infos, OUSTR("verbose") );
242 OptionInfo const * info_log = getOptionInfo(
243 s_option_infos, OUSTR("log-file") );
244 OptionInfo const * info_context = getOptionInfo(
245 s_option_infos, OUSTR("deployment-context") );
246 OptionInfo const * info_help = getOptionInfo(
247 s_option_infos, OUSTR("help") );
248 OptionInfo const * info_version = getOptionInfo(
249 s_option_infos, OUSTR("version") );
250 OptionInfo const * info_bundled = getOptionInfo(
251 s_option_infos, OUSTR("bundled") );
252 OptionInfo const * info_suppressLicense = getOptionInfo(
253 s_option_infos, OUSTR("suppress-license") );
254
255
256 Reference<XComponentContext> xComponentContext;
257 Reference<XComponentContext> xLocalComponentContext;
258
259 try {
260 sal_uInt32 nPos = 0;
261 sal_uInt32 nCount = osl_getCommandArgCount();
262 if (nCount == 0 || isOption( info_help, &nPos ))
263 {
264 dp_misc::writeConsole(s_usingText);
265 return 0;
266 }
267 else if (isOption( info_version, &nPos )) {
268 dp_misc::writeConsole( "\n" APP_NAME " Version 3.3\n");
269 return 0;
270 }
271 // consume all bootstrap variables which may occur before the subcommand
272 while(isBootstrapVariable(&nPos));
273
274 if(nPos >= nCount)
275 return 0;
276 //get the sub command
277 osl_getCommandArg( nPos, &subCommand.pData );
278 ++nPos;
279 subCommand = subCommand.trim();
280 subcmd_add = subCommand.equalsAsciiL(
281 RTL_CONSTASCII_STRINGPARAM("add") );
282 subcmd_gui = subCommand.equalsAsciiL(
283 RTL_CONSTASCII_STRINGPARAM("gui") );
284
285 // sun-command options and packages:
286 while (nPos < nCount)
287 {
288 if (readArgument( &cmdArg, info_log, &nPos )) {
289 logFile = makeAbsoluteFileUrl(
290 cmdArg.trim(), getProcessWorkingDir() );
291 }
292 else if (!readOption( &option_verbose, info_verbose, &nPos ) &&
293 !readOption( &option_shared, info_shared, &nPos ) &&
294 !readOption( &option_force, info_force, &nPos ) &&
295 !readOption( &option_bundled, info_bundled, &nPos ) &&
296 !readOption( &option_suppressLicense, info_suppressLicense, &nPos ) &&
297 !readArgument( &repository, info_context, &nPos ) &&
298 !isBootstrapVariable(&nPos))
299 {
300 osl_getCommandArg( nPos, &cmdArg.pData );
301 ++nPos;
302 cmdArg = cmdArg.trim();
303 if (cmdArg.getLength() > 0)
304 {
305 if (cmdArg[ 0 ] == '-')
306 {
307 // is option:
308 dp_misc::writeConsoleError(
309 OUSTR("\nERROR: unexpected option ") +
310 cmdArg +
311 OUSTR("!\n") +
312 OUSTR(" Use " APP_NAME " ") +
313 toString(info_help) +
314 OUSTR(" to print all options.\n"));
315 return 1;
316 }
317 else
318 {
319 // is package:
320 cmdPackages.push_back(
321 subcmd_add || subcmd_gui
322 ? makeAbsoluteFileUrl(
323 cmdArg, getProcessWorkingDir() )
324 : cmdArg );
325 }
326 }
327 }
328 }
329
330 if (repository.getLength() == 0)
331 {
332 if (option_shared)
333 repository = OUSTR("shared");
334 else if (option_bundled)
335 repository = OUSTR("bundled");
336 else
337 repository = OUSTR("user");
338 }
339 else
340 {
341 if (repository.equalsAsciiL(
342 RTL_CONSTASCII_STRINGPARAM("shared") )) {
343 option_shared = true;
344 }
345 else if (option_shared) {
346 dp_misc::writeConsoleError(
347 OUSTR("WARNING: explicit context given! ") +
348 OUSTR("Ignoring option ") +
349 toString( info_shared ) +
350 OUSTR("!\n") );
351 }
352 }
353
354 if (subCommand.equals(OUSTR("reinstall")))
355 {
356 //We must prevent that services and types are loaded by UNO,
357 //otherwise we cannot delete the registry data folder.
358 OUString extensionUnorc;
359 if (repository.equals(OUSTR("user")))
360 extensionUnorc = OUSTR("$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
361 else if (repository.equals(OUSTR("shared")))
362 extensionUnorc = OUSTR("$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
363 else if (repository.equals(OUSTR("bundled")))
364 extensionUnorc = OUSTR("$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc");
365 else
366 OSL_ASSERT(0);
367
368 ::rtl::Bootstrap::expandMacros(extensionUnorc);
369 oslFileError e = osl_removeFile(extensionUnorc.pData);
370 if (e != osl_File_E_None && e != osl_File_E_NOENT)
371 throw Exception(OUSTR("Could not delete ") + extensionUnorc, 0);
372 }
373 else if (subCommand.equals(OUSTR("sync")))
374 {
375 //sync is private!!!! Only to be called from setup!!!
376 //The UserInstallation is diverted to the prereg folder. But only
377 //the lock file is written! This requires that
378 //-env:UNO_JAVA_JFW_INSTALL_DATA is passed to javaldx and unopkg otherwise the
379 //javasettings file is written to the prereg folder.
380 //
381 //For performance reasons unopkg sync is called during the setup and
382 //creates the registration data for the repository of the bundled
383 //extensions. It is then copied to the user installation during
384 //startup of AOO (userdata/extensions/bundled). The registration
385 //data is in the brand installation and must be removed when
386 //uninstalling AOO. We do this here, before UNO is
387 //bootstrapped. Otherwise files could be locked by this process.
388
389 //If there is no folder left in
390 //$OOO_BASE_DIR/share/extensions
391 //then we can delete the registration data at
392 //$BUNDLED_EXTENSIONS_USER
393 if (hasNoFolder(OUSTR("$OOO_BASE_DIR/share/extensions")))
394 {
395 removeFolder(OUSTR("$BUNDLED_EXTENSIONS_PREREG"));
396 //return otherwise we create the registration data again
397 return 0;
398 }
399 //redirect the UserInstallation, so we do not create a
400 //user installation for the admin and we also do not need
401 //to call unopkg with -env:UserInstallation
402 ::rtl::Bootstrap::set(OUSTR("UserInstallation"),
403 OUSTR("$BUNDLED_EXTENSIONS_PREREG/.."));
404 //Setting UNO_JAVA_JFW_INSTALL_DATA causes the javasettings to be written
405 //in the office installation. We do not want to create the user data folder
406 //for the admin. The value must also be set in the unopkg script (Linux, etc.)
407 //when calling javaldx
408 ::rtl::Bootstrap::set(OUSTR("UNO_JAVA_JFW_INSTALL_DATA"),
409 OUSTR("$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml"));
410
411 }
412
413 xComponentContext = getUNO(
414 disposeGuard, option_verbose, option_shared, subcmd_gui,
415 xLocalComponentContext );
416
417 Reference<deployment::XExtensionManager> xExtensionManager(
418 deployment::ExtensionManager::get( xComponentContext ) );
419
420 Reference< ::com::sun::star::ucb::XCommandEnvironment > xCmdEnv(
421 createCmdEnv( xComponentContext, logFile,
422 option_force, option_verbose) );
423
424 //synchronize bundled/shared extensions
425 //Do not synchronize when command is "reinstall". This could add types and services to UNO and
426 //prevent the deletion of the registry data folder
427 //synching is done in XExtensionManager.reinstall
428 if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall"))
429 && ! subCommand.equals(OUSTR("sync"))
430 && ! dp_misc::office_is_running())
431 dp_misc::syncRepositories(xCmdEnv);
432
433 if (subcmd_add ||
434 subCommand.equalsAsciiL(
435 RTL_CONSTASCII_STRINGPARAM("remove") ))
436 {
437 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
438 {
439 OUString const & cmdPackage = cmdPackages[ pos ];
440 if (subcmd_add)
441 {
442 beans::NamedValue nvSuppress(
443 OUSTR("SUPPRESS_LICENSE"), option_suppressLicense ?
444 makeAny(OUSTR("1")):makeAny(OUSTR("0")));
445 xExtensionManager->addExtension(
446 cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1),
447 repository, Reference<task::XAbortChannel>(), xCmdEnv);
448 }
449 else
450 {
451 try
452 {
453 xExtensionManager->removeExtension(
454 cmdPackage, cmdPackage, repository,
455 Reference<task::XAbortChannel>(), xCmdEnv );
456 }
457 catch (lang::IllegalArgumentException &)
458 {
459 Reference<deployment::XPackage> p(
460 findPackage(repository,
461 xExtensionManager, xCmdEnv, cmdPackage ) );
462 if ( !p.is())
463 throw;
464 else if (p.is())
465 xExtensionManager->removeExtension(
466 ::dp_misc::getIdentifier(p), p->getName(),
467 repository,
468 Reference<task::XAbortChannel>(), xCmdEnv );
469 }
470 }
471 }
472 }
473 else if (subCommand.equalsAsciiL(
474 RTL_CONSTASCII_STRINGPARAM("reinstall") ))
475 {
476 xExtensionManager->reinstallDeployedExtensions(
477 repository, Reference<task::XAbortChannel>(), xCmdEnv);
478 }
479 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("list") ))
480 {
481 ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
482 ::comphelper::sequenceToContainer(vecExtUnaccepted,
483 xExtensionManager->getExtensionsWithUnacceptedLicenses(
484 repository, xCmdEnv));
485
486 //This vector tells what XPackage in allExtensions has an
487 //unaccepted license.
488 std::vector<bool> vecUnaccepted;
489 std::vector<Reference<deployment::XPackage> > allExtensions;
490 if (cmdPackages.empty())
491 {
492 Sequence< Reference<deployment::XPackage> >
493 packages = xExtensionManager->getDeployedExtensions(
494 repository, Reference<task::XAbortChannel>(), xCmdEnv );
495
496 ::std::vector<Reference<deployment::XPackage> > vec_packages;
497 ::comphelper::sequenceToContainer(vec_packages, packages);
498
499 //First copy the extensions with the unaccepted license
500 //to vector allExtensions.
501 allExtensions.resize(vecExtUnaccepted.size() + vec_packages.size());
502
503 ::std::vector<Reference<deployment::XPackage> >::iterator i_all_ext =
504 ::std::copy(vecExtUnaccepted.begin(), vecExtUnaccepted.end(),
505 allExtensions.begin());
506 //Now copy those we got from getDeployedExtensions
507 ::std::copy(vec_packages.begin(), vec_packages.end(), i_all_ext);
508
509 //Now prepare the vector which tells what extension has an
510 //unaccepted license
511 vecUnaccepted.resize(vecExtUnaccepted.size() + vec_packages.size());
512 ::std::fill_n( vecUnaccepted.begin(), vecExtUnaccepted.size(), true);
513 std::vector<bool>::iterator i_unaccepted = vecUnaccepted.begin() + vecExtUnaccepted.size();
514 ::std::fill_n(i_unaccepted, vec_packages.size(), false);
515
516 dp_misc::writeConsole(
517 OUSTR("All deployed ") + repository + OUSTR(" extensions:\n\n"));
518 }
519 else
520 {
521 //The user provided the names (ids or file names) of the extensions
522 //which shall be listed
523 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
524 {
525 Reference<deployment::XPackage> extension;
526 try
527 {
528 extension = xExtensionManager->getDeployedExtension(
529 repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
530 }
531 catch (lang::IllegalArgumentException &)
532 {
533 extension = findPackage(repository,
534 xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
535 }
536
537 //Now look if the requested extension has an unaccepted license
538 bool bUnacceptedLic = false;
539 if (!extension.is())
540 {
541 ::std::vector<Reference<deployment::XPackage> >::const_iterator
542 i = ::std::find_if(
543 vecExtUnaccepted.begin(),
544 vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
545 if (i != vecExtUnaccepted.end())
546 {
547 extension = *i;
548 bUnacceptedLic = true;
549 }
550 }
551
552 if (extension.is())
553 {
554 allExtensions.push_back(extension);
555 vecUnaccepted.push_back(bUnacceptedLic);
556 }
557
558 else
559 throw lang::IllegalArgumentException(
560 OUSTR("There is no such extension deployed: ") +
561 cmdPackages[pos],0,-1);
562 }
563
564 }
565
566 printf_packages(allExtensions, vecUnaccepted, xCmdEnv );
567 }
568 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("validate") ))
569 {
570 ::std::vector<Reference<deployment::XPackage> > vecExtUnaccepted;
571 ::comphelper::sequenceToContainer(
572 vecExtUnaccepted, xExtensionManager->getExtensionsWithUnacceptedLicenses(
573 repository, xCmdEnv));
574
575 for ( ::std::size_t pos = 0; pos < cmdPackages.size(); ++pos )
576 {
577 Reference<deployment::XPackage> extension;
578 try
579 {
580 extension = xExtensionManager->getDeployedExtension(
581 repository, cmdPackages[ pos ], cmdPackages[ pos ], xCmdEnv );
582 }
583 catch (lang::IllegalArgumentException &)
584 {
585 extension = findPackage(
586 repository, xExtensionManager, xCmdEnv, cmdPackages[ pos ] );
587 }
588
589 if (!extension.is())
590 {
591 ::std::vector<Reference<deployment::XPackage> >::const_iterator
592 i = ::std::find_if(
593 vecExtUnaccepted.begin(),
594 vecExtUnaccepted.end(), ExtensionName(cmdPackages[pos]));
595 if (i != vecExtUnaccepted.end())
596 {
597 extension = *i;
598 }
599 }
600
601 if (extension.is())
602 xExtensionManager->checkPrerequisitesAndEnable(
603 extension, Reference<task::XAbortChannel>(), xCmdEnv);
604 }
605 }
606 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("gui") ))
607 {
608 Reference<ui::dialogs::XAsynchronousExecutableDialog> xDialog(
609 deployment::ui::PackageManagerDialog::createAndInstall(
610 xComponentContext,
611 cmdPackages.size() > 0 ? cmdPackages[0] : OUString() ));
612
613 osl::Condition dialogEnded;
614 dialogEnded.reset();
615
616 Reference< ui::dialogs::XDialogClosedListener > xListener(
617 new DialogClosedListenerImpl( dialogEnded ) );
618
619 xDialog->startExecuteModal(xListener);
620 dialogEnded.wait();
621 }
622 else if (subCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("sync")))
623 {
624 if (! dp_misc::office_is_running())
625 {
626 xExtensionManager->synchronizeBundledPrereg(
627 Reference<task::XAbortChannel>(), xCmdEnv);
628 }
629 else
630 {
631 dp_misc::writeConsoleError(OUSTR("\nError: office is running"));
632 }
633 }
634 else
635 {
636 dp_misc::writeConsoleError(
637 OUSTR("\nERROR: unknown sub-command ") +
638 subCommand +
639 OUSTR("!\n") +
640 OUSTR(" Use " APP_NAME " ") +
641 toString(info_help) +
642 OUSTR(" to print all options.\n"));
643 return 1;
644 }
645
646 if (option_verbose)
647 dp_misc::writeConsole( OUSTR( "\n" APP_NAME " done.\n"));
648 //Force to release all bridges which connect us to the child processes
649 disposeBridges(xLocalComponentContext);
650 return 0;
651 }
652 catch (ucb::CommandFailedException &e)
653 {
654 dp_misc::writeConsoleError(e.Message + OUSTR("\n"));
655 bNoOtherErrorMsg = true;
656 }
657 catch (ucb::CommandAbortedException &)
658 {
659 dp_misc::writeConsoleError( "\n" APP_NAME " aborted!\n");
660 }
661 catch (deployment::DeploymentException & exc)
662 {
663 OUString cause;
664 if (option_verbose)
665 {
666 cause = ::comphelper::anyToString(exc.Cause);
667 }
668 else
669 {
670 css::uno::Exception e;
671 if (exc.Cause >>= e)
672 cause = e.Message;
673 }
674
675 dp_misc::writeConsoleError(
676 OUSTR("\nERROR: ") + exc.Message + OUSTR("\n"));
677 if (cause.getLength())
678 dp_misc::writeConsoleError(
679 OUSTR(" Cause: ") + cause + OUSTR("\n"));
680 }
681 catch (LockFileException & e)
682 {
683 if (!subcmd_gui)
684 dp_misc::writeConsoleError(e.Message);
685 bNoOtherErrorMsg = true;
686 }
687 catch (::com::sun::star::uno::Exception & e ) {
688 Any exc( ::cppu::getCaughtException() );
689
690 dp_misc::writeConsoleError(
691 OUSTR("\nERROR: ") +
692 OUString(option_verbose ? e.Message + OUSTR("\nException details: \n") +
693 ::comphelper::anyToString(exc) : e.Message) +
694 OUSTR("\n"));
695 }
696 if (!bNoOtherErrorMsg)
697 dp_misc::writeConsoleError( "\n" APP_NAME " failed.\n");
698 disposeBridges(xLocalComponentContext);
699 return 1;
700 }
701