FileTypes.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Windows.Forms;
  7. namespace PaintDotNet
  8. {
  9. /// <summary>
  10. /// Provides static method and properties for obtaining all the FileType objects
  11. /// responsible for loading and saving Document instances. Loads FileType plugins
  12. /// too.
  13. /// </summary>
  14. internal sealed class FileTypes
  15. {
  16. private FileTypes()
  17. {
  18. }
  19. private static FileTypeCollection collection;
  20. public static FileTypeCollection GetFileTypes()
  21. {
  22. if (collection == null)
  23. {
  24. collection = LoadFileTypes();
  25. }
  26. return collection;
  27. }
  28. private static bool IsInterfaceImplemented(Type derivedType, Type interfaceType)
  29. {
  30. return -1 != Array.IndexOf<Type>(derivedType.GetInterfaces(), interfaceType);
  31. }
  32. private static Type[] GetFileTypeFactoriesFromAssembly(Assembly assembly)
  33. {
  34. List<Type> fileTypeFactories = new List<Type>();
  35. foreach (Type type in assembly.GetTypes())
  36. {
  37. if (IsInterfaceImplemented(type, typeof(IFileTypeFactory)) && !type.IsAbstract)
  38. {
  39. fileTypeFactories.Add(type);
  40. }
  41. }
  42. return fileTypeFactories.ToArray();
  43. }
  44. private static Type[] GetFileTypeFactoriesFromAssemblies(ICollection assemblies)
  45. {
  46. List<Type> allFactories = new List<Type>();
  47. foreach (Assembly assembly in assemblies)
  48. {
  49. Type[] factories;
  50. try
  51. {
  52. factories = GetFileTypeFactoriesFromAssembly(assembly);
  53. }
  54. catch (Exception)
  55. {
  56. continue;
  57. }
  58. foreach (Type type in factories)
  59. {
  60. allFactories.Add(type);
  61. }
  62. }
  63. return allFactories.ToArray();
  64. }
  65. private static FileTypeCollection LoadFileTypes()
  66. {
  67. List<Assembly> assemblies = new List<Assembly>();
  68. // add the built-in IFileTypeFactory house
  69. assemblies.Add(typeof(FileType).Assembly);
  70. // enumerate the assemblies inside the FileTypes directory
  71. string homeDir = Path.GetDirectoryName(Application.ExecutablePath);
  72. string fileTypesDir = Path.Combine(homeDir, "FileTypes");
  73. bool dirExists;
  74. try
  75. {
  76. DirectoryInfo dirInfo = new DirectoryInfo(fileTypesDir);
  77. dirExists = dirInfo.Exists;
  78. }
  79. catch (Exception)
  80. {
  81. dirExists = false;
  82. }
  83. if (dirExists)
  84. {
  85. foreach (string fileName in Directory.GetFiles(fileTypesDir, "*.dll"))
  86. {
  87. bool success;
  88. Assembly pluginAssembly = null;
  89. try
  90. {
  91. pluginAssembly = Assembly.LoadFrom(fileName);
  92. success = true;
  93. }
  94. catch (Exception)
  95. {
  96. success = false;
  97. }
  98. if (success)
  99. {
  100. assemblies.Add(pluginAssembly);
  101. }
  102. }
  103. }
  104. // Get all the IFileTypeFactory implementations
  105. Type[] fileTypeFactories = GetFileTypeFactoriesFromAssemblies(assemblies);
  106. List<FileType> allFileTypes = new List<FileType>(10);
  107. foreach (Type type in fileTypeFactories)
  108. {
  109. ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes);
  110. IFileTypeFactory factory;
  111. try
  112. {
  113. factory = (IFileTypeFactory)ci.Invoke(null);
  114. }
  115. catch (Exception)
  116. {
  117. #if DEBUG
  118. throw;
  119. #else
  120. continue;
  121. #endif
  122. }
  123. FileType[] fileTypes;
  124. try
  125. {
  126. fileTypes = factory.GetFileTypeInstances();
  127. }
  128. catch (Exception)
  129. {
  130. #if DEBUG
  131. throw;
  132. #else
  133. continue;
  134. #endif
  135. }
  136. if (fileTypes != null)
  137. {
  138. foreach (FileType fileType in fileTypes)
  139. {
  140. allFileTypes.Add(fileType);
  141. }
  142. }
  143. }
  144. return new FileTypeCollection(allFileTypes);
  145. }
  146. }
  147. }