1 // 2 // AddinManager.cs 3 // 4 // Author: 5 // Lluis Sanchez Gual 6 // 7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com) 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining 10 // a copy of this software and associated documentation files (the 11 // "Software"), to deal in the Software without restriction, including 12 // without limitation the rights to use, copy, modify, merge, publish, 13 // distribute, sublicense, and/or sell copies of the Software, and to 14 // permit persons to whom the Software is furnished to do so, subject to 15 // the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 // 28 29 using System; 30 using System.IO; 31 using System.Reflection; 32 using System.Collections; 33 using System.Collections.Generic; 34 35 using Mono.Addins.Localization; 36 37 namespace Mono.Addins 38 { 39 /// <summary> 40 /// Provides access to add-in and extension model management operations. 41 /// </summary> 42 public class AddinManager 43 { 44 static AddinEngine sessionService; 45 AddinManager()46 private AddinManager () 47 { 48 } 49 50 /// <summary> 51 /// Initializes the add-in engine. 52 /// </summary> 53 /// <remarks> 54 /// The add-in engine needs to be initialized before doing any add-in operation. 55 /// When initialized with this method, it will look for add-ins in the global add-in registry. 56 /// </remarks> Initialize()57 public static void Initialize () 58 { 59 // Code not shared with the other Initialize since I need to get the calling assembly 60 Assembly asm = Assembly.GetEntryAssembly (); 61 if (asm == null) asm = Assembly.GetCallingAssembly (); 62 AddinEngine.Initialize (asm, null, null, null); 63 } 64 65 /// <summary> 66 /// Initializes the add-in engine. 67 /// </summary> 68 /// <param name="configDir"> 69 /// Location of the add-in registry. 70 /// </param> 71 /// <remarks> 72 /// The add-in engine needs to be initialized before doing any add-in operation. 73 /// Configuration information about the add-in registry will be stored in the 74 /// provided location. The add-in engine will look for add-ins in an 'addins' 75 /// subdirectory of the provided directory. 76 /// 77 /// When specifying a path, it is possible to use a special folder name as root. 78 /// For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced 79 /// by the location of the Environment.SpecialFolder.Personal folder. Any value 80 /// of the Environment.SpecialFolder enumeration can be used (always between square 81 /// brackets) 82 /// </remarks> Initialize(string configDir)83 public static void Initialize (string configDir) 84 { 85 Assembly asm = Assembly.GetEntryAssembly (); 86 if (asm == null) asm = Assembly.GetCallingAssembly (); 87 AddinEngine.Initialize (asm, configDir, null, null); 88 } 89 90 /// <summary> 91 /// Initializes the add-in engine. 92 /// </summary> 93 /// <param name='configDir'> 94 /// Location of the add-in registry. 95 /// </param> 96 /// <param name='addinsDir'> 97 /// Add-ins directory. If the path is relative, it is considered to be relative 98 /// to the configDir directory. 99 /// </param> 100 /// <remarks> 101 /// The add-in engine needs to be initialized before doing any add-in operation. 102 /// Configuration information about the add-in registry will be stored in the 103 /// provided location. The add-in engine will look for add-ins in the provided 104 /// 'addinsDir' directory. 105 /// 106 /// When specifying a path, it is possible to use a special folder name as root. 107 /// For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced 108 /// by the location of the Environment.SpecialFolder.Personal folder. Any value 109 /// of the Environment.SpecialFolder enumeration can be used (always between square 110 /// brackets) 111 /// </remarks> Initialize(string configDir, string addinsDir)112 public static void Initialize (string configDir, string addinsDir) 113 { 114 Assembly asm = Assembly.GetEntryAssembly (); 115 if (asm == null) asm = Assembly.GetCallingAssembly (); 116 AddinEngine.Initialize (asm, configDir, addinsDir, null); 117 } 118 119 /// <summary> 120 /// Initializes the add-in engine. 121 /// </summary> 122 /// <param name='configDir'> 123 /// Location of the add-in registry. 124 /// </param> 125 /// <param name='addinsDir'> 126 /// Add-ins directory. If the path is relative, it is considered to be relative 127 /// to the configDir directory. 128 /// </param> 129 /// <param name='databaseDir'> 130 /// Location of the add-in database. If the path is relative, it is considered to be relative 131 /// to the configDir directory. 132 /// </param> 133 /// <remarks> 134 /// The add-in engine needs to be initialized before doing any add-in operation. 135 /// Configuration information about the add-in registry will be stored in the 136 /// provided location. The add-in engine will look for add-ins in the provided 137 /// 'addinsDir' directory. Cached information about add-ins will be stored in 138 /// the 'databaseDir' directory. 139 /// 140 /// When specifying a path, it is possible to use a special folder name as root. 141 /// For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced 142 /// by the location of the Environment.SpecialFolder.Personal folder. Any value 143 /// of the Environment.SpecialFolder enumeration can be used (always between square 144 /// brackets) 145 /// </remarks> Initialize(string configDir, string addinsDir, string databaseDir)146 public static void Initialize (string configDir, string addinsDir, string databaseDir) 147 { 148 Assembly asm = Assembly.GetEntryAssembly (); 149 if (asm == null) asm = Assembly.GetCallingAssembly (); 150 AddinEngine.Initialize (asm, configDir, addinsDir, databaseDir); 151 } 152 153 /// <summary> 154 /// Finalizes an add-in engine. 155 /// </summary> Shutdown()156 public static void Shutdown () 157 { 158 AddinEngine.Shutdown (); 159 } 160 161 /// <summary> 162 /// Sets the default localizer to be used for this add-in engine 163 /// </summary> 164 /// <param name="localizer"> 165 /// The add-in localizer 166 /// </param> InitializeDefaultLocalizer(IAddinLocalizer localizer)167 public static void InitializeDefaultLocalizer (IAddinLocalizer localizer) 168 { 169 AddinEngine.InitializeDefaultLocalizer (localizer); 170 } 171 172 internal static string StartupDirectory { 173 get { return AddinEngine.StartupDirectory; } 174 } 175 176 /// <summary> 177 /// Gets whether the add-in engine has been initialized. 178 /// </summary> 179 public static bool IsInitialized { 180 get { return AddinEngine.IsInitialized; } 181 } 182 183 /// <summary> 184 /// Gets the default add-in installer 185 /// </summary> 186 /// <remarks> 187 /// The default installer is used by the CheckInstalled method to request 188 /// the installation of missing add-ins. 189 /// </remarks> 190 public static IAddinInstaller DefaultInstaller { 191 get { return AddinEngine.DefaultInstaller; } 192 set { AddinEngine.DefaultInstaller = value; } 193 } 194 195 /// <summary> 196 /// Gets the default localizer for this add-in engine 197 /// </summary> 198 public static AddinLocalizer DefaultLocalizer { 199 get { 200 return AddinEngine.DefaultLocalizer; 201 } 202 } 203 204 /// <summary> 205 /// Gets the localizer for the add-in that is invoking this property 206 /// </summary> 207 public static AddinLocalizer CurrentLocalizer { 208 get { 209 AddinEngine.CheckInitialized (); 210 RuntimeAddin addin = AddinEngine.GetAddinForAssembly (Assembly.GetCallingAssembly ()); 211 if (addin != null) 212 return addin.Localizer; 213 else 214 return AddinEngine.DefaultLocalizer; 215 } 216 } 217 218 /// <summary> 219 /// Gets a reference to the RuntimeAddin object for the add-in that is invoking this property 220 /// </summary> 221 public static RuntimeAddin CurrentAddin { 222 get { 223 AddinEngine.CheckInitialized (); 224 return AddinEngine.GetAddinForAssembly (Assembly.GetCallingAssembly ()); 225 } 226 } 227 228 /// <summary> 229 /// Gets the default add-in engine 230 /// </summary> 231 public static AddinEngine AddinEngine { 232 get { 233 if (sessionService == null) 234 sessionService = new AddinEngine(); 235 236 return sessionService; 237 } 238 } 239 240 /// <summary> 241 /// Gets the add-in registry bound to the default add-in engine 242 /// </summary> 243 public static AddinRegistry Registry { 244 get { 245 return AddinEngine.Registry; 246 } 247 } 248 249 /// <summary> 250 /// Checks if the provided add-ins are installed, and requests the installation of those 251 /// which aren't. 252 /// </summary> 253 /// <param name="message"> 254 /// Message to show to the user when new add-ins have to be installed. 255 /// </param> 256 /// <param name="addinIds"> 257 /// List of IDs of the add-ins to be checked. 258 /// </param> 259 /// <remarks> 260 /// This method checks if the specified add-ins are installed. 261 /// If some of the add-ins are not installed, it will use 262 /// the installer assigned to the DefaultAddinInstaller property 263 /// to install them. If the installation fails, or if DefaultAddinInstaller 264 /// is not set, an exception will be thrown. 265 /// </remarks> CheckInstalled(string message, params string[] addinIds)266 public static void CheckInstalled (string message, params string[] addinIds) 267 { 268 AddinEngine.CheckInstalled (message, addinIds); 269 } 270 271 /// <summary> 272 /// Checks if an add-in has been loaded. 273 /// </summary> 274 /// <param name="id"> 275 /// Full identifier of the add-in. 276 /// </param> 277 /// <returns> 278 /// True if the add-in is loaded. 279 /// </returns> IsAddinLoaded(string id)280 public static bool IsAddinLoaded (string id) 281 { 282 return AddinEngine.IsAddinLoaded (id); 283 } 284 285 /// <summary> 286 /// Forces the loading of an add-in. 287 /// </summary> 288 /// <param name="statusMonitor"> 289 /// Status monitor to keep track of the loading process. 290 /// </param> 291 /// <param name="id"> 292 /// Full identifier of the add-in to load. 293 /// </param> 294 /// <remarks> 295 /// This method loads all assemblies that belong to an add-in in memory. 296 /// All add-ins on which the specified add-in depends will also be loaded. 297 /// Notice that in general add-ins don't need to be explicitly loaded using 298 /// this method, since the add-in engine will load them on demand. 299 /// </remarks> LoadAddin(IProgressStatus statusMonitor, string id)300 public static void LoadAddin (IProgressStatus statusMonitor, string id) 301 { 302 AddinEngine.LoadAddin (statusMonitor, id); 303 } 304 305 /// <summary> 306 /// Creates a new extension context. 307 /// </summary> 308 /// <returns> 309 /// The new extension context. 310 /// </returns> 311 /// <remarks> 312 /// Extension contexts can be used to query the extension model using particular condition values. 313 /// </remarks> CreateExtensionContext()314 public static ExtensionContext CreateExtensionContext () 315 { 316 return AddinEngine.CreateExtensionContext (); 317 } 318 319 /// <summary> 320 /// Returns the extension node in a path 321 /// </summary> 322 /// <param name="path"> 323 /// Location of the node. 324 /// </param> 325 /// <returns> 326 /// The node, or null if not found. 327 /// </returns> GetExtensionNode(string path)328 public static ExtensionNode GetExtensionNode (string path) 329 { 330 AddinEngine.CheckInitialized (); 331 return AddinEngine.GetExtensionNode (path); 332 } 333 334 /// <summary> 335 /// Returns the extension node in a path 336 /// </summary> 337 /// <param name="path"> 338 /// Location of the node. 339 /// </param> 340 /// <returns> 341 /// The node, or null if not found. 342 /// </returns> 343 public static T GetExtensionNode<T> (string path) where T:ExtensionNode 344 { 345 AddinEngine.CheckInitialized (); 346 return AddinEngine.GetExtensionNode<T> (path); 347 } 348 349 /// <summary> 350 /// Gets extension nodes registered in a path. 351 /// </summary> 352 /// <param name="path"> 353 /// An extension path.> 354 /// </param> 355 /// <returns> 356 /// All nodes registered in the provided path. 357 /// </returns> GetExtensionNodes(string path)358 public static ExtensionNodeList GetExtensionNodes (string path) 359 { 360 AddinEngine.CheckInitialized (); 361 return AddinEngine.GetExtensionNodes (path); 362 } 363 364 /// <summary> 365 /// Gets extension nodes registered in a path. 366 /// </summary> 367 /// <param name="path"> 368 /// An extension path. 369 /// </param> 370 /// <param name="expectedNodeType"> 371 /// Expected node type. 372 /// </param> 373 /// <returns> 374 /// A list of nodes 375 /// </returns> 376 /// <remarks> 377 /// This method returns all nodes registered under the provided path. 378 /// It will throw a InvalidOperationException if the type of one of 379 /// the registered nodes is not assignable to the provided type. 380 /// </remarks> GetExtensionNodes(string path, Type expectedNodeType)381 public static ExtensionNodeList GetExtensionNodes (string path, Type expectedNodeType) 382 { 383 AddinEngine.CheckInitialized (); 384 return AddinEngine.GetExtensionNodes (path, expectedNodeType); 385 } 386 387 /// <summary> 388 /// Gets extension nodes registered in a path. 389 /// </summary> 390 /// <param name="path"> 391 /// An extension path. 392 /// </param> 393 /// <returns> 394 /// A list of nodes 395 /// </returns> 396 /// <remarks> 397 /// This method returns all nodes registered under the provided path. 398 /// It will throw a InvalidOperationException if the type of one of 399 /// the registered nodes is not assignable to the provided type. 400 /// </remarks> 401 public static ExtensionNodeList<T> GetExtensionNodes<T> (string path) where T:ExtensionNode 402 { 403 AddinEngine.CheckInitialized (); 404 return AddinEngine.GetExtensionNodes<T> (path); 405 } 406 407 /// <summary> 408 /// Gets extension nodes for a type extension point 409 /// </summary> 410 /// <param name="instanceType"> 411 /// Type defining the extension point 412 /// </param> 413 /// <returns> 414 /// A list of nodes 415 /// </returns> 416 /// <remarks> 417 /// This method returns all extension nodes bound to the provided type. 418 /// </remarks> GetExtensionNodes(Type instanceType)419 public static ExtensionNodeList GetExtensionNodes (Type instanceType) 420 { 421 AddinEngine.CheckInitialized (); 422 return AddinEngine.GetExtensionNodes (instanceType); 423 } 424 425 /// <summary> 426 /// Gets extension nodes for a type extension point 427 /// </summary> 428 /// <param name="instanceType"> 429 /// Type defining the extension point 430 /// </param> 431 /// <param name="expectedNodeType"> 432 /// Expected extension node type 433 /// </param> 434 /// <returns> 435 /// A list of nodes 436 /// </returns> 437 /// <remarks> 438 /// This method returns all nodes registered for the provided type. 439 /// It will throw a InvalidOperationException if the type of one of 440 /// the registered nodes is not assignable to the provided node type. 441 /// </remarks> GetExtensionNodes(Type instanceType, Type expectedNodeType)442 public static ExtensionNodeList GetExtensionNodes (Type instanceType, Type expectedNodeType) 443 { 444 AddinEngine.CheckInitialized (); 445 return AddinEngine.GetExtensionNodes (instanceType, expectedNodeType); 446 } 447 448 /// <summary> 449 /// Gets extension nodes for a type extension point 450 /// </summary> 451 /// <param name="instanceType"> 452 /// Type defining the extension point 453 /// </param> 454 /// <returns> 455 /// A list of nodes 456 /// </returns> 457 /// <remarks> 458 /// This method returns all nodes registered for the provided type. 459 /// It will throw a InvalidOperationException if the type of one of 460 /// the registered nodes is not assignable to the specified node type argument. 461 /// </remarks> 462 public static ExtensionNodeList<T> GetExtensionNodes<T> (Type instanceType) where T: ExtensionNode 463 { 464 AddinEngine.CheckInitialized (); 465 return AddinEngine.GetExtensionNodes<T> (instanceType); 466 } 467 468 /// <summary> 469 /// Gets extension objects registered for a type extension point. 470 /// </summary> 471 /// <param name="instanceType"> 472 /// Type defining the extension point 473 /// </param> 474 /// <returns> 475 /// A list of objects 476 /// </returns> GetExtensionObjects(Type instanceType)477 public static object[] GetExtensionObjects (Type instanceType) 478 { 479 AddinEngine.CheckInitialized (); 480 return AddinEngine.GetExtensionObjects (instanceType); 481 } 482 483 /// <summary> 484 /// Gets extension objects registered for a type extension point. 485 /// </summary> 486 /// <returns> 487 /// A list of objects 488 /// </returns> 489 /// <remarks> 490 /// The type argument of this generic method is the type that defines 491 /// the extension point. 492 /// </remarks> GetExtensionObjects()493 public static T[] GetExtensionObjects<T> () 494 { 495 AddinEngine.CheckInitialized (); 496 return AddinEngine.GetExtensionObjects<T> (); 497 } 498 499 /// <summary> 500 /// Gets extension objects registered for a type extension point. 501 /// </summary> 502 /// <param name="instanceType"> 503 /// Type defining the extension point 504 /// </param> 505 /// <param name="reuseCachedInstance"> 506 /// When set to True, it will return instances created in previous calls. 507 /// </param> 508 /// <returns> 509 /// A list of extension objects. 510 /// </returns> GetExtensionObjects(Type instanceType, bool reuseCachedInstance)511 public static object[] GetExtensionObjects (Type instanceType, bool reuseCachedInstance) 512 { 513 AddinEngine.CheckInitialized (); 514 return AddinEngine.GetExtensionObjects (instanceType, reuseCachedInstance); 515 } 516 517 /// <summary> 518 /// Gets extension objects registered for a type extension point. 519 /// </summary> 520 /// <param name="reuseCachedInstance"> 521 /// When set to True, it will return instances created in previous calls. 522 /// </param> 523 /// <returns> 524 /// A list of extension objects. 525 /// </returns> 526 /// <remarks> 527 /// The type argument of this generic method is the type that defines 528 /// the extension point. 529 /// </remarks> GetExtensionObjects(bool reuseCachedInstance)530 public static T[] GetExtensionObjects<T> (bool reuseCachedInstance) 531 { 532 AddinEngine.CheckInitialized (); 533 return AddinEngine.GetExtensionObjects<T> (reuseCachedInstance); 534 } 535 536 /// <summary> 537 /// Gets extension objects registered in a path 538 /// </summary> 539 /// <param name="path"> 540 /// An extension path. 541 /// </param> 542 /// <returns> 543 /// An array of objects registered in the path. 544 /// </returns> 545 /// <remarks> 546 /// This method can only be used if all nodes in the provided extension path 547 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 548 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 549 /// method for each node. 550 /// </remarks> GetExtensionObjects(string path)551 public static object[] GetExtensionObjects (string path) 552 { 553 AddinEngine.CheckInitialized (); 554 return AddinEngine.GetExtensionObjects (path); 555 } 556 557 /// <summary> 558 /// Gets extension objects registered in a path. 559 /// </summary> 560 /// <param name="path"> 561 /// An extension path. 562 /// </param> 563 /// <param name="reuseCachedInstance"> 564 /// When set to True, it will return instances created in previous calls. 565 /// </param> 566 /// <returns> 567 /// An array of objects registered in the path. 568 /// </returns> 569 /// <remarks> 570 /// This method can only be used if all nodes in the provided extension path 571 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 572 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 573 /// method for each node (or TypeExtensionNode.GetInstance() if 574 /// reuseCachedInstance is set to true) 575 /// </remarks> GetExtensionObjects(string path, bool reuseCachedInstance)576 public static object[] GetExtensionObjects (string path, bool reuseCachedInstance) 577 { 578 AddinEngine.CheckInitialized (); 579 return AddinEngine.GetExtensionObjects (path, reuseCachedInstance); 580 } 581 582 /// <summary> 583 /// Gets extension objects registered in a path. 584 /// </summary> 585 /// <param name="path"> 586 /// An extension path. 587 /// </param> 588 /// <param name="arrayElementType"> 589 /// Type of the return array elements. 590 /// </param> 591 /// <returns> 592 /// An array of objects registered in the path. 593 /// </returns> 594 /// <remarks> 595 /// This method can only be used if all nodes in the provided extension path 596 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 597 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 598 /// method for each node. 599 /// 600 /// An InvalidOperationException exception is thrown if one of the found 601 /// objects is not a subclass of the provided type. 602 /// </remarks> GetExtensionObjects(string path, Type arrayElementType)603 public static object[] GetExtensionObjects (string path, Type arrayElementType) 604 { 605 AddinEngine.CheckInitialized (); 606 return AddinEngine.GetExtensionObjects (path, arrayElementType); 607 } 608 609 /// <summary> 610 /// Gets extension objects registered in a path. 611 /// </summary> 612 /// <param name="path"> 613 /// An extension path. 614 /// </param> 615 /// <returns> 616 /// An array of objects registered in the path. 617 /// </returns> 618 /// <remarks> 619 /// This method can only be used if all nodes in the provided extension path 620 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 621 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 622 /// method for each node. 623 /// 624 /// An InvalidOperationException exception is thrown if one of the found 625 /// objects is not a subclass of the provided type. 626 /// </remarks> GetExtensionObjects(string path)627 public static T[] GetExtensionObjects<T> (string path) 628 { 629 AddinEngine.CheckInitialized (); 630 return AddinEngine.GetExtensionObjects<T> (path); 631 } 632 633 /// <summary> 634 /// Gets extension objects registered in a path. 635 /// </summary> 636 /// <param name="path"> 637 /// An extension path. 638 /// </param> 639 /// <param name="arrayElementType"> 640 /// Type of the return array elements. 641 /// </param> 642 /// <param name="reuseCachedInstance"> 643 /// When set to True, it will return instances created in previous calls. 644 /// </param> 645 /// <returns> 646 /// An array of objects registered in the path. 647 /// </returns> 648 /// <remarks> 649 /// This method can only be used if all nodes in the provided extension path 650 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 651 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 652 /// method for each node (or TypeExtensionNode.GetInstance() if 653 /// reuseCachedInstance is set to true). 654 /// 655 /// An InvalidOperationException exception is thrown if one of the found 656 /// objects is not a subclass of the provided type. 657 /// </remarks> GetExtensionObjects(string path, Type arrayElementType, bool reuseCachedInstance)658 public static object[] GetExtensionObjects (string path, Type arrayElementType, bool reuseCachedInstance) 659 { 660 AddinEngine.CheckInitialized (); 661 return AddinEngine.GetExtensionObjects (path, arrayElementType, reuseCachedInstance); 662 } 663 664 /// <summary> 665 /// Gets extension objects registered in a path. 666 /// </summary> 667 /// <param name="path"> 668 /// An extension path. 669 /// </param> 670 /// <param name="reuseCachedInstance"> 671 /// When set to True, it will return instances created in previous calls. 672 /// </param> 673 /// <returns> 674 /// An array of objects registered in the path. 675 /// </returns> 676 /// <remarks> 677 /// This method can only be used if all nodes in the provided extension path 678 /// are of type Mono.Addins.TypeExtensionNode. The returned array is composed 679 /// by all objects created by calling the TypeExtensionNode.CreateInstance() 680 /// method for each node (or TypeExtensionNode.GetInstance() if 681 /// reuseCachedInstance is set to true). 682 /// 683 /// An InvalidOperationException exception is thrown if one of the found 684 /// objects is not a subclass of the provided type. 685 /// </remarks> GetExtensionObjects(string path, bool reuseCachedInstance)686 public static T[] GetExtensionObjects<T> (string path, bool reuseCachedInstance) 687 { 688 AddinEngine.CheckInitialized (); 689 return AddinEngine.GetExtensionObjects<T> (path, reuseCachedInstance); 690 } 691 692 /// <summary> 693 /// Extension change event. 694 /// </summary> 695 /// <remarks> 696 /// This event is fired when any extension point in the add-in system changes. 697 /// The event args object provides the path of the changed extension, although 698 /// it does not provide information about what changed. Hosts subscribing to 699 /// this event should get the new list of nodes using a query method such as 700 /// AddinManager.GetExtensionNodes() and then update whatever needs to be updated. 701 /// </remarks> 702 public static event ExtensionEventHandler ExtensionChanged { 703 add { AddinEngine.CheckInitialized(); AddinEngine.ExtensionChanged += value; } 704 remove { AddinEngine.CheckInitialized(); AddinEngine.ExtensionChanged -= value; } 705 } 706 707 /// <summary> 708 /// Register a listener of extension node changes. 709 /// </summary> 710 /// <param name="path"> 711 /// Path of the node. 712 /// </param> 713 /// <param name="handler"> 714 /// A handler method. 715 /// </param> 716 /// <remarks> 717 /// Hosts can call this method to be subscribed to an extension change 718 /// event for a specific path. The event will be fired once for every 719 /// individual node change. The event arguments include the change type 720 /// (Add or Remove) and the extension node added or removed. 721 /// 722 /// NOTE: The handler will be called for all nodes existing in the path at the moment of registration. 723 /// </remarks> AddExtensionNodeHandler(string path, ExtensionNodeEventHandler handler)724 public static void AddExtensionNodeHandler (string path, ExtensionNodeEventHandler handler) 725 { 726 AddinEngine.CheckInitialized (); 727 AddinEngine.AddExtensionNodeHandler (path, handler); 728 } 729 730 /// <summary> 731 /// Unregister a listener of extension node changes. 732 /// </summary> 733 /// <param name="path"> 734 /// Path of the node. 735 /// </param> 736 /// <param name="handler"> 737 /// A handler method. 738 /// </param> 739 /// <remarks> 740 /// This method unregisters a delegate from the node change event of a path. 741 /// </remarks> RemoveExtensionNodeHandler(string path, ExtensionNodeEventHandler handler)742 public static void RemoveExtensionNodeHandler (string path, ExtensionNodeEventHandler handler) 743 { 744 AddinEngine.CheckInitialized (); 745 AddinEngine.RemoveExtensionNodeHandler (path, handler); 746 } 747 748 /// <summary> 749 /// Register a listener of extension node changes. 750 /// </summary> 751 /// <param name="instanceType"> 752 /// Type defining the extension point 753 /// </param> 754 /// <param name="handler"> 755 /// A handler method. 756 /// </param> 757 /// <remarks> 758 /// Hosts can call this method to be subscribed to an extension change 759 /// event for a specific type extension point. The event will be fired once for every 760 /// individual node change. The event arguments include the change type 761 /// (Add or Remove) and the extension node added or removed. 762 /// 763 /// NOTE: The handler will be called for all nodes existing in the path at the moment of registration. 764 /// </remarks> AddExtensionNodeHandler(Type instanceType, ExtensionNodeEventHandler handler)765 public static void AddExtensionNodeHandler (Type instanceType, ExtensionNodeEventHandler handler) 766 { 767 AddinEngine.CheckInitialized (); 768 AddinEngine.AddExtensionNodeHandler (instanceType, handler); 769 } 770 771 /// <summary> 772 /// Unregister a listener of extension node changes. 773 /// </summary> 774 /// <param name="instanceType"> 775 /// Type defining the extension point 776 /// </param> 777 /// <param name="handler"> 778 /// A handler method. 779 /// </param> RemoveExtensionNodeHandler(Type instanceType, ExtensionNodeEventHandler handler)780 public static void RemoveExtensionNodeHandler (Type instanceType, ExtensionNodeEventHandler handler) 781 { 782 AddinEngine.CheckInitialized (); 783 AddinEngine.RemoveExtensionNodeHandler (instanceType, handler); 784 } 785 786 /// <summary> 787 /// Add-in loading error event. 788 /// </summary> 789 /// <remarks> 790 /// This event is fired when there is an error when loading the extension 791 /// of an add-in, or any other kind of error that may happen when querying extension points. 792 /// </remarks> 793 public static event AddinErrorEventHandler AddinLoadError { 794 add { AddinEngine.AddinLoadError += value; } 795 remove { AddinEngine.AddinLoadError -= value; } 796 } 797 798 /// <summary> 799 /// Add-in loaded event. 800 /// </summary> 801 /// <remarks> 802 /// Fired after loading an add-in in memory. 803 /// </remarks> 804 public static event AddinEventHandler AddinLoaded { 805 add { AddinEngine.AddinLoaded += value; } 806 remove { AddinEngine.AddinLoaded -= value; } 807 } 808 809 /// <summary> 810 /// Add-in unload event. 811 /// </summary> 812 /// <remarks> 813 /// Fired when an add-in is unloaded from memory. It may happen an add-in is disabled or uninstalled. 814 /// </remarks> 815 public static event AddinEventHandler AddinUnloaded { 816 add { AddinEngine.AddinUnloaded += value; } 817 remove { AddinEngine.AddinUnloaded -= value; } 818 } 819 CheckAssembliesLoaded(HashSet<string> files)820 internal static bool CheckAssembliesLoaded (HashSet<string> files) 821 { 822 foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ()) { 823 if (asm is System.Reflection.Emit.AssemblyBuilder) 824 continue; 825 try { 826 Uri u; 827 if (!Uri.TryCreate (asm.CodeBase, UriKind.Absolute, out u)) 828 continue; 829 string asmFile = u.LocalPath; 830 if (files.Contains (Path.GetFullPath (asmFile))) 831 return true; 832 } catch { 833 // Ignore 834 } 835 } 836 return false; 837 } 838 } 839 840 } 841