/// <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 static void Load(List <string> addInFiles, List <string> disabledAddIns) { List <AddIn> list = new List <AddIn>(); Dictionary <string, Version> dict = new Dictionary <string, Version>(); Dictionary <string, AddIn> addInDict = new Dictionary <string, AddIn>(); foreach (string fileName in addInFiles) { AddIn addIn; try { addIn = AddIn.Load(fileName); } catch (AddInLoadException ex) { LoggingService.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(); addIn.addInFileName = fileName; addIn.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) { LoggingService.Error(ex); MessageService.ShowError("Error loading AddIn " + addIn.FileName + ":\n" + ex.Message); } } }