/// @brief Load a plugin from file. /// @details Try to open the XML definition for the plugin from the file name given as /// parameter. Then extract information from the XML (class name, auxiliary references /// and source code to compile), trying to compile the C# source code (based on /// Gear.PluginSupport.PluginCommon class) and returning the new class instance. If the /// compilation fails, then it opens the plugin editor to show errors and source code. /// @param[in] FileName Name and path to the XML plugin file to open /// @returns Reference to the new plugin instance (on success) or NULL (on fail). /// @throws Exception // TODO Modify the method to receive a PluginData, and delete the validation public void LoadPlugin(string FileName) { object objInst = null; //create the structure to fill data from file PluginData pluginCandidate = new PluginData(); //Determine if the XML is valid, and for which DTD version if (!pluginCandidate.ValidatePluginFile(FileName)) { string allMessages = string.Empty; //case not valid file, so show the errors. foreach (string strText in pluginCandidate.ValidationErrors) { allMessages += (strText.Trim() + "\r\n"); } /// @todo Add a custom dialog to show every error message in a grid. //show messages MessageBox.Show(allMessages, "Emulator - OpenPlugin.", MessageBoxButtons.OK, MessageBoxIcon.Error); } else //...XML plugin file is valid & system version is determined { //determine time to use to build the plugin DateTime TimeOfBuild = AssemblyUtils.GetFileDateTime(FileName); for (int i = 0; i < pluginCandidate.UseExtFiles.Length; i++) { if (pluginCandidate.UseExtFiles[i] == true) { TimeOfBuild = DateTime.FromBinary(Math.Max( TimeOfBuild.ToBinary(), AssemblyUtils.GetFileDateTime(pluginCandidate.ExtFiles[i]).ToBinary())); } } //generate the full name of the assembly corresponding to the plugin candidate string candidateAssemblyFullName = pluginCandidate.PluginAssemblyFullName(TimeOfBuild).FullName; //determine the version to look for the correct method to load it switch (pluginCandidate.PluginSystemVersion) { case "0.0": if (PluginPersistence.GetDataFromXML_v0_0(FileName, ref pluginCandidate)) { //Search and replace plugin class declarations for V0.0 plugin // system compatibility. pluginCandidate.Codes[0] = PluginSystem.ReplacePropellerClassV0_0( PluginSystem.ReplaceBaseClassV0_0(pluginCandidate.Codes[0])); } break; case "1.0": PluginPersistence.GetDataFromXML_v1_0(FileName, ref pluginCandidate); objInst = this.Chip; break; default: MessageBox.Show(string.Format("Plugin system version '{0}' not recognized " + "on file \"{1}\".", pluginCandidate.PluginSystemVersion, FileName), "Emulator - Open File.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //add information into plugin's code to generate with assembly attributes pluginCandidate.Codes[0] = PluginSystem.InsertAssemblyDetails( pluginCandidate.Codes[0], TimeOfBuild, pluginCandidate.InstanceName, pluginCandidate.Description, pluginCandidate.PluginVersion); try { //Dynamic load and compile the plugin module as a class, giving the chip // instance as a parameter, and casting to appropriate class PluginCommon plugin = ModuleCompiler.LoadModule( pluginCandidate.Codes, //string[] codeTexts pluginCandidate.ExtFiles, //string[] sourceFiles pluginCandidate.InstanceName, //string module pluginCandidate.References, //string[] references objInst, //object objInstance pluginCandidate.PluginSystemVersion); //string pluginSystemVersion, if (plugin == null) { throw new Exception("Emulator - OpenPlugin: plugin object not generated!" + " (null response from memory loading)."); } else //if success compiling & instantiate the new instance... { //...add to the corresponding plugin list of the emulator instance AttachPlugin(plugin); //update location of last plugin Properties.Settings.Default.LastPlugin = FileName; Properties.Settings.Default.Save(); } } catch (Exception) { //open plugin editor in other window PluginEditor errorPlugin = new PluginEditor(false); if (errorPlugin.OpenFile(FileName, true)) { //remember plugin successfully loaded errorPlugin.UpdateLastPluginOpened(); //show plugin editor loaded with the faultly one errorPlugin.MdiParent = this.MdiParent; //the compilation errors are displayed in the error grid ModuleCompiler.EnumerateErrors(errorPlugin.EnumErrors); //show the error list errorPlugin.ShowErrorGrid(true); errorPlugin.Show(); } } } }