using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Windows.Forms; namespace PaintDotNet { /// /// Provides static method and properties for obtaining all the FileType objects /// responsible for loading and saving Document instances. Loads FileType plugins /// too. /// internal sealed class FileTypes { private FileTypes() { } private static FileTypeCollection collection; public static FileTypeCollection GetFileTypes() { if (collection == null) { collection = LoadFileTypes(); } return collection; } private static bool IsInterfaceImplemented(Type derivedType, Type interfaceType) { return -1 != Array.IndexOf(derivedType.GetInterfaces(), interfaceType); } private static Type[] GetFileTypeFactoriesFromAssembly(Assembly assembly) { List fileTypeFactories = new List(); foreach (Type type in assembly.GetTypes()) { if (IsInterfaceImplemented(type, typeof(IFileTypeFactory)) && !type.IsAbstract) { fileTypeFactories.Add(type); } } return fileTypeFactories.ToArray(); } private static Type[] GetFileTypeFactoriesFromAssemblies(ICollection assemblies) { List allFactories = new List(); foreach (Assembly assembly in assemblies) { Type[] factories; try { factories = GetFileTypeFactoriesFromAssembly(assembly); } catch (Exception) { continue; } foreach (Type type in factories) { allFactories.Add(type); } } return allFactories.ToArray(); } private static FileTypeCollection LoadFileTypes() { List assemblies = new List(); // add the built-in IFileTypeFactory house assemblies.Add(typeof(FileType).Assembly); // enumerate the assemblies inside the FileTypes directory string homeDir = Path.GetDirectoryName(Application.ExecutablePath); string fileTypesDir = Path.Combine(homeDir, "FileTypes"); bool dirExists; try { DirectoryInfo dirInfo = new DirectoryInfo(fileTypesDir); dirExists = dirInfo.Exists; } catch (Exception) { dirExists = false; } if (dirExists) { foreach (string fileName in Directory.GetFiles(fileTypesDir, "*.dll")) { bool success; Assembly pluginAssembly = null; try { pluginAssembly = Assembly.LoadFrom(fileName); success = true; } catch (Exception) { success = false; } if (success) { assemblies.Add(pluginAssembly); } } } // Get all the IFileTypeFactory implementations Type[] fileTypeFactories = GetFileTypeFactoriesFromAssemblies(assemblies); List allFileTypes = new List(10); foreach (Type type in fileTypeFactories) { ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes); IFileTypeFactory factory; try { factory = (IFileTypeFactory)ci.Invoke(null); } catch (Exception) { #if DEBUG throw; #else continue; #endif } FileType[] fileTypes; try { fileTypes = factory.GetFileTypeInstances(); } catch (Exception) { #if DEBUG throw; #else continue; #endif } if (fileTypes != null) { foreach (FileType fileType in fileTypes) { allFileTypes.Add(fileType); } } } return new FileTypeCollection(allFileTypes); } } }