internal static void LoadHotUpdatePlugins() { using (ShadowedCache shadowedCache = new ShadowedCache("Plugins")) { try { var plugins = EncompassHelper.RemoteSession.StartupInfo.Plugins; var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); foreach (var pluginInfo in plugins) { string assemblyPath = shadowedCache.GetFilePath(pluginInfo.Name); string assmName = Path.GetFileNameWithoutExtension(assemblyPath); // The plugin should already be loaded into the assembly cache var appAssm = assemblies.FirstOrDefault(w => w.FullName.Contains(assmName)); if (appAssm != null) { var loadedAssmTypes = appAssm.GetTypes(); var loadedTypesWithAttr = loadedAssmTypes.Where(s => s.GetCustomAttributes(true).Any(a => a.GetType().FullName.Contains("HotUpdatePlugin.Objects.Attributes.HotUpdatePluginAttribute"))); if (loadedTypesWithAttr.Count() > 0) { RunningPlugin rp = new RunningPlugin(); // Load the updated plugin assembly Assembly assembly = RuntimeContext.Current.LoadAssembly(assemblyPath, EncompassHelper.SessionObjects.StartupInfo.RevertPluginChanges); rp.Assembly = assembly; var assmTypes = assembly.GetTypes(); var typesWithAttr = assmTypes.Where(s => s.GetCustomAttributes(true).Any(a => a.GetType().FullName.Contains("HotUpdatePlugin.Objects.Attributes.HotUpdatePluginAttribute"))); List <object> instances = new List <object>(); foreach (Type type in typesWithAttr) { object pluginInstance = type.InvokeMember("", BindingFlags.CreateInstance, null, null, new object[0]); instances.Add(pluginInstance); } rp.Instances = instances; RunningPlugins.Plugins.Add(pluginInfo.Name, rp); } } } } catch (Exception ex) { Logger.HandleError(ex, nameof(PluginLoader), (object)null); } } }
internal static void UpdatePlugin(PluginInfo pluginInfo) { using (ShadowedCache shadowedCache = new ShadowedCache("Plugins")) { Version fileVersion = shadowedCache.GetFileVersion(pluginInfo.Name); Version version = pluginInfo.Version; // Download the latest server plugin and put into the cache if (fileVersion == null || version != fileVersion) { shadowedCache.Put(pluginInfo.Name, EncompassHelper.SessionObjects.ConfigurationManager.GetPluginAssembly(pluginInfo.Name)); } // Dispose of the existing hot updateable plugin RunningPlugins.Plugins.TryGetValue(pluginInfo.Name, out RunningPlugin runningPlugin); if (runningPlugin != null) { foreach (var instance in runningPlugin.Instances) { Type runningType = instance.GetType(); runningType.InvokeMember("Dispose", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, instance, new object[0]); } runningPlugin.Instances = null; runningPlugin.Assembly = null; RunningPlugins.Plugins.Remove(pluginInfo.Name); GC.Collect(); } RunningPlugin rp = new RunningPlugin(); // Load the updated plugin assembly string assemblyPath = shadowedCache.GetFilePath(pluginInfo.Name); Assembly assembly = RuntimeContext.Current.LoadAssembly(assemblyPath, EncompassHelper.SessionObjects.StartupInfo.RevertPluginChanges); rp.Assembly = assembly; var assmTypes = assembly.GetTypes(); var typesWithAttr = assmTypes.Where(s => s.GetCustomAttributes(true).Any(a => a.GetType().FullName.Contains("HotUpdatePlugin.Objects.Attributes.HotUpdatePluginAttribute"))); List <object> instances = new List <object>(); foreach (Type type in typesWithAttr) { object pluginInstance = type.InvokeMember("", BindingFlags.CreateInstance, null, null, new object[0]); instances.Add(pluginInstance); } rp.Instances = instances; RunningPlugins.Plugins.Add(pluginInfo.Name, rp); } }