Changeset 2481 for branches/PluginInfrastructure Refactoring
- Timestamp:
- 11/11/09 18:25:15 (15 years ago)
- Location:
- branches/PluginInfrastructure Refactoring
- Files:
-
- 5 added
- 19 edited
- 9 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager
- Property svn:ignore
-
old new 1 1 bin 2 2 obj 3 HeuristicLab.PluginInfrastructure.Manager.csproj.user
-
- Property svn:ignore
-
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs
r2472 r2481 24 24 using System.Text; 25 25 26 namespace HeuristicLab.PluginInfrastructure {26 namespace HeuristicLab.PluginInfrastructure.Manager { 27 27 /// <summary> 28 28 /// Class that provides information about an application. 29 29 /// </summary> 30 30 [Serializable] 31 public class Application Info{31 public class ApplicationDescription { 32 32 private string name; 33 33 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj
r2475 r2481 6 6 <ProductVersion>9.0.30729</ProductVersion> 7 7 <SchemaVersion>2.0</SchemaVersion> 8 <ProjectGuid> a687a63d-d039-4b62-9de0-71f8ef480e57</ProjectGuid>8 <ProjectGuid>{CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}</ProjectGuid> 9 9 <OutputType>Library</OutputType> 10 10 <AppDesignerFolder>Properties</AppDesignerFolder> … … 13 13 <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> 14 14 <FileAlignment>512</FileAlignment> 15 <SignAssembly>true</SignAssembly> 16 <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile> 15 17 </PropertyGroup> 16 18 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> … … 46 48 </ItemGroup> 47 49 <ItemGroup> 48 <Compile Include="Class1.cs" /> 50 <Compile Include="ApplicationDescription.cs" /> 51 <Compile Include="PluginDescriptionIterator.cs" /> 52 <Compile Include="Loader.cs" /> 53 <Compile Include="PluginState.cs" /> 54 <Compile Include="PluginDescription.cs" /> 55 <Compile Include="PluginManager.cs" /> 56 <Compile Include="PluginManagerActionEventArgs.cs" /> 49 57 <Compile Include="Properties\AssemblyInfo.cs" /> 58 <Compile Include="Runner.cs" /> 59 </ItemGroup> 60 <ItemGroup> 61 <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj"> 62 <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project> 63 <Name>HeuristicLab.PluginInfrastructure</Name> 64 </ProjectReference> 65 </ItemGroup> 66 <ItemGroup> 67 <None Include="HeuristicLab.snk" /> 50 68 </ItemGroup> 51 69 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs
r2475 r2481 26 26 using System.IO; 27 27 using System.Diagnostics; 28 using System.Windows.Forms; 29 30 namespace HeuristicLab.PluginInfrastructure { 28 using System.Linq; 29 30 31 namespace HeuristicLab.PluginInfrastructure.Manager { 31 32 internal class Loader : MarshalByRefObject { 32 /// <summary>33 /// Event handler for loaded plugins.34 /// </summary>35 /// <param name="pluginName">The plugin that has been loaded.</param>36 public delegate void PluginLoadedEventHandler(string pluginName);37 38 public delegate void PluginLoadFailedEventHandler(string pluginName, string args);39 40 private Dictionary<PluginInfo, List<string>> pluginDependencies = new Dictionary<PluginInfo, List<string>>();41 private List<PluginInfo> preloadedPluginInfos = new List<PluginInfo>();42 private Dictionary<IPlugin, PluginInfo> pluginInfos = new Dictionary<IPlugin, PluginInfo>();43 private Dictionary<PluginInfo, IPlugin> allPlugins = new Dictionary<PluginInfo, IPlugin>();44 private List<PluginInfo> disabledPlugins = new List<PluginInfo>();45 private string pluginDir = Application.StartupPath + "/" + HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir;46 47 internal event PluginLoadFailedEventHandler MissingPluginFile;48 33 internal event PluginManagerActionEventHandler PluginAction; 49 34 50 internal ICollection<PluginInfo> ActivePlugins { 51 get { 52 List<PluginInfo> list = new List<PluginInfo>(); 53 foreach (PluginInfo info in allPlugins.Keys) { 54 if (!disabledPlugins.Exists(delegate(PluginInfo disabledInfo) { return info.Name == disabledInfo.Name; })) { 55 list.Add(info); 56 } 57 } 58 return list; 59 } 60 } 61 62 internal ICollection<PluginInfo> InstalledPlugins { 63 get { 64 return new List<PluginInfo>(allPlugins.Keys); 65 } 66 } 67 68 internal ICollection<PluginInfo> DisabledPlugins { 69 get { 70 return disabledPlugins; 71 } 72 } 73 74 private ICollection<ApplicationInfo> applications; 75 internal ICollection<ApplicationInfo> InstalledApplications { 35 private Dictionary<PluginDescription, List<string>> pluginDependencies; 36 37 private List<ApplicationDescription> applications; 38 internal IEnumerable<ApplicationDescription> Applications { 76 39 get { 77 40 return applications; … … 79 42 } 80 43 81 private IPlugin FindPlugin(PluginInfo plugin) { 82 if (allPlugins.ContainsKey(plugin)) { 83 return allPlugins[plugin]; 84 } else return null; 44 private IEnumerable<PluginDescription> plugins; 45 internal IEnumerable<PluginDescription> Plugins { 46 get { 47 return plugins; 48 } 49 } 50 51 public string PluginDir { get; set; } 52 53 public Loader() { 54 this.applications = new List<ApplicationDescription>(); 55 this.plugins = new List<PluginDescription>(); 56 this.pluginDependencies = new Dictionary<PluginDescription, List<string>>(); 85 57 } 86 58 … … 89 61 /// Init first clears all internal datastructures (including plugin lists) 90 62 /// 1. All assemblies in the plugins directory are loaded into the reflection only context. 91 /// 2. The loader checks if all dependencies for each assembly are available. 92 /// 3. All assemblies for which there are no dependencies missing are loaded into the execution context. 93 /// 4. Each loaded assembly is searched for a type that implements IPlugin, then one instance of each IPlugin type is activated 94 /// 5. The loader checks if all necessary files for each plugin are available. 95 /// 6. The loader builds an acyclic graph of PluginDescriptions (childs are dependencies of a plugin) based on the 96 /// list of assemblies of an plugin and the list of dependencies for each of those assemblies 63 /// 2. The loader checks if all necessary files for each plugin are available. 64 /// 3. The loaded builds the tree of plugin descriptions (dependencies) 65 /// 4. The loader checks if all dependencies for each plugin are ok. 66 /// 5. All plugins for which there are no dependencies missing are loaded into the execution context. 67 /// 6. Each loaded plugin (all assemblies) is searched for a types that implement IPlugin 68 /// then one instance of each IPlugin type is activated and the OnLoad hook is called. 69 /// 7. All types implementing IApplication are discovered 97 70 /// </summary> 98 /// <exception cref="FileLoadException">Thrown when the file could not be loaded.</exception>99 71 internal void Init() { 100 AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += delegate(object sender, ResolveEventArgs args) { 101 try { 102 return Assembly.ReflectionOnlyLoad(args.Name); 103 } 104 catch (FileLoadException ex) { 105 return null; 106 } 107 }; 108 allPlugins.Clear(); 109 disabledPlugins.Clear(); 110 pluginInfos.Clear(); 111 pluginsByName.Clear(); 72 //AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += delegate(object sender, ResolveEventArgs args) { 73 // try { 74 // return Assembly.ReflectionOnlyLoad(args.Name); 75 // } 76 // catch (FileLoadException ex) { 77 // return null; 78 // } 79 //}; 112 80 pluginDependencies.Clear(); 113 81 114 List<Assembly> assemblies = ReflectionOnlyLoadDlls(); 115 CheckAssemblyDependencies(assemblies); 116 CheckPluginFiles(); 117 CheckPluginDependencies(); 118 LoadPlugins(); 119 82 IEnumerable<Assembly> reflectionOnlyAssemblies = ReflectionOnlyLoadDlls(); 83 IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(reflectionOnlyAssemblies); 84 CheckPluginFiles(pluginDescriptions); 85 86 // a full list of plugin descriptions is available now we can build the dependency tree 87 BuildDependencyTree(pluginDescriptions); 88 89 // recursively check if all necessary plugins are available and not disabled 90 // disable plugins with missing or disabled dependencies 91 CheckPluginDependencies(pluginDescriptions); 92 93 // test full loading (in contrast to reflection only loading) of plugins 94 // disables plugins that are not loaded correctly 95 LoadPlugins(pluginDescriptions); 96 97 plugins = pluginDescriptions; 98 DiscoverApplications(); 99 } 100 101 private void DiscoverApplications() { 120 102 DiscoveryService service = new DiscoveryService(); 121 103 IApplication[] apps = service.GetInstances<IApplication>(); 122 applications = new List<Application Info>();104 applications = new List<ApplicationDescription>(); 123 105 124 106 foreach (IApplication application in apps) { 125 Application Info info = new ApplicationInfo();107 ApplicationDescription info = new ApplicationDescription(); 126 108 info.Name = application.Name; 127 109 info.Version = application.Version; … … 135 117 } 136 118 137 private List<Assembly> ReflectionOnlyLoadDlls() {119 private IEnumerable<Assembly> ReflectionOnlyLoadDlls() { 138 120 List<Assembly> assemblies = new List<Assembly>(); 139 // load all installed pluginsinto the reflection only context140 foreach ( String filename in Directory.GetFiles(pluginDir, "*.dll")) {121 // try to load each .dll file in the plugin directory into the reflection only context 122 foreach (string filename in Directory.GetFiles(PluginDir, "*.dll")) { 141 123 try { 142 assemblies.Add( ReflectionOnlyLoadDll(filename));124 assemblies.Add(Assembly.ReflectionOnlyLoadFrom(filename)); 143 125 } 144 126 catch (BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll … … 147 129 } 148 130 149 private Assembly ReflectionOnlyLoadDll(string filename) {150 return Assembly.ReflectionOnlyLoadFrom(filename);151 }152 153 private void CheckAssemblyDependencies(List<Assembly> assemblies) {131 // find all types implementing IPlugin in the reflectionOnlyAssemblies and create a list of plugin descriptions 132 // the dependencies in the plugin descriptions are not yet set correctly because we need to create 133 // the full list of all plugin descriptions first 134 private IEnumerable<PluginDescription> GatherPluginDescriptions(IEnumerable<Assembly> assemblies) { 135 List<PluginDescription> pluginDescriptions = new List<PluginDescription>(); 154 136 foreach (Assembly assembly in assemblies) { 155 137 // GetExportedTypes throws FileNotFoundException when a referenced assembly 156 138 // of the current assembly is missing. 157 139 try { 158 Type[] exported = assembly.GetExportedTypes(); 159 160 foreach (Type t in exported) { 140 foreach (Type t in assembly.GetExportedTypes()) { 161 141 // if there is a type that implements IPlugin 162 if (! t.IsAbstract && Array.Exists<Type>(t.GetInterfaces(), delegate(Type iface) { 163 // use AssemblyQualifiedName to compare the types because we can't directly 164 // compare ReflectionOnly types and Execution types 165 return iface.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName; 166 })) { 142 // use AssemblyQualifiedName to compare the types because we can't directly 143 // compare ReflectionOnly types and Execution types 144 if (!t.IsAbstract && 145 t.GetInterfaces().Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)) { 167 146 // fetch the attributes of the IPlugin type 168 GetPluginAttributeData(t);147 pluginDescriptions.Add(GetPluginDescription(t)); 169 148 } 170 149 } 171 150 } 172 151 catch (FileNotFoundException ex) { 173 PluginInfo info = new PluginInfo();174 AssemblyName name = assembly.GetName();175 info.Name = name.Name;176 info.Version = name.Version;177 info.Assemblies.Add(assembly.FullName);178 info.Files.Add(assembly.Location);179 info.Message = "File not found: " + ex.FileName;180 disabledPlugins.Add(info);152 //PluginDescription info = new PluginDescription(); 153 //AssemblyName name = assembly.GetName(); 154 //info.Name = name.Name; 155 //info.Version = name.Version; 156 //info.Assemblies.Add(assembly.FullName); 157 //info.Files.Add(assembly.Location); 158 //info.Message = "File not found: " + ex.FileName; 159 //disabledPlugins.Add(info); 181 160 } 182 161 catch (FileLoadException ex) { 183 PluginInfo info = new PluginInfo();184 AssemblyName name = assembly.GetName();185 info.Name = name.Name;186 info.Version = name.Version;187 info.Files.Add(assembly.Location);188 info.Assemblies.Add(assembly.FullName);189 info.Message = "Couldn't load file: " + ex.FileName;190 disabledPlugins.Add(info);162 //PluginDescription info = new PluginDescription(); 163 //AssemblyName name = assembly.GetName(); 164 //info.Name = name.Name; 165 //info.Version = name.Version; 166 //info.Files.Add(assembly.Location); 167 //info.Assemblies.Add(assembly.FullName); 168 //info.Message = "Couldn't load file: " + ex.FileName; 169 //disabledPlugins.Add(info); 191 170 } 192 171 catch (InvalidPluginException ex) { 193 PluginInfo info = new PluginInfo(); 194 AssemblyName name = assembly.GetName(); 195 info.Name = name.Name; 196 info.Version = name.Version; 197 info.Files.Add(assembly.Location); 198 info.Assemblies.Add(assembly.FullName); 199 info.Message = "Couldn't load plugin class from assembly: " + assembly.GetName().Name+". Necessary plugin attributes are missing."; 200 disabledPlugins.Add(info); 201 } 202 } 172 //PluginDescription info = new PluginDescription(); 173 //AssemblyName name = assembly.GetName(); 174 //info.Name = name.Name; 175 //info.Version = name.Version; 176 //info.Files.Add(assembly.Location); 177 //info.Assemblies.Add(assembly.FullName); 178 //info.Message = "Couldn't load plugin class from assembly: " + assembly.GetName().Name + ". Necessary plugin attributes are missing."; 179 //disabledPlugins.Add(info); 180 } 181 } 182 return pluginDescriptions; 203 183 } 204 184 … … 209 189 /// </summary> 210 190 /// <param name="t"></param> 211 private void GetPluginAttributeData(Type t) {191 private PluginDescription GetPluginDescription(Type pluginType) { 212 192 // get all attributes of that type 213 IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes( t);193 IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(pluginType); 214 194 List<string> pluginAssemblies = new List<string>(); 215 195 List<string> pluginDependencies = new List<string>(); 216 196 List<string> pluginFiles = new List<string>(); 217 string pluginName = "";218 // iterate through all custom attributes and search for named argumentsthat we are interested in197 string pluginName = null; 198 // iterate through all custom attributes and search for attributed that we are interested in 219 199 foreach (CustomAttributeData attributeData in attributes) { 220 List<CustomAttributeNamedArgument> namedArguments = new List<CustomAttributeNamedArgument>(attributeData.NamedArguments); 221 // if the current attribute contains a named argument with the name "Name" then extract the plugin name 222 CustomAttributeNamedArgument pluginNameArgument = namedArguments.Find(delegate(CustomAttributeNamedArgument arg) { 223 return arg.MemberInfo.Name == "Name"; 224 }); 225 if (pluginNameArgument.MemberInfo != null) { 226 pluginName = (string)pluginNameArgument.TypedValue.Value; 227 } 228 // if the current attribute contains a named argument with the name "Dependency" then extract the dependency 229 // and store it in the list of all dependencies 230 CustomAttributeNamedArgument dependencyNameArgument = namedArguments.Find(delegate(CustomAttributeNamedArgument arg) { 231 return arg.MemberInfo.Name == "Dependency"; 232 }); 233 if (dependencyNameArgument.MemberInfo != null) { 234 pluginDependencies.Add((string)dependencyNameArgument.TypedValue.Value); 235 } 236 // if the current attribute has a named argument "Filename" then find if the argument "Filetype" is also supplied 237 // and if the filetype is Assembly then store the name of the assembly in the list of assemblies 238 CustomAttributeNamedArgument filenameArg = namedArguments.Find(delegate(CustomAttributeNamedArgument arg) { 239 return arg.MemberInfo.Name == "Filename"; 240 }); 241 CustomAttributeNamedArgument filetypeArg = namedArguments.Find(delegate(CustomAttributeNamedArgument arg) { 242 return arg.MemberInfo.Name == "Filetype"; 243 }); 244 if (filenameArg.MemberInfo != null && filetypeArg.MemberInfo != null) { 245 pluginFiles.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value); 246 if ((PluginFileType)filetypeArg.TypedValue.Value == PluginFileType.Assembly) { 247 pluginAssemblies.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value); 200 if (IsAttributeDataForType(attributeData, typeof(PluginDescriptionAttribute))) { 201 pluginName = (string)attributeData.ConstructorArguments[0].Value; 202 } else if (IsAttributeDataForType(attributeData, typeof(PluginDependencyAttribute))) { 203 pluginDependencies.Add((string)attributeData.ConstructorArguments[0].Value); 204 } else if (IsAttributeDataForType(attributeData, typeof(PluginFileAttribute))) { 205 string pluginFileName = (string)attributeData.ConstructorArguments[0].Value; 206 PluginFileType fileType = (PluginFileType)attributeData.ConstructorArguments[1].Value; 207 pluginFiles.Add(PluginDir + "/" + pluginFileName); 208 if (fileType == PluginFileType.Assembly) { 209 pluginAssemblies.Add(PluginDir + "/" + pluginFileName); 248 210 } 249 211 } … … 251 213 252 214 // minimal sanity check of the attribute values 253 if (pluginName != "" && pluginAssemblies.Count > 0) { 254 // create a temporary PluginInfo that contains the attribute values 255 PluginInfo info = new PluginInfo(); 215 if (!string.IsNullOrEmpty(pluginName) && 216 pluginFiles.Count > 0 && 217 pluginAssemblies.Count > 0) { 218 // create a temporary PluginDescription that contains the attribute values 219 PluginDescription info = new PluginDescription(); 256 220 info.Name = pluginName; 257 info.Version = t.Assembly.GetName().Version; 258 info.Assemblies = pluginAssemblies; 259 info.Files.AddRange(pluginFiles); 221 info.Version = pluginType.Assembly.GetName().Version; 222 info.AddAssemblies(pluginAssemblies); 223 info.AddFiles(pluginFiles); 224 info.PluginState = PluginState.Undefined; 225 260 226 this.pluginDependencies[info] = pluginDependencies; 261 preloadedPluginInfos.Add(info);227 return info; 262 228 } else { 263 throw new InvalidPluginException(); 264 } 265 } 266 267 private void CheckPluginDependencies() { 268 foreach (PluginInfo pluginInfo in preloadedPluginInfos) { 269 // don't need to check plugins that are already disabled 270 if (disabledPlugins.Contains(pluginInfo)) { 271 continue; 272 } 273 visitedDependencies.Clear(); 274 if (!CheckPluginDependencies(pluginInfo.Name)) { 275 PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginInfo.Name; }); 276 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen 277 foreach (string dependency in pluginDependencies[matchingInfo]) { 278 PluginInfo dependencyInfo = new PluginInfo(); 279 dependencyInfo.Name = dependency; 280 pluginInfo.Dependencies.Add(dependencyInfo); 281 } 282 283 pluginInfo.Message = "Disabled: missing plugin dependency."; 284 disabledPlugins.Add(pluginInfo); 285 } 286 } 287 } 288 289 private List<string> visitedDependencies = new List<string>(); 290 private bool CheckPluginDependencies(string pluginName) { 291 if (!preloadedPluginInfos.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) || 292 disabledPlugins.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) || 293 visitedDependencies.Contains(pluginName)) { 294 // when the plugin is not available return false; 295 return false; 296 } else { 297 // otherwise check if all dependencies of the plugin are OK 298 // if yes then this plugin is also ok and we store it in the list of loadable plugins 299 300 PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginName; }); 301 if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen 302 foreach (string dependency in pluginDependencies[matchingInfo]) { 303 visitedDependencies.Add(pluginName); 304 if (CheckPluginDependencies(dependency) == false) { 305 // if only one dependency is not available that means that the current plugin also is unloadable 306 return false; 307 } 308 visitedDependencies.Remove(pluginName); 309 } 310 // all dependencies OK 311 return true; 312 } 313 } 314 315 316 private Dictionary<string, IPlugin> pluginsByName = new Dictionary<string, IPlugin>(); 317 private void LoadPlugins() { 229 throw new InvalidPluginException("Invalid metadata in plugin " + pluginType.ToString()); 230 } 231 } 232 233 private bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) { 234 return attributeData.Constructor.DeclaringType.AssemblyQualifiedName == attributeType.AssemblyQualifiedName; 235 } 236 237 // builds a dependency tree of all plugin descriptions 238 // searches matching plugin descriptions based on the list of dependency names for each plugin 239 // and sets the dependencies in the plugin descriptions 240 private void BuildDependencyTree(IEnumerable<PluginDescription> pluginDescriptions) { 241 foreach (var desc in pluginDescriptions) { 242 foreach (string pluginName in pluginDependencies[desc]) { 243 var matchingDescriptions = pluginDescriptions.Where(x => x.Name == pluginName); 244 if (matchingDescriptions.Count() > 0) { 245 desc.AddDependency(matchingDescriptions.First()); 246 } else { 247 // no plugin description that matches the dependency name is available => plugin is disabled 248 desc.PluginState = PluginState.Disabled; 249 break; // stop processing more dependencies 250 } 251 } 252 } 253 } 254 255 private void CheckPluginDependencies(IEnumerable<PluginDescription> pluginDescriptions) { 256 foreach (PluginDescription pluginDescription in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) { 257 if (IsAnyDependencyDisabled(pluginDescription)) { 258 // PluginDescription.Message = "Disabled: missing plugin dependency."; 259 pluginDescription.PluginState = PluginState.Disabled; 260 } 261 } 262 } 263 264 265 private bool IsAnyDependencyDisabled(PluginDescription descr) { 266 if (descr.PluginState == PluginState.Disabled) return true; 267 foreach (PluginDescription dependency in descr.Dependencies) { 268 if (IsAnyDependencyDisabled(dependency)) return true; 269 } 270 return false; 271 } 272 273 private void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) { 318 274 // load all loadable plugins (all dependencies available) into the execution context 319 foreach (PluginInfo pluginInfo in preloadedPluginInfos) { 320 if (!disabledPlugins.Contains(pluginInfo)) { 321 foreach (string assembly in pluginInfo.Assemblies) { 322 Assembly.LoadFrom(assembly); 323 } 324 } 325 } 326 327 Queue<IPlugin> pluginsToLoad = new Queue<IPlugin>(); 328 DiscoveryService service = new DiscoveryService(); 329 // now search and instantiate an IPlugin type in each loaded assembly 330 // and prepare the queue to load all plugins 331 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { 332 // don't search for plugins in the PluginInfrastructure 333 if (assembly == this.GetType().Assembly) 334 continue; 335 Type[] availablePluginTypes = service.GetTypes(typeof(IPlugin), assembly); 336 foreach (Type pluginType in availablePluginTypes) { 275 foreach (PluginDescription desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) { 276 List<Type> types = new List<Type>(); 277 foreach (string assembly in desc.Assemblies) { 278 var asm = Assembly.LoadFrom(assembly); 279 foreach (Type t in asm.GetTypes()) { 280 if (typeof(IPlugin).IsAssignableFrom(t)) { 281 types.Add(t); 282 } 283 } 284 } 285 286 foreach (Type pluginType in types) { 337 287 if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) { 338 288 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); 339 pluginsToLoad.Enqueue(plugin); 340 pluginsByName.Add(plugin.Name, plugin); 341 } 342 } 343 } 344 345 // load all plugins respecting their dependencies 346 while (pluginsToLoad.Count > 0) { 347 IPlugin plugin = pluginsToLoad.Dequeue(); 348 PluginInfo pluginInfo = GetPluginInfo(plugin); 349 bool canLoad = true; 350 foreach (PluginInfo dependency in pluginInfo.Dependencies) { 351 if (!allPlugins.ContainsKey(dependency)) { 352 canLoad = false; 353 break; 354 } 355 } 356 if (canLoad) { 357 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.InitializingPlugin)); 358 plugin.OnLoad(); 359 allPlugins.Add(pluginInfo, plugin); 360 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.InitializedPlugin)); 361 } else { 362 pluginsToLoad.Enqueue(plugin); 363 } 364 } 365 } 366 private PluginInfo GetPluginInfo(IPlugin plugin) { 367 if (pluginInfos.ContainsKey(plugin)) { 368 return pluginInfos[plugin]; 369 } 370 // store the data of the plugin in a description file which can be used without loading the plugin assemblies 371 PluginInfo pluginInfo = new PluginInfo(); 372 pluginInfo.Name = plugin.Name; 373 pluginInfo.Version = plugin.Version; 374 375 object[] customAttributes = plugin.GetType().Assembly.GetCustomAttributes(typeof(AssemblyBuildDateAttribute), false); 376 if (customAttributes.Length > 0) { 377 pluginInfo.BuildDate = ((AssemblyBuildDateAttribute)customAttributes[0]).BuildDate; 378 } 379 380 string baseDir = AppDomain.CurrentDomain.BaseDirectory; 381 382 Array.ForEach<string>(plugin.FileNames, delegate(string file) { 383 string filename = pluginDir + "/" + file; 384 // always use \ as the directory separator 385 pluginInfo.Files.Add(filename.Replace('/', '\\')); 386 }); 387 388 PluginInfo preloadedInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == plugin.Name; }); 389 foreach (string assembly in preloadedInfo.Assemblies) { 390 // always use \ as directory separator (this is necessary for discovery of types in 391 // plugins see DiscoveryService.GetTypes() 392 pluginInfo.Assemblies.Add(assembly.Replace('/', '\\')); 393 } 394 foreach (string dependency in pluginDependencies[preloadedInfo]) { 395 // accumulate the dependencies of each assembly into the dependencies of the whole plugin 396 PluginInfo dependencyInfo = GetPluginInfo(pluginsByName[dependency]); 397 pluginInfo.Dependencies.Add(dependencyInfo); 398 } 399 pluginInfos[plugin] = pluginInfo; 400 return pluginInfo; 401 } 402 403 private void CheckPluginFiles() { 404 foreach (PluginInfo plugin in preloadedPluginInfos) { 405 if (!CheckPluginFiles(plugin)) { 406 plugin.Message = "Disabled: missing plugin file."; 407 disabledPlugins.Add(plugin); 408 } 409 } 410 } 411 412 private bool CheckPluginFiles(PluginInfo pluginInfo) { 413 foreach (string filename in pluginInfo.Files) { 289 plugin.OnLoad(); 290 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded)); 291 } 292 } 293 } 294 } 295 //private PluginDescription GetPluginDescription(IPlugin plugin) { 296 // if (PluginDescriptions.ContainsKey(plugin)) { 297 // return PluginDescriptions[plugin]; 298 // } 299 // // store the data of the plugin in a description file which can be used without loading the plugin assemblies 300 // PluginDescription PluginDescription = new PluginDescription(); 301 // PluginDescription.Name = plugin.Name; 302 // PluginDescription.Version = plugin.Version; 303 304 // object[] customAttributes = plugin.GetType().Assembly.GetCustomAttributes(typeof(AssemblyBuildDateAttribute), false); 305 // if (customAttributes.Length > 0) { 306 // PluginDescription.BuildDate = ((AssemblyBuildDateAttribute)customAttributes[0]).BuildDate; 307 // } 308 309 // string baseDir = AppDomain.CurrentDomain.BaseDirectory; 310 311 // Array.ForEach<string>(plugin.FileNames, delegate(string file) { 312 // string filename = pluginDir + "/" + file; 313 // // always use \ as the directory separator 314 // PluginDescription.Files.Add(filename.Replace('/', '\\')); 315 // }); 316 317 // PluginDescription preloadedInfo = preloadedPluginDescriptions.Find(delegate(PluginDescription info) { return info.Name == plugin.Name; }); 318 // foreach (string assembly in preloadedInfo.Assemblies) { 319 // // always use \ as directory separator (this is necessary for discovery of types in 320 // // plugins see DiscoveryService.GetTypes() 321 // PluginDescription.Assemblies.Add(assembly.Replace('/', '\\')); 322 // } 323 // foreach (string dependency in pluginDependencies[preloadedInfo]) { 324 // // accumulate the dependencies of each assembly into the dependencies of the whole plugin 325 // PluginDescription dependencyInfo = GetPluginDescription(pluginsByName[dependency]); 326 // PluginDescription.Dependencies.Add(dependencyInfo); 327 // } 328 // PluginDescriptions[plugin] = PluginDescription; 329 // return PluginDescription; 330 //} 331 332 // checks if all declared plugin files are actually available and disables plugins with missing files 333 private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) { 334 foreach (PluginDescription desc in pluginDescriptions) { 335 if (!CheckPluginFiles(desc)) { 336 //plugin.Message = "Disabled: missing plugin file."; 337 desc.PluginState = PluginState.Disabled; 338 } 339 } 340 } 341 342 private bool CheckPluginFiles(PluginDescription PluginDescription) { 343 foreach (string filename in PluginDescription.Files) { 414 344 if (!File.Exists(filename)) { 415 if (MissingPluginFile != null) {416 MissingPluginFile(pluginInfo.Name, filename);417 }345 //if (MissingPluginFile != null) { 346 // MissingPluginFile(PluginDescription.Name, filename); 347 //} 418 348 return false; 419 349 } … … 429 359 return null; 430 360 } 431 432 internal void OnDelete(PluginInfo pluginInfo) {433 IPlugin plugin = FindPlugin(pluginInfo);434 if (plugin != null) plugin.OnDelete();435 }436 437 internal void OnInstall(PluginInfo pluginInfo) {438 IPlugin plugin = FindPlugin(pluginInfo);439 if (plugin != null) plugin.OnInstall();440 }441 442 internal void OnPreUpdate(PluginInfo pluginInfo) {443 IPlugin plugin = FindPlugin(pluginInfo);444 if (plugin != null) plugin.OnPreUpdate();445 }446 447 internal void OnPostUpdate(PluginInfo pluginInfo) {448 IPlugin plugin = FindPlugin(pluginInfo);449 if (plugin != null) plugin.OnPostUpdate();450 }451 361 } 452 362 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs
r2472 r2481 24 24 using System.Text; 25 25 26 namespace HeuristicLab.PluginInfrastructure {26 namespace HeuristicLab.PluginInfrastructure.Manager { 27 27 /// <summary> 28 28 /// Holds information of loaded plugins that is needed for plugin management. … … 30 30 /// </summary> 31 31 [Serializable] 32 public class Plugin Info{32 public class PluginDescription { 33 33 private string name; 34 34 /// <summary> … … 55 55 set { buildDate = value; } 56 56 } 57 58 private PluginState pluginState; 59 /// <summary> 60 /// Gets or sets the plugin state. 61 /// </summary> 62 public PluginState PluginState { 63 get { return pluginState; } 64 set { pluginState = value; } 65 } 66 57 67 private List<string> files = new List<string>(); 58 68 /// <summary> … … 60 70 /// These files are deleted when the plugin is removed or updated. 61 71 /// </summary> 62 public List<string> Files {72 public IEnumerable<string> Files { 63 73 get { return files; } 64 74 } 65 75 66 private List<PluginInfo> dependencies = new List<PluginInfo>(); 76 internal void AddFiles(IEnumerable<string> fileNames) { 77 files.AddRange(fileNames); 78 } 79 80 private List<PluginDescription> dependencies = new List<PluginDescription>(); 67 81 /// <summary> 68 82 /// Gets all dependencies of the plugin. 69 83 /// </summary> 70 public List<PluginInfo> Dependencies {84 public IEnumerable<PluginDescription> Dependencies { 71 85 get { return dependencies; } 72 86 } 87 88 public void AddDependency(PluginDescription dependency) { 89 dependencies.Add(dependency); 90 } 91 92 73 93 private List<string> assemblies = new List<string>(); 74 94 /// <summary> 75 95 /// Gets the names of the assemblies that belong to this plugin. 76 96 /// </summary> 77 public List<string> Assemblies {97 public IEnumerable<string> Assemblies { 78 98 get { return assemblies; } 79 set { assemblies = value; }99 // set { assemblies = value; } 80 100 } 81 private string message; 82 /// <summary> 83 /// Gets or sets the message. 84 /// </summary> 85 public string Message { 86 get { return message; } 87 set { message = value; } 101 102 internal void AddAssemblies(IEnumerable<string> assemblyNames) { 103 assemblies.AddRange(assemblyNames); 88 104 } 105 106 //private string message; 107 ///// <summary> 108 ///// Gets or sets the message. 109 ///// </summary> 110 //public string Message { 111 // get { return message; } 112 // set { message = value; } 113 //} 114 89 115 /// <summary> 90 116 /// Gets the string representation of the plugin. … … 94 120 return Name; 95 121 } 96 122 97 123 // equals and hashcode have to be implemented because we want to compare PluginDescriptions from 98 124 // different AppDomains and serialization destroys reference equality … … 103 129 /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns> 104 130 public override bool Equals(object obj) { 105 if (!(obj is PluginInfo))131 if (!(obj is PluginDescription)) 106 132 return false; 107 Plugin Info other = (PluginInfo)obj;133 PluginDescription other = (PluginDescription)obj; 108 134 109 135 return other.Name == this.Name && other.Version == this.Version; … … 114 140 /// <returns>The hash code of the plugin.</returns> 115 141 public override int GetHashCode() { 116 if (version != null) {142 if (version != null) { 117 143 return name.GetHashCode() + version.GetHashCode(); 118 144 } else return name.GetHashCode(); -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs
r2472 r2481 28 28 using System.Security; 29 29 30 namespace HeuristicLab.PluginInfrastructure {30 namespace HeuristicLab.PluginInfrastructure.Manager { 31 31 32 32 // must extend MarshalByRefObject because of event passing between Loader and PluginManager (each in it's own AppDomain) … … 35 35 /// </summary> 36 36 public class PluginManager : MarshalByRefObject { 37 38 // singleton: only one manager allowed in each AppDomain39 private static PluginManager manager = new PluginManager();40 /// <summary>41 /// Gets the plugin manager (is a singleton).42 /// </summary>43 public static PluginManager Manager {44 get { return manager; }45 }46 47 // singleton: only one control manager allowed in each applicatoin (i.e. AppDomain)48 private static IControlManager controlManager;49 /// <summary>50 /// Gets or sets the control manager (is a singleton).51 /// </summary>52 public static IControlManager ControlManager {53 get { return controlManager; }54 set { controlManager = value; }55 }56 57 37 /// <summary> 58 38 /// Event handler for actions in the plugin manager. … … 60 40 public event PluginManagerActionEventHandler Action; 61 41 62 // holds a proxy for the loader in the special AppDomain for PluginManagament63 private Loader remoteLoader;64 private AppDomain pluginDomain;65 42 private string pluginDir; 66 43 67 44 // singleton pattern 68 private PluginManager() { 69 this.pluginDir = HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir; 70 } 71 72 /// <summary> 73 /// Gets all installed plugins. 74 /// </summary> 75 /// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 76 public ICollection<PluginInfo> InstalledPlugins { 77 get { return remoteLoader.InstalledPlugins; } 78 } 79 80 /// <summary> 81 /// Gets all disabled plugins. 82 /// </summary> 83 /// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 84 public ICollection<PluginInfo> DisabledPlugins { 85 get { return remoteLoader.DisabledPlugins; } 86 } 87 88 /// <summary> 89 /// Gets all active plugins. 90 /// </summary> 91 /// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 92 public ICollection<PluginInfo> ActivePlugins { 93 get { return remoteLoader.ActivePlugins; } 94 } 95 45 public PluginManager(string pluginDir) { 46 this.pluginDir = pluginDir; 47 } 48 49 ///// <summary> 50 ///// Gets all installed plugins. 51 ///// </summary> 52 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 53 //public ICollection<PluginInfo> InstalledPlugins { 54 // get { return remoteLoader.InstalledPlugins; } 55 //} 56 57 ///// <summary> 58 ///// Gets all disabled plugins. 59 ///// </summary> 60 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 61 //public ICollection<PluginInfo> DisabledPlugins { 62 // get { return remoteLoader.DisabledPlugins; } 63 //} 64 65 ///// <summary> 66 ///// Gets all active plugins. 67 ///// </summary> 68 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 69 //public ICollection<PluginInfo> ActivePlugins { 70 // get { return remoteLoader.ActivePlugins; } 71 //} 72 73 //private ICollection<PluginInfo> loadedPlugins; 74 ///// <summary> 75 ///// Gets or (internally) sets the loaded plugins. 76 ///// </summary> 77 //public ICollection<PluginInfo> LoadedPlugins { 78 // get { return loadedPlugins; } 79 // internal set { loadedPlugins = value; } 80 //} 81 82 private List<PluginDescription> plugins; 83 public IEnumerable<PluginDescription> Plugins { 84 get { return plugins; } 85 } 86 87 private List<ApplicationDescription> applications; 96 88 /// <summary> 97 89 /// Gets all installed applications. 98 90 /// </summary> 99 /// <remarks>This information is provided by a <see cref="Loader"/>.</remarks> 100 public ICollection<ApplicationInfo> InstalledApplications { 101 get { return remoteLoader.InstalledApplications; } 102 } 103 104 private ICollection<PluginInfo> loadedPlugins; 105 /// <summary> 106 /// Gets or (internally) sets the loaded plugins. 107 /// </summary> 108 public ICollection<PluginInfo> LoadedPlugins { 109 get { return loadedPlugins; } 110 internal set { loadedPlugins = value; } 111 } 112 113 /// <summary> 114 /// Creates a dedicated AppDomain for loading all plugins and checking dependencies. 91 public IEnumerable<ApplicationDescription> Applications { 92 get { return applications; } 93 } 94 95 /// <summary> 96 /// Determines installed plugins and checks if all plugins are loadable. 115 97 /// </summary> 116 98 public void Initialize() { … … 118 100 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 119 101 setup.PrivateBinPath = pluginDir; 120 pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup); 121 remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure", "HeuristicLab.PluginInfrastructure.Loader"); 102 AppDomain pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup); 103 Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader"); 104 remoteLoader.PluginDir = pluginDir; 122 105 remoteLoader.PluginAction += delegate(object sender, PluginManagerActionEventArgs args) { if (Action != null) Action(this, args); }; 123 106 remoteLoader.Init(); 124 107 NotifyListeners(PluginManagerAction.Initialized, "-"); 125 } 108 109 plugins = new List<PluginDescription>(remoteLoader.Plugins); 110 applications = new List<ApplicationDescription>(remoteLoader.Applications); 111 throw new NotImplementedException(); 112 } 113 114 115 ///// <summary> 116 ///// Creates a new AppDomain with all plugins preloaded. 117 ///// </summary> 118 ///// <param name="friendlyName">Name of the new AppDomain</param> 119 ///// <returns>the new AppDomain with all plugins preloaded.</returns> 120 //public AppDomain CreateAndInitAppDomain(string friendlyName) { 121 122 // return applicationDomain; 123 //} 126 124 127 125 /// <summary> … … 130 128 /// </summary> 131 129 /// <param name="appInfo">application to run</param> 132 public void Run(Application InfoappInfo) {130 public void Run(ApplicationDescription appInfo) { 133 131 // create a separate AppDomain for the application 134 132 // activate a PluginRunner instance in the application 135 133 // and remotely tell it to start the application 136 134 137 NotifyListeners(PluginManagerAction. Starting, appInfo.Name);135 NotifyListeners(PluginManagerAction.ApplicationStart, appInfo.Name); 138 136 AppDomain applicationDomain = null; 139 137 try { 140 applicationDomain = CreateAndInitAppDomain(appInfo.Name); 138 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 139 setup.PrivateBinPath = pluginDir; 140 applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup); 141 141 Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName); 142 remoteRunner.PluginAction += delegate(object sender, PluginManagerActionEventArgs args) { if (Action != null) Action(this, args); }; 143 remoteRunner.LoadPlugins(Plugins); 144 NotifyListeners(PluginManagerAction.Initialized, "All plugins"); 142 145 remoteRunner.Run(appInfo); 143 146 } … … 148 151 } 149 152 150 /// <summary> 151 /// Creates a new AppDomain with all plugins preloaded. 152 /// </summary> 153 /// <param name="friendlyName">Name of the new AppDomain</param> 154 /// <returns>the new AppDomain with all plugins preloaded.</returns> 155 public AppDomain CreateAndInitAppDomain(string friendlyName) { 156 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 157 setup.PrivateBinPath = pluginDir; 158 AppDomain applicationDomain = AppDomain.CreateDomain(friendlyName, null, setup); 159 Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName); 160 NotifyListeners(PluginManagerAction.Initializing, "All plugins"); 161 if (remoteLoader != null) { 162 remoteRunner.LoadPlugins(remoteLoader.ActivePlugins); 163 } else if (LoadedPlugins != null && LoadedPlugins.Count > 0) { 164 remoteRunner.LoadPlugins(LoadedPlugins); 165 } 166 NotifyListeners(PluginManagerAction.Initialized, "All plugins"); 167 return applicationDomain; 168 } 169 170 /// <summary> 171 /// Creates a new AppDomain with all plugins preloaded and Sandboxing capability. 172 /// </summary> 173 /// <param name="assembly">Assembly reference</param> 174 /// <returns>the strongname of the assembly</returns> 175 private StrongName CreateStrongName(Assembly assembly) { 176 if (assembly == null) 177 throw new ArgumentNullException("assembly"); 178 179 AssemblyName assemblyName = assembly.GetName(); 180 Debug.Assert(assemblyName != null, "Could not get assembly name"); 181 182 // get the public key blob 183 byte[] publicKey = assemblyName.GetPublicKey(); 184 if (publicKey == null || publicKey.Length == 0) 185 throw new InvalidOperationException("Assembly is not strongly named"); 186 187 StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey); 188 189 // and create the StrongName 190 return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version); 191 } 192 193 public AppDomain CreateAndInitAppDomainWithSandbox(string friendlyName, bool sandboxed, Type jobType, ICollection<byte[]> assemblyFiles) { 194 PermissionSet pset; 195 196 197 198 //DiscoveryService dService = new DiscoveryService(); 199 //get the declaring plugin of the job 200 //PluginInfo jobPlugin = dService.GetDeclaringPlugin(jobType); 201 202 //get all the plugins that have dependencies with the jobplugin 203 //List<PluginInfo> depPlugins = GetDependentPluginsRec(jobPlugin); 204 //insert all jobs into one list 205 //depPlugins.Add(jobPlugin); 206 207 if (sandboxed) { 208 pset = new PermissionSet(PermissionState.None); 209 pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 210 pset.AddPermission(new ReflectionPermission(PermissionState.Unrestricted)); 211 FileIOPermission fPerm = new FileIOPermission(PermissionState.None); 212 213 /*foreach (PluginInfo plugin in depPlugins) { 214 foreach(String assemblies in plugin.Assemblies) 215 fPerm.AddPathList(FileIOPermissionAccess.AllAccess, assemblies); 216 } 217 218 pset.AddPermission(fPerm);*/ 219 220 } else { 221 pset = new PermissionSet(PermissionState.Unrestricted); 222 } 223 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 224 setup.PrivateBinPath = pluginDir; 225 setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 226 AppDomain applicationDomain = AppDomain.CreateDomain(friendlyName, AppDomain.CurrentDomain.Evidence, setup, pset, CreateStrongName(Assembly.GetExecutingAssembly())); 227 Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName); 228 NotifyListeners(PluginManagerAction.Initializing, "All plugins"); 229 230 if (assemblyFiles != null && assemblyFiles.Count > 0) 231 remoteRunner.LoadAssemblies(assemblyFiles); 232 233 //if (depPlugins != null && depPlugins.Count > 0) { 234 //remoteRunner.LoadPlugins(ActivePlugins); 235 //} 236 NotifyListeners(PluginManagerAction.Initialized, "All plugins"); 237 return applicationDomain; 238 } 239 240 /// <summary> 241 /// Calculates a set of plugins that directly or transitively depend on the plugin given in the argument. 242 /// </summary> 243 /// <param name="pluginInfo">The plugin the other depend on.</param> 244 /// <returns>a list of plugins that are directly of transitively dependent.</returns> 245 public List<PluginInfo> GetDependentPlugins(PluginInfo pluginInfo) { 246 List<PluginInfo> mergedList = new List<PluginInfo>(); 247 foreach (PluginInfo plugin in InstalledPlugins) { 248 if (plugin.Dependencies.Contains(pluginInfo)) { 249 if (!mergedList.Contains(plugin)) { 250 mergedList.Add(plugin); 251 } 252 // for each of the dependent plugins add the list of transitively dependent plugins 253 // make sure that only one entry for each plugin is added to the merged list 254 GetDependentPlugins(plugin).ForEach(delegate(PluginInfo dependentPlugin) { 255 if (!mergedList.Contains(dependentPlugin)) { 256 mergedList.Add(dependentPlugin); 257 } 258 }); 259 } 260 } 261 return mergedList; 262 } 263 264 /// <summary> 265 /// Unloads all plugins. 266 /// </summary> 267 public void UnloadAllPlugins() { 268 AppDomain.Unload(pluginDomain); 269 } 270 271 /// <summary> 272 /// Loads all plugins. 273 /// </summary> 274 public void LoadAllPlugins() { 275 Initialize(); 276 } 277 278 /// <inheritdoc cref="Loader.OnDelete"/> 279 public void OnDelete(PluginInfo pluginInfo) { 280 remoteLoader.OnDelete(pluginInfo); 281 } 282 283 /// <inheritdoc cref="Loader.OnInstall"/> 284 public void OnInstall(PluginInfo pluginInfo) { 285 remoteLoader.OnInstall(pluginInfo); 286 } 287 288 /// <inheritdoc cref="Loader.OnPreUpdate"/> 289 public void OnPreUpdate(PluginInfo pluginInfo) { 290 remoteLoader.OnPreUpdate(pluginInfo); 291 } 292 293 /// <inheritdoc cref="Loader.OnPostUpdate"/> 294 public void OnPostUpdate(PluginInfo pluginInfo) { 295 remoteLoader.OnPostUpdate(pluginInfo); 296 } 153 ///// <summary> 154 ///// Creates a new AppDomain with all plugins preloaded and Sandboxing capability. 155 ///// </summary> 156 ///// <param name="assembly">Assembly reference</param> 157 ///// <returns>the strongname of the assembly</returns> 158 //private StrongName CreateStrongName(Assembly assembly) { 159 // if (assembly == null) 160 // throw new ArgumentNullException("assembly"); 161 162 // AssemblyName assemblyName = assembly.GetName(); 163 // Debug.Assert(assemblyName != null, "Could not get assembly name"); 164 165 // // get the public key blob 166 // byte[] publicKey = assemblyName.GetPublicKey(); 167 // if (publicKey == null || publicKey.Length == 0) 168 // throw new InvalidOperationException("Assembly is not strongly named"); 169 170 // StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey); 171 172 // // and create the StrongName 173 // return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version); 174 //} 175 176 //public AppDomain CreateAndInitAppDomainWithSandbox(string friendlyName, bool sandboxed, Type jobType, ICollection<byte[]> assemblyFiles) { 177 // PermissionSet pset; 178 179 180 181 // //DiscoveryService dService = new DiscoveryService(); 182 // //get the declaring plugin of the job 183 // //PluginInfo jobPlugin = dService.GetDeclaringPlugin(jobType); 184 185 // //get all the plugins that have dependencies with the jobplugin 186 // //List<PluginInfo> depPlugins = GetDependentPluginsRec(jobPlugin); 187 // //insert all jobs into one list 188 // //depPlugins.Add(jobPlugin); 189 190 // if (sandboxed) { 191 // pset = new PermissionSet(PermissionState.None); 192 // pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 193 // pset.AddPermission(new ReflectionPermission(PermissionState.Unrestricted)); 194 // FileIOPermission fPerm = new FileIOPermission(PermissionState.None); 195 196 // /*foreach (PluginInfo plugin in depPlugins) { 197 // foreach(String assemblies in plugin.Assemblies) 198 // fPerm.AddPathList(FileIOPermissionAccess.AllAccess, assemblies); 199 // } 200 201 // pset.AddPermission(fPerm);*/ 202 203 // } else { 204 // pset = new PermissionSet(PermissionState.Unrestricted); 205 // } 206 // AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 207 // setup.PrivateBinPath = pluginDir; 208 // setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 209 // AppDomain applicationDomain = AppDomain.CreateDomain(friendlyName, AppDomain.CurrentDomain.Evidence, setup, pset, CreateStrongName(Assembly.GetExecutingAssembly())); 210 // Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName); 211 // NotifyListeners("Initializing", "All plugins"); 212 213 // if (assemblyFiles != null && assemblyFiles.Count > 0) 214 // remoteRunner.LoadAssemblies(assemblyFiles); 215 216 // //if (depPlugins != null && depPlugins.Count > 0) { 217 // //remoteRunner.LoadPlugins(ActivePlugins); 218 // //} 219 // NotifyListeners("Initialized", "All plugins"); 220 // return applicationDomain; 221 //} 222 223 ///// <summary> 224 ///// Calculates a set of plugins that directly or transitively depend on the plugin given in the argument. 225 ///// </summary> 226 ///// <param name="pluginInfo">The plugin the other depend on.</param> 227 ///// <returns>a list of plugins that are directly of transitively dependent.</returns> 228 //public List<PluginDescription> GetDependentPlugins(PluginDescription pluginInfo) { 229 // List<PluginDescription> mergedList = new List<PluginDescription>(); 230 // foreach (PluginDescription plugin in Plugins) { 231 // if (plugin.Dependencies.Contains(pluginInfo)) { 232 // if (!mergedList.Contains(plugin)) { 233 // mergedList.Add(plugin); 234 // } 235 // // for each of the dependent plugins add the list of transitively dependent plugins 236 // // make sure that only one entry for each plugin is added to the merged list 237 // foreach (PluginDescription dependentPlugin in GetDependentPlugins(plugin)) { 238 // if (!mergedList.Contains(dependentPlugin)) { 239 // mergedList.Add(dependentPlugin); 240 // } 241 // } 242 // } 243 // } 244 // return mergedList; 245 //} 297 246 298 247 private void NotifyListeners(PluginManagerAction action, string text) { -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManagerActionEventArgs.cs
r2472 r2481 24 24 using System.Text; 25 25 26 namespace HeuristicLab.PluginInfrastructure { 27 /// <summary> 28 /// Enum for all possible actions the plugin manager can execute. 29 /// </summary> 30 public enum PluginManagerAction { Initializing, InitializingPlugin, InitializedPlugin, Initialized, Starting } 26 namespace HeuristicLab.PluginInfrastructure.Manager { 27 public enum PluginManagerAction { Initializing, PluginLoaded, ApplicationStart, Initialized } 28 29 31 30 /// <summary> 32 31 /// Event handler for all action events of the plugin manager. -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Runner.cs
r2472 r2481 26 26 using System.Security.Permissions; 27 27 using System.Security; 28 using System.Linq; 28 29 29 namespace HeuristicLab.PluginInfrastructure {30 namespace HeuristicLab.PluginInfrastructure.Manager { 30 31 public class Runner : MarshalByRefObject { 32 internal event PluginManagerActionEventHandler PluginAction; 31 33 32 34 private Dictionary<string, Assembly> loadedAssemblies; … … 35 37 loadedAssemblies = new Dictionary<string, Assembly>(); 36 38 AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { 37 if (loadedAssemblies.ContainsKey(args.Name)) {39 if (loadedAssemblies.ContainsKey(args.Name)) { 38 40 return loadedAssemblies[args.Name]; 39 41 } … … 42 44 } 43 45 44 public void LoadPlugins(I Collection<PluginInfo> plugins) {46 public void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) { 45 47 //FileIOPermission fileperm = new FileIOPermission(FileIOPermissionAccess.AllAccess, @"C:\Program Files\HeuristicLab 3.0\plugins\"); 46 48 //fileperm.Assert(); 47 foreach(PluginInfo pluginInfo in plugins) { 48 foreach(string assemblyName in pluginInfo.Assemblies) { 49 Assembly.LoadFrom(assemblyName); 49 50 // load all loadable plugins (all dependencies available) into the execution context 51 foreach (PluginDescription desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) { 52 List<Type> types = new List<Type>(); 53 foreach (string assembly in desc.Assemblies) { 54 var asm = Assembly.LoadFrom(assembly); 55 foreach (Type t in asm.GetTypes()) { 56 if (typeof(IPlugin).IsAssignableFrom(t)) { 57 types.Add(t); 58 } 59 } 60 } 61 62 foreach (Type pluginType in types) { 63 if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) { 64 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); 65 plugin.OnLoad(); 66 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded)); 67 } 50 68 } 51 69 } 52 70 //CodeAccessPermission.RevertAssert(); 53 FireOnLoad();54 PluginManager.Manager.LoadedPlugins = plugins;55 71 } 72 56 73 /// <summary> 57 74 /// Loads assemblies from a byte array 58 75 /// </summary> 59 76 /// <param name="plugins">bytearray of all assemblies that should be loaded</param> 60 public void LoadAssemblies(I Collection<byte[]> assemblies) {77 public void LoadAssemblies(IEnumerable<byte[]> assemblies) { 61 78 foreach (byte[] asm in assemblies) { 62 79 Assembly loadedAsm = Assembly.Load(asm); … … 70 87 } 71 88 72 public void Run(Application InfoappInfo) {89 public void Run(ApplicationDescription appInfo) { 73 90 IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.PluginAssembly, appInfo.PluginType).Unwrap(); 74 91 try { 75 92 runnablePlugin.Run(); 76 } catch (Exception e) { 93 } 94 catch (Exception e) { 77 95 throw new Exception(String.Format( 78 96 "Unexpected exception caught: \"{0}\"\r\n" + … … 84 102 e.ToString())); 85 103 } 86 }87 88 private void FireOnLoad() {89 DiscoveryService service = new DiscoveryService();90 Array.ForEach(service.GetInstances<IPlugin>(), p => p.OnLoad());91 104 } 92 105 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Attributes/PluginDependencyAttribute.cs
r2475 r2481 37 37 public string Dependency { 38 38 get { return dependency; } 39 set { dependency = value; }39 // set { dependency = value; } 40 40 } 41 41 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Attributes/PluginDescriptionAttribute.cs
r2475 r2481 37 37 public string Name { 38 38 get { return name; } 39 set { name = value; }39 // set { name = value; } 40 40 } 41 41 42 private string version;43 /// <summary>44 /// Gets or sets the version of the plugin.45 /// </summary>46 public string Version {47 get { return version; }48 set { version = value; }49 }42 //private string version; 43 ///// <summary> 44 ///// Gets or sets the version of the plugin. 45 ///// </summary> 46 //public string Version { 47 // get { return version; } 48 // set { version = value; } 49 //} 50 50 51 private string description;52 /// <summary>53 /// Gets or sets the description of the plugin.54 /// </summary>55 public string Description {56 get { return description; }57 set { description = value; }58 }51 //private string description; 52 ///// <summary> 53 ///// Gets or sets the description of the plugin. 54 ///// </summary> 55 //public string Description { 56 // get { return description; } 57 // set { description = value; } 58 //} 59 59 60 60 /// <summary> … … 62 62 /// <param name="name">Name of the plugin</param> 63 63 /// </summary> 64 public PluginDescriptionAttribute(string name) 65 : this(name, "") {64 public PluginDescriptionAttribute(string name) { 65 this.name = name; 66 66 } 67 67 68 /// <summary>69 /// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>.70 /// <param name="name">Name of the plugin</param>71 /// <param name="description">Description of the plugin</param>72 /// </summary>73 public PluginDescriptionAttribute(string name, string description)74 : this(name, description, "") {75 }68 ///// <summary> 69 ///// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>. 70 ///// <param name="name">Name of the plugin</param> 71 ///// <param name="description">Description of the plugin</param> 72 ///// </summary> 73 //public PluginDescriptionAttribute(string name, string description) 74 // : this(name, description, "") { 75 //} 76 76 77 /// <summary>78 /// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>.79 /// <param name="name">Name of the plugin</param>80 /// <param name="description">Description of the plugin</param>81 /// <param name="version">Version string of the plugin</param>82 /// </summary>83 public PluginDescriptionAttribute(string name, string description, string version) {84 this.name = name;85 this.version = version;86 this.description = description;87 }77 ///// <summary> 78 ///// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>. 79 ///// <param name="name">Name of the plugin</param> 80 ///// <param name="description">Description of the plugin</param> 81 ///// <param name="version">Version string of the plugin</param> 82 ///// </summary> 83 //public PluginDescriptionAttribute(string name, string description, string version) { 84 // this.name = name; 85 // this.version = version; 86 // this.description = description; 87 //} 88 88 } 89 89 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Attributes/PluginFileAttribute.cs
r2475 r2481 30 30 public enum PluginFileType { 31 31 Assembly, 32 Executable,32 NativeAssembly, 33 33 Data, 34 34 License … … 48 48 public string Filename { 49 49 get { return filename; } 50 set { filename = value; }50 //set { filename = value; } 51 51 } 52 52 … … 58 58 public PluginFileType Filetype { 59 59 get { return filetype; } 60 set { filetype = value; }60 //set { filetype = value; } 61 61 } 62 62 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs
r2475 r2481 56 56 } 57 57 58 /// <inheritdoc />59 public Version Version {60 get {61 var pluginAttribute = PluginDescriptionAttribute;62 // if the version is not set in the attribute then the version of the assembly is used as default63 if (string.IsNullOrEmpty(pluginAttribute.Version)) {64 return this.GetType().Assembly.GetName().Version;65 } else {66 return new Version(pluginAttribute.Version);67 }68 }69 }58 ///// <inheritdoc /> 59 //public Version Version { 60 // get { 61 // var pluginAttribute = PluginDescriptionAttribute; 62 // // if the version is not set in the attribute then the version of the assembly is used as default 63 // if (string.IsNullOrEmpty(pluginAttribute.Version)) { 64 // return this.GetType().Assembly.GetName().Version; 65 // } else { 66 // return new Version(pluginAttribute.Version); 67 // } 68 // } 69 //} 70 70 71 /// <inheritdoc />72 public string Description {73 get {74 var pluginAttribute = PluginDescriptionAttribute;75 // if the description is not explicitly set in the attribute then the name of the plugin is used as default76 if (string.IsNullOrEmpty(pluginAttribute.Description)) {77 return pluginAttribute.Name;78 } else {79 return pluginAttribute.Description;80 }81 }82 }71 ///// <inheritdoc /> 72 //public string Description { 73 // get { 74 // var pluginAttribute = PluginDescriptionAttribute; 75 // // if the description is not explicitly set in the attribute then the name of the plugin is used as default 76 // if (string.IsNullOrEmpty(pluginAttribute.Description)) { 77 // return pluginAttribute.Name; 78 // } else { 79 // return pluginAttribute.Description; 80 // } 81 // } 82 //} 83 83 84 84 /// <inheritdoc/> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/DiscoveryService.cs
r2234 r2481 31 31 public class DiscoveryService { 32 32 33 public PluginInfo[] Plugins {34 get {35 PluginInfo[] plugins = new PluginInfo[PluginManager.Manager.LoadedPlugins.Count];36 PluginManager.Manager.LoadedPlugins.CopyTo(plugins, 0);37 return plugins;38 }39 }33 //public PluginDescription[] Plugins { 34 // get { 35 // PluginInfo[] plugins = new PluginInfo[PluginManager.Manager.LoadedPlugins.Count]; 36 // PluginManager.Manager.LoadedPlugins.CopyTo(plugins, 0); 37 // return plugins; 38 // } 39 //} 40 40 41 41 /// <summary> … … 87 87 } 88 88 89 /// <summary>90 /// Finds all types that are subtypes or equal to the specified type if they are part of the given91 /// <paramref name="plugin"/>.92 /// </summary>93 /// <param name="type">Most general type for which to find matching types.</param>94 /// <param name="plugin">The plugin the subtypes must be part of.</param>95 /// <returns>The found types as array.</returns>96 public Type[] GetTypes(Type type, PluginInfo plugin) {97 Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();98 List<Type> types = new List<Type>();99 foreach (Assembly asm in assemblies) {100 if (plugin.Assemblies.Contains(asm.Location)) {101 Array.ForEach<Type>(GetTypes(type, asm), delegate(Type t) {102 types.Add(t);103 });104 }105 }89 ///// <summary> 90 ///// Finds all types that are subtypes or equal to the specified type if they are part of the given 91 ///// <paramref name="plugin"/>. 92 ///// </summary> 93 ///// <param name="type">Most general type for which to find matching types.</param> 94 ///// <param name="plugin">The plugin the subtypes must be part of.</param> 95 ///// <returns>The found types as array.</returns> 96 //public Type[] GetTypes(Type type, PluginInfo plugin) { 97 // Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 98 // List<Type> types = new List<Type>(); 99 // foreach (Assembly asm in assemblies) { 100 // if (plugin.Assemblies.Contains(asm.Location)) { 101 // Array.ForEach<Type>(GetTypes(type, asm), delegate(Type t) { 102 // types.Add(t); 103 // }); 104 // } 105 // } 106 106 107 return types.ToArray();108 }107 // return types.ToArray(); 108 //} 109 109 110 /// <summary>111 /// Gets instances of all types that implement the specified interface only in the given assembly.112 /// </summary>113 /// <typeparam name="T">Interface type.</typeparam>114 /// <param name="assembly">Assembly that should be searched for types.</param>115 /// <returns>The found instances as array.</returns>116 internal T[] GetInstances<T>(Assembly assembly) {117 Type[] types = GetTypes(typeof(T), assembly);118 List<T> instances = new List<T>();119 foreach (Type t in types) {120 if (!t.IsAbstract && !t.IsInterface && !t.HasElementType) {121 instances.Add((T)Activator.CreateInstance(t));122 }123 }124 return instances.ToArray();125 }110 ///// <summary> 111 ///// Gets instances of all types that implement the specified interface only in the given assembly. 112 ///// </summary> 113 ///// <typeparam name="T">Interface type.</typeparam> 114 ///// <param name="assembly">Assembly that should be searched for types.</param> 115 ///// <returns>The found instances as array.</returns> 116 //internal T[] GetInstances<T>(Assembly assembly) { 117 // Type[] types = GetTypes(typeof(T), assembly); 118 // List<T> instances = new List<T>(); 119 // foreach (Type t in types) { 120 // if (!t.IsAbstract && !t.IsInterface && !t.HasElementType) { 121 // instances.Add((T)Activator.CreateInstance(t)); 122 // } 123 // } 124 // return instances.ToArray(); 125 //} 126 126 127 127 /// <summary> … … 141 141 } 142 142 143 /// <summary>144 /// Gets the plugin of the given <paramref name="type"/>.145 /// </summary>146 /// <param name="type"></param>147 /// <returns>The found plugin or <c>null</c>.</returns>148 public PluginInfo GetDeclaringPlugin(Type type) {149 foreach (PluginInfo info in PluginManager.Manager.LoadedPlugins) {150 if (info.Assemblies.Contains(type.Assembly.Location)) return info;151 }152 return null;153 }143 ///// <summary> 144 ///// Gets the plugin of the given <paramref name="type"/>. 145 ///// </summary> 146 ///// <param name="type"></param> 147 ///// <returns>The found plugin or <c>null</c>.</returns> 148 //public PluginInfo GetDeclaringPlugin(Type type) { 149 // foreach (PluginInfo info in PluginManager.Manager.LoadedPlugins) { 150 // if (info.Assemblies.Contains(type.Assembly.Location)) return info; 151 // } 152 // return null; 153 //} 154 154 } 155 155 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj
r2475 r2481 86 86 </ItemGroup> 87 87 <ItemGroup> 88 <Compile Include="ApplicationInfo.cs" />89 88 <Compile Include="Attributes\ApplicationDescriptionAttribute.cs" /> 90 89 <Compile Include="Attributes\AssemblyBuildDateAttribute.cs" /> … … 97 96 <Compile Include="Interfaces\IControl.cs" /> 98 97 <Compile Include="Interfaces\IControlManager.cs" /> 99 <Compile Include="InvalidPluginException.cs" />100 <Compile Include="PluginManager.cs" />101 <Compile Include="PluginManagerActionEventArgs.cs" />102 98 <Compile Include="Interfaces\IPlugin.cs" /> 103 99 <Compile Include="DiscoveryService.cs" /> 104 <Compile Include="PluginInfo.cs" /> 105 <Compile Include="Loader.cs" /> 106 <Compile Include="Runner.cs" /> 100 <Compile Include="ControlManager.cs" /> 101 <Compile Include="InvalidPluginException.cs" /> 107 102 <Compile Include="Properties\AssemblyInfo.cs" /> 108 103 <EmbeddedResource Include="Properties\Resources.resx"> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IApplication.cs
r2475 r2481 25 25 26 26 namespace HeuristicLab.PluginInfrastructure { 27 internalinterface IApplication {27 public interface IApplication { 28 28 string Name { get; } 29 29 Version Version { get; } 30 string Description { get; }30 string Description { get; } 31 31 bool RestartOnErrors { get; } 32 32 void Run(); -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs
r2475 r2481 32 32 /// The method OnLoad() is called by the framework when the plugin is loaded (application start). 33 33 /// </summary> 34 internalinterface IPlugin {34 public interface IPlugin { 35 35 /// <summary> 36 36 /// Gets the name of the plugin. 37 37 /// </summary> 38 38 string Name { get; } 39 /// <summary>40 /// Gets the version of the plugin.41 /// </summary>42 Version Version { get; }39 ///// <summary> 40 ///// Gets the version of the plugin. 41 ///// </summary> 42 //Version Version { get; } 43 43 /// <summary> 44 44 /// Gets all file names that are bundled with this plugin including all assembly files (*.dll) -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/InvalidPluginException.cs
r2475 r2481 28 28 /// Exception class for invalid plugins. 29 29 /// </summary> 30 internalclass InvalidPluginException : Exception {30 public class InvalidPluginException : Exception { 31 31 public InvalidPluginException(string message) : base(message) { } 32 32 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.Update.Client
- Property svn:ignore
-
old new 1 1 bin 2 2 obj 3 *.user
-
- Property svn:ignore
-
branches/PluginInfrastructure Refactoring/HeuristicLab.Update.Client/HeuristicLab.Update.Client.csproj
r2475 r2481 6 6 <ProductVersion>9.0.30729</ProductVersion> 7 7 <SchemaVersion>2.0</SchemaVersion> 8 <ProjectGuid> dd7f11cf-d865-4206-ba2e-febf3a16a54b</ProjectGuid>8 <ProjectGuid>{A8EDF081-459A-4A3D-9F5C-D565A9B01F52}</ProjectGuid> 9 9 <OutputType>Library</OutputType> 10 10 <AppDesignerFolder>Properties</AppDesignerFolder> … … 46 46 </ItemGroup> 47 47 <ItemGroup> 48 <Compile Include=" Class1.cs" />48 <Compile Include="Manager.cs" /> 49 49 <Compile Include="Properties\AssemblyInfo.cs" /> 50 50 </ItemGroup> -
branches/PluginInfrastructure Refactoring/HeuristicLab.Update.Client/Manager.cs
r2475 r2481 4 4 using System.Text; 5 5 6 namespace HeuristicLab. PluginInfrastructure.Manager{6 namespace HeuristicLab.Update.Client { 7 7 public class Manager { 8 8 public void InstallPlugin(string name) { … … 14 14 } 15 15 16 public IEnumera tion<PluginDescription> InstalledPlugins {16 public IEnumerable<PluginDescription> InstalledPlugins { 17 17 get { 18 18 throw new NotImplementedException(); -
branches/PluginInfrastructure Refactoring/HeuristicLab.Update.Interfaces/HeuristicLab.Update.Interfaces.csproj
r2475 r2481 6 6 <ProductVersion>9.0.30729</ProductVersion> 7 7 <SchemaVersion>2.0</SchemaVersion> 8 <ProjectGuid> ff397810-e3c5-4739-b5e9-36462cd67ef8</ProjectGuid>8 <ProjectGuid>{F47613C0-06D3-4314-8DAD-F992850A3B23}</ProjectGuid> 9 9 <OutputType>Library</OutputType> 10 10 <AppDesignerFolder>Properties</AppDesignerFolder> … … 46 46 </ItemGroup> 47 47 <ItemGroup> 48 <Compile Include="Class1.cs" />49 48 <Compile Include="Properties\AssemblyInfo.cs" /> 50 49 </ItemGroup> -
branches/PluginInfrastructure Refactoring/HeuristicLab.Update.Service/HeuristicLab.Update.Service.csproj
r2475 r2481 6 6 <ProductVersion>9.0.30729</ProductVersion> 7 7 <SchemaVersion>2.0</SchemaVersion> 8 <ProjectGuid> b0fee259-b3da-4fed-b27a-2f4e0cd2d8b6</ProjectGuid>8 <ProjectGuid>{175263A8-716D-40AC-85A1-E837F6F4736A}</ProjectGuid> 9 9 <OutputType>Library</OutputType> 10 10 <AppDesignerFolder>Properties</AppDesignerFolder> … … 46 46 </ItemGroup> 47 47 <ItemGroup> 48 <Compile Include="Class1.cs" />49 48 <Compile Include="Properties\AssemblyInfo.cs" /> 50 49 </ItemGroup> -
branches/PluginInfrastructure Refactoring/HeuristicLab.sln
r2472 r2481 255 255 EndProject 256 256 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.MainForm.WindowsForms", "HeuristicLab.MainForm.WindowsForms\3.2\HeuristicLab.MainForm.WindowsForms.csproj", "{AB687BBE-1BFE-476B-906D-44237135431D}" 257 EndProject 258 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.PluginInfrastructure.Manager", "HeuristicLab.PluginInfrastructure.Manager\HeuristicLab.PluginInfrastructure.Manager.csproj", "{CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}" 259 EndProject 260 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Update.Service", "HeuristicLab.Update.Service\HeuristicLab.Update.Service.csproj", "{175263A8-716D-40AC-85A1-E837F6F4736A}" 261 EndProject 262 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Update.Interfaces", "HeuristicLab.Update.Interfaces\HeuristicLab.Update.Interfaces.csproj", "{F47613C0-06D3-4314-8DAD-F992850A3B23}" 263 EndProject 264 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Update.Client", "HeuristicLab.Update.Client\HeuristicLab.Update.Client.csproj", "{A8EDF081-459A-4A3D-9F5C-D565A9B01F52}" 257 265 EndProject 258 266 Global … … 4079 4087 {AB687BBE-1BFE-476B-906D-44237135431D}.Visualization Debug|x64.ActiveCfg = Debug|x64 4080 4088 {AB687BBE-1BFE-476B-906D-44237135431D}.Visualization Debug|x86.ActiveCfg = Debug|x86 4089 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU 4090 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU 4091 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU 4092 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU 4093 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 4094 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Debug|Any CPU.Build.0 = Debug|Any CPU 4095 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Debug|x64.ActiveCfg = Debug|Any CPU 4096 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Debug|x86.ActiveCfg = Debug|Any CPU 4097 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Modeling Debug|Any CPU.ActiveCfg = Debug|Any CPU 4098 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU 4099 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU 4100 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Modeling Debug|x86.ActiveCfg = Debug|Any CPU 4101 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Release|Any CPU.ActiveCfg = Release|Any CPU 4102 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Release|Any CPU.Build.0 = Release|Any CPU 4103 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Release|x64.ActiveCfg = Release|Any CPU 4104 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Release|x86.ActiveCfg = Release|Any CPU 4105 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.v3.2 Debug|Any CPU.ActiveCfg = Debug|Any CPU 4106 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.v3.2 Debug|Any CPU.Build.0 = Debug|Any CPU 4107 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.v3.2 Debug|x64.ActiveCfg = Debug|Any CPU 4108 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.v3.2 Debug|x86.ActiveCfg = Debug|Any CPU 4109 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU 4110 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU 4111 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU 4112 {CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU 4113 {175263A8-716D-40AC-85A1-E837F6F4736A}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU 4114 {175263A8-716D-40AC-85A1-E837F6F4736A}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU 4115 {175263A8-716D-40AC-85A1-E837F6F4736A}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU 4116 {175263A8-716D-40AC-85A1-E837F6F4736A}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU 4117 {175263A8-716D-40AC-85A1-E837F6F4736A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 4118 {175263A8-716D-40AC-85A1-E837F6F4736A}.Debug|Any CPU.Build.0 = Debug|Any CPU 4119 {175263A8-716D-40AC-85A1-E837F6F4736A}.Debug|x64.ActiveCfg = Debug|Any CPU 4120 {175263A8-716D-40AC-85A1-E837F6F4736A}.Debug|x86.ActiveCfg = Debug|Any CPU 4121 {175263A8-716D-40AC-85A1-E837F6F4736A}.Modeling Debug|Any CPU.ActiveCfg = Debug|Any CPU 4122 {175263A8-716D-40AC-85A1-E837F6F4736A}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU 4123 {175263A8-716D-40AC-85A1-E837F6F4736A}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU 4124 {175263A8-716D-40AC-85A1-E837F6F4736A}.Modeling Debug|x86.ActiveCfg = Debug|Any CPU 4125 {175263A8-716D-40AC-85A1-E837F6F4736A}.Release|Any CPU.ActiveCfg = Release|Any CPU 4126 {175263A8-716D-40AC-85A1-E837F6F4736A}.Release|Any CPU.Build.0 = Release|Any CPU 4127 {175263A8-716D-40AC-85A1-E837F6F4736A}.Release|x64.ActiveCfg = Release|Any CPU 4128 {175263A8-716D-40AC-85A1-E837F6F4736A}.Release|x86.ActiveCfg = Release|Any CPU 4129 {175263A8-716D-40AC-85A1-E837F6F4736A}.v3.2 Debug|Any CPU.ActiveCfg = Debug|Any CPU 4130 {175263A8-716D-40AC-85A1-E837F6F4736A}.v3.2 Debug|Any CPU.Build.0 = Debug|Any CPU 4131 {175263A8-716D-40AC-85A1-E837F6F4736A}.v3.2 Debug|x64.ActiveCfg = Debug|Any CPU 4132 {175263A8-716D-40AC-85A1-E837F6F4736A}.v3.2 Debug|x86.ActiveCfg = Debug|Any CPU 4133 {175263A8-716D-40AC-85A1-E837F6F4736A}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU 4134 {175263A8-716D-40AC-85A1-E837F6F4736A}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU 4135 {175263A8-716D-40AC-85A1-E837F6F4736A}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU 4136 {175263A8-716D-40AC-85A1-E837F6F4736A}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU 4137 {F47613C0-06D3-4314-8DAD-F992850A3B23}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU 4138 {F47613C0-06D3-4314-8DAD-F992850A3B23}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU 4139 {F47613C0-06D3-4314-8DAD-F992850A3B23}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU 4140 {F47613C0-06D3-4314-8DAD-F992850A3B23}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU 4141 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 4142 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Debug|Any CPU.Build.0 = Debug|Any CPU 4143 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Debug|x64.ActiveCfg = Debug|Any CPU 4144 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Debug|x86.ActiveCfg = Debug|Any CPU 4145 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Modeling Debug|Any CPU.ActiveCfg = Debug|Any CPU 4146 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU 4147 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU 4148 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Modeling Debug|x86.ActiveCfg = Debug|Any CPU 4149 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Release|Any CPU.ActiveCfg = Release|Any CPU 4150 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Release|Any CPU.Build.0 = Release|Any CPU 4151 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Release|x64.ActiveCfg = Release|Any CPU 4152 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Release|x86.ActiveCfg = Release|Any CPU 4153 {F47613C0-06D3-4314-8DAD-F992850A3B23}.v3.2 Debug|Any CPU.ActiveCfg = Debug|Any CPU 4154 {F47613C0-06D3-4314-8DAD-F992850A3B23}.v3.2 Debug|Any CPU.Build.0 = Debug|Any CPU 4155 {F47613C0-06D3-4314-8DAD-F992850A3B23}.v3.2 Debug|x64.ActiveCfg = Debug|Any CPU 4156 {F47613C0-06D3-4314-8DAD-F992850A3B23}.v3.2 Debug|x86.ActiveCfg = Debug|Any CPU 4157 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU 4158 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU 4159 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU 4160 {F47613C0-06D3-4314-8DAD-F992850A3B23}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU 4161 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU 4162 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU 4163 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU 4164 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU 4165 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 4166 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Debug|Any CPU.Build.0 = Debug|Any CPU 4167 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Debug|x64.ActiveCfg = Debug|Any CPU 4168 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Debug|x86.ActiveCfg = Debug|Any CPU 4169 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Modeling Debug|Any CPU.ActiveCfg = Debug|Any CPU 4170 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU 4171 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU 4172 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Modeling Debug|x86.ActiveCfg = Debug|Any CPU 4173 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Release|Any CPU.ActiveCfg = Release|Any CPU 4174 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Release|Any CPU.Build.0 = Release|Any CPU 4175 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Release|x64.ActiveCfg = Release|Any CPU 4176 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Release|x86.ActiveCfg = Release|Any CPU 4177 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.v3.2 Debug|Any CPU.ActiveCfg = Debug|Any CPU 4178 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.v3.2 Debug|Any CPU.Build.0 = Debug|Any CPU 4179 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.v3.2 Debug|x64.ActiveCfg = Debug|Any CPU 4180 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.v3.2 Debug|x86.ActiveCfg = Debug|Any CPU 4181 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU 4182 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU 4183 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU 4184 {A8EDF081-459A-4A3D-9F5C-D565A9B01F52}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU 4081 4185 EndGlobalSection 4082 4186 GlobalSection(SolutionProperties) = preSolution -
branches/PluginInfrastructure Refactoring/HeuristicLab/HeuristicLab.csproj
r1970 r2481 19 19 </UpgradeBackupLocation> 20 20 <RunPostBuildEvent>Always</RunPostBuildEvent> 21 <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> 21 22 </PropertyGroup> 22 23 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> … … 72 73 <ItemGroup> 73 74 <Reference Include="System" /> 75 <Reference Include="System.Core"> 76 <RequiredTargetFramework>3.5</RequiredTargetFramework> 77 </Reference> 74 78 <Reference Include="System.Data" /> 75 79 <Reference Include="System.Deployment" /> … … 123 127 </ItemGroup> 124 128 <ItemGroup> 125 <ProjectReference Include="..\HeuristicLab.PluginInfrastructure. GUI\HeuristicLab.PluginInfrastructure.GUI.csproj">126 <Project>{ D3F92C1F-42B4-4EFB-9E73-B64FD3428ADE}</Project>127 <Name>HeuristicLab.PluginInfrastructure. GUI</Name>129 <ProjectReference Include="..\HeuristicLab.PluginInfrastructure.Manager\HeuristicLab.PluginInfrastructure.Manager.csproj"> 130 <Project>{CA8AAD91-E8E2-41AF-96AD-2BA94BC3EF2D}</Project> 131 <Name>HeuristicLab.PluginInfrastructure.Manager</Name> 128 132 </ProjectReference> 129 133 <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj"> -
branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs
r1394 r2481 29 29 using System.Diagnostics; 30 30 using HeuristicLab.PluginInfrastructure; 31 using HeuristicLab.PluginInfrastructure.GUI;32 31 using System.Threading; 32 using HeuristicLab.PluginInfrastructure.Manager; 33 33 34 34 namespace HeuristicLab { … … 38 38 private bool abortRequested; 39 39 40 public MainForm() { 40 public MainForm() 41 : base() { 42 InitializeComponent(); 43 41 44 abortRequested = false; 42 SplashScreen splashScreen = new SplashScreen(1000, "Loading HeuristicLab..."); 45 PluginManager pluginManager = new PluginManager(HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir); 46 SplashScreen splashScreen = new SplashScreen(pluginManager, 1000, "Loading HeuristicLab..."); 43 47 splashScreen.Owner = this; 44 48 splashScreen.Show(); … … 47 51 this.Enabled = false; 48 52 49 PluginManager.Manager.Action += new PluginManagerActionEventHandler(splashScreen.Manager_Action); 50 PluginManager.Manager.Initialize(); 53 pluginManager.Initialize(); 51 54 52 InitializeComponent();53 54 RefreshApplicationsList();55 56 this.Enabled = true;57 this.Visible = true;58 }59 60 private void RefreshApplicationsList() {61 55 applicationsListView.Items.Clear(); 62 56 … … 69 63 applicationsListView.Items.Add(pluginManagerListViewItem); 70 64 71 foreach (Application Info info in PluginManager.Manager.InstalledApplications) {65 foreach (ApplicationDescription info in pluginManager.Applications) { 72 66 ListViewItem item = new ListViewItem(info.Name, 0); 73 67 item.Tag = info; … … 78 72 applicationsListView.Items.Add(item); 79 73 } 74 75 76 this.Enabled = true; 77 this.Visible = true; 80 78 } 81 79 … … 89 87 this.Visible = false; 90 88 form.ShowDialog(this); 91 RefreshApplicationsList();89 // RefreshApplicationsList(); 92 90 this.Visible = true; 93 91 } … … 96 94 } 97 95 } else { 98 Application Info app = (ApplicationInfo)applicationsListView.SelectedItems[0].Tag;96 ApplicationDescription app = (ApplicationDescription)applicationsListView.SelectedItems[0].Tag; 99 97 SplashScreen splashScreen = new SplashScreen(2000, "Loading " + app.Name); 100 98 splashScreen.Owner = this; -
branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs
r2442 r2481 27 27 using System.Reflection; 28 28 using HeuristicLab.PluginInfrastructure; 29 using HeuristicLab.PluginInfrastructure.Manager; 29 30 30 31 namespace HeuristicLab { … … 35 36 private object bigLock = new object(); 36 37 private bool closing = false; 38 private PluginManager manager; 37 39 38 40 public SplashScreen() { 39 41 InitializeComponent(); 42 } 40 43 44 public SplashScreen(PluginManager manager, int initialInterval, string initialText) 45 : this() { 46 this.initialInterval = initialInterval; 47 infoLabel.Text = initialText; 48 this.manager = manager; 49 manager.Action += new PluginManagerActionEventHandler(Manager_Action); 41 50 Assembly assembly = this.GetType().Assembly; 42 51 object[] attributes = assembly.GetCustomAttributes(false); … … 47 56 infoLabel.Text = ""; 48 57 49 foreach (object obj in attributes) {50 if (obj is AssemblyCopyrightAttribute) {58 foreach (object obj in attributes) { 59 if (obj is AssemblyCopyrightAttribute) { 51 60 copyrightLabel.Text = "Copyright " + ((AssemblyCopyrightAttribute)obj).Copyright; 52 61 } … … 57 66 company = HeuristicLab.Properties.Settings.Default.Organization; 58 67 59 if ((user == null) || (user.Equals(""))) {68 if ((user == null) || (user.Equals(""))) { 60 69 userNameLabel.Text = "-"; 61 70 } else { … … 63 72 } 64 73 65 if ((company == null) || (company.Equals(""))) {74 if ((company == null) || (company.Equals(""))) { 66 75 companyLabel.Text = "-"; 67 76 } else { 68 77 companyLabel.Text = company; 69 78 } 70 } catch(Exception) { 79 } 80 catch (Exception) { 71 81 userNameLabel.Text = "-"; 72 82 companyLabel.Text = "-"; 73 83 } 74 }75 76 public SplashScreen(int initialInterval, string initialText)77 : this() {78 this.initialInterval = initialInterval;79 infoLabel.Text = initialText;80 84 } 81 85 … … 86 90 public void Manager_Action(object sender, PluginManagerActionEventArgs e) { 87 91 string info; 88 if(e.Action == PluginManagerAction.Initializing) info = "Initializing ..."; 89 else if(e.Action == PluginManagerAction.InitializingPlugin) info = "Initializing Plugin " + e.Id + " ..."; 90 else if(e.Action == PluginManagerAction.InitializedPlugin) info = "Initializing Plugin " + e.Id + " ... Initialized"; 91 else if(e.Action == PluginManagerAction.Initialized) { 92 if (e.Action == PluginManagerAction.Initializing) info = "Initializing ..."; 93 else if (e.Action == PluginManagerAction.PluginLoaded) info = "Loaded plugin " + e.Id + " ..."; 94 else if (e.Action == PluginManagerAction.Initialized) { 92 95 info = "Initialization Completed"; 93 96 fadeTimer = new System.Timers.Timer(); … … 98 101 fadeTimer.Start(); 99 102 } else { 100 if (e.Id != null) info = e.Action.ToString() + " (" + e.Id + ")";103 if (e.Id != null) info = e.Action.ToString() + " (" + e.Id + ")"; 101 104 else info = e.Action.ToString(); 102 105 } … … 107 110 private void fadeTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { 108 111 fadeTimer.Stop(); 109 if (InvokeRequired) {112 if (InvokeRequired) { 110 113 Invoke((MethodInvoker)UpdateOpacity); 111 114 } else { … … 140 143 closing = true; 141 144 if (fadeTimer != null) fadeTimer.Stop(); 142 PluginManager.Manager.Action -= new PluginManagerActionEventHandler(this.Manager_Action); // remove event before calling close145 manager.Action -= new PluginManagerActionEventHandler(this.Manager_Action); // remove event before calling close 143 146 Application.DoEvents(); // work up all existing events 144 147 Close(); // close
Note: See TracChangeset
for help on using the changeset viewer.