/// <summary> /// Loads a list of .addin files, ensuring that dependencies are satisfied. /// This method is normally called by <see cref="CoreStartup.RunInitialization"/>. /// </summary> /// <param name="addInFiles"> /// The list of .addin file names to load. /// </param> /// <param name="disabledAddIns"> /// The list of disabled AddIn identity names. /// </param> public void Load(List <string> addInFiles, List <string> disabledAddIns) { var list = new List <AddIn>(); var dict = new Dictionary <string, Version>(); var addInDict = new Dictionary <string, AddIn>(); var nameTable = new System.Xml.NameTable(); foreach (string fileName in addInFiles) { AddIn addIn; try { addIn = AddIn.Load(this, fileName, nameTable); } catch (AddInLoadException ex) { Current.Log.Error(ex); if (ex.InnerException != null) { MessageService.ShowError("Error loading AddIn " + fileName + ":\n" + ex.InnerException.Message); } else { MessageService.ShowError("Error loading AddIn " + fileName + ":\n" + ex.Message); } addIn = new AddIn(this) { addInFileName = fileName, CustomErrorMessage = ex.Message }; } if (addIn.Action == AddInAction.CustomError) { list.Add(addIn); continue; } addIn.Enabled = true; if (disabledAddIns != null && disabledAddIns.Count > 0) { foreach (string name in addIn.Manifest.Identities.Keys) { if (disabledAddIns.Contains(name)) { addIn.Enabled = false; break; } } } if (addIn.Enabled) { foreach (KeyValuePair <string, Version> pair in addIn.Manifest.Identities) { if (dict.ContainsKey(pair.Key)) { MessageService.ShowError("Name '" + pair.Key + "' is used by " + "'" + addInDict[pair.Key].FileName + "' and '" + fileName + "'"); addIn.Enabled = false; addIn.Action = AddInAction.InstalledTwice; break; } else { dict.Add(pair.Key, pair.Value); addInDict.Add(pair.Key, addIn); } } } list.Add(addIn); } checkDependencies: for (int i = 0; i < list.Count; i++) { AddIn addIn = list[i]; if (!addIn.Enabled) { continue; } Version versionFound; foreach (AddInReference reference in addIn.Manifest.Conflicts) { if (reference.Check(dict, out versionFound)) { MessageService.ShowError(addIn.Name + " conflicts with " + reference.ToString() + " and has been disabled."); DisableAddin(addIn, dict, addInDict); goto checkDependencies; // after removing one addin, others could break } } foreach (AddInReference reference in addIn.Manifest.Dependencies) { if (!reference.Check(dict, out versionFound)) { if (versionFound != null) { MessageService.ShowError(addIn.Name + " has not been loaded because it requires " + reference.ToString() + ", but version " + versionFound.ToString() + " is installed."); } else { MessageService.ShowError(addIn.Name + " has not been loaded because it requires " + reference.ToString() + "."); } DisableAddin(addIn, dict, addInDict); goto checkDependencies; // after removing one addin, others could break } } } foreach (AddIn addIn in list) { try { InsertAddIn(addIn); } catch (AddInLoadException ex) { Current.Log.Error(ex); MessageService.ShowError("Error loading AddIn " + addIn.FileName + ":\n" + ex.Message); } } }
public static ICondition Read(XmlReader reader, AddIn addIn) { return(new OrCondition(Condition.ReadConditionList(reader, "Or", addIn))); }
public static ICondition Read(XmlReader reader, AddIn addIn) { return(new NegatedCondition(Condition.ReadConditionList(reader, "Not", addIn)[0])); }
public static ICondition[] ReadConditionList(XmlReader reader, string endElement, AddIn addIn) { var conditions = new List <ICondition>(); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.EndElement: if (reader.LocalName == endElement) { return(conditions.ToArray()); } break; case XmlNodeType.Element: switch (reader.LocalName) { case "And": conditions.Add(AndCondition.Read(reader, addIn)); break; case "Or": conditions.Add(OrCondition.Read(reader, addIn)); break; case "Not": conditions.Add(NegatedCondition.Read(reader, addIn)); break; case "Condition": conditions.Add(Condition.Read(reader, addIn)); break; default: throw new AddInLoadException("Invalid element name '" + reader.LocalName + "', entries in a <" + endElement + "> " + "must be <And>, <Or>, <Not> or <Condition>"); } break; } } return(conditions.ToArray()); }