public static PluginDescriptor ParsePluginDescriptionFile(string filePath) { var descriptor = new PluginDescriptor(); var text = File.ReadAllText(filePath); if (String.IsNullOrEmpty(text)) return descriptor; var settings = new List<string>(); using (var reader = new StringReader(text)) { string str; while ((str = reader.ReadLine()) != null) { if (String.IsNullOrWhiteSpace(str)) continue; settings.Add(str.Trim()); } } //Old way of file reading. This leads to unexpected behavior when a user's FTP program transfers these files as ASCII (\r\n becomes \n). //var settings = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (var setting in settings) { var separatorIndex = setting.IndexOf(':'); if (separatorIndex == -1) { continue; } string key = setting.Substring(0, separatorIndex).Trim(); string value = setting.Substring(separatorIndex + 1).Trim(); switch (key) { case "Group": descriptor.Group = value; break; case "FriendlyName": descriptor.FriendlyName = value; break; case "Version": descriptor.Version = value; break; case "SupportedVersions": { //parse supported versions descriptor.SupportedVersions = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .ToList(); } break; case "Author": descriptor.Author = value; break; case "DisplayOrder": { int displayOrder; int.TryParse(value, out displayOrder); descriptor.DisplayOrder = displayOrder; } break; case "FileName": descriptor.PluginFileName = value; break; case "LimitedToStores": { //parse list of store IDs foreach (var str1 in value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim())) { int storeId; if (int.TryParse(str1, out storeId)) { descriptor.LimitedToStores.Add(storeId); } } } break; default: break; } } //nopCommerce 2.00 didn't have 'SupportedVersions' parameter //so let's set it to "2.00" if (descriptor.SupportedVersions.Count == 0) descriptor.SupportedVersions.Add("2.00"); return descriptor; }
public static void SavePluginDescriptionFile(PluginDescriptor plugin) { if (plugin == null) throw new ArgumentException("plugin"); //get the Description.txt file path if (plugin.OriginalAssemblyFile == null) throw new Exception(string.Format("Cannot load original assembly path for {0} plugin.", plugin.Name)); var filePath = Path.Combine(plugin.OriginalAssemblyFile.Directory.FullName, "Description.txt"); if (!File.Exists(filePath)) throw new Exception(string.Format("Description file for {0} plugin does not exist. {1}", plugin.Name, filePath)); var keyValues = new List<KeyValuePair<string, string>>(); keyValues.Add(new KeyValuePair<string, string>("Group", plugin.Group)); keyValues.Add(new KeyValuePair<string, string>("FriendlyName", plugin.FriendlyName)); keyValues.Add(new KeyValuePair<string, string>("Version", plugin.Version)); keyValues.Add(new KeyValuePair<string, string>("SupportedVersions", string.Join(",", plugin.SupportedVersions))); keyValues.Add(new KeyValuePair<string, string>("Author", plugin.Author)); keyValues.Add(new KeyValuePair<string, string>("DisplayOrder", plugin.DisplayOrder.ToString())); keyValues.Add(new KeyValuePair<string, string>("FileName", plugin.PluginFileName)); if (plugin.LimitedToStores.Count > 0) { var storeList = ""; for (int i = 0; i < plugin.LimitedToStores.Count; i++) { storeList += plugin.LimitedToStores[i]; if (i != plugin.LimitedToStores.Count - 1) storeList += ","; } keyValues.Add(new KeyValuePair<string, string>("LimitedToStores", storeList)); } var sb = new StringBuilder(); for (int i = 0; i < keyValues.Count; i++) { var key = keyValues[i].Key; var value = keyValues[i].Value; sb.AppendFormat("{0}: {1}", key, value); if (i != keyValues.Count - 1) sb.Append(Environment.NewLine); } //save the file File.WriteAllText(filePath, sb.ToString()); }
/// <summary> /// 加载插件。 /// </summary> public static IEnumerable<PluginDescriptor> Load() { var installedPluginSystemNames = PluginFileParser.ParseInstalledPluginsFile(GetInstalledPluginsFilePath()); List<PluginDescriptor> plugins = new List<PluginDescriptor>(); if (PluginFolder == null) throw new ArgumentNullException("pluginFolder"); foreach (var pluginFolder in PluginFolder.GetDirectories()) { if (installedPluginSystemNames.Count > 0 && installedPluginSystemNames.Contains(pluginFolder.Name) == false) { continue; } var descriptionFilepath = Path.Combine(pluginFolder.FullName, "Description.txt"); if (File.Exists(descriptionFilepath)) { var pluginDescriptor = PluginFileParser.ParsePluginDescriptionFile(descriptionFilepath); pluginDescriptor.Name = pluginFolder.Name; plugins.Add(pluginDescriptor); } else { var pluginDescriptor = new PluginDescriptor(); pluginDescriptor.Name = pluginFolder.Name; plugins.Add(pluginDescriptor); } } plugins.Sort((firstPair, nextPair) => firstPair.DisplayOrder.CompareTo(nextPair.DisplayOrder)); //程序集复制到临时目录。 CopyToTempPluginFolderDirectory(plugins); //加载 bin 目录下的所有程序集。 IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies(); //加载临时目录下的所有程序集。 var list = TempPluginFolder.GetFiles("*.dll", SearchOption.AllDirectories).Select(x => Assembly.LoadFile(x.FullName)).ToList().FindAll(p => assemblies.Contains(p) == false); list.AddRange(assemblies); InitPlugins(list, plugins); return plugins.Where(p => p.Plugin != null); }
/// <summary> /// 初始化插件。 /// </summary> /// <param name="pluginDescriptor">插件描述</param> private static void Initialize(PluginDescriptor pluginDescriptor) { //使用插件名称做为字典 KEY。 string key = pluginDescriptor.Plugin.Name; //不存在时才进行初始化。 if (!_plugins.ContainsKey(key)) { //初始化。 pluginDescriptor.Plugin.Initialize(); //增加到字典。 _plugins.Add(key, pluginDescriptor); } }
/// <summary> /// 卸载。 /// </summary> public static void Unload(PluginDescriptor pluginDescriptor) { pluginDescriptor.Plugin.Unload(); _plugins.Remove(pluginDescriptor.Plugin.ToString()); }
public int CompareTo(PluginDescriptor other) { if (DisplayOrder != other.DisplayOrder) return DisplayOrder.CompareTo(other.DisplayOrder); return FriendlyName.CompareTo(other.FriendlyName); }