using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; namespace ScreenConnect; [AttributeUsage(AttributeTargets.Assembly)] public sealed class PluginAttribute : Attribute { private static readonly object syncLock = new object(); private static List pluginAssemblies; public static IEnumerable GetPluginAssemblies() { if (pluginAssemblies == null) { lock (syncLock) { if (pluginAssemblies == null) { pluginAssemblies = LoadPlugins(); } } } return pluginAssemblies; } private static List LoadPlugins() { List plugins = new List(); ResolveEventHandler value = (object sender, ResolveEventArgs args) => Assembly.ReflectionOnlyLoad(args.Name); AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += value; try { Assembly[] array = (from it in AppDomain.CurrentDomain.GetAssemblies() where !it.IsDynamicX() select it).ToArray(); string[] privateAssemblyFilePaths = Singleton.Instance.GetPrivateAssemblyFilePaths(); byte[] mainAssemblyPublicKey = null; Assembly[] array2 = array; foreach (Assembly loadedAssembly in array2) { Extensions.Try(delegate { if (loadedAssembly.GetCustomAttributes(typeof(PluginAttribute), inherit: true).Length != 0) { plugins.Add(loadedAssembly); } }); } HashSet loadedAssemblyFileNames = array.Select((Assembly it) => it.Location).WhereNotNullOrEmpty().Select(Path.GetFullPath) .Select(Path.GetFileName) .ToHashSet(StringComparer.OrdinalIgnoreCase); string[] array3 = privateAssemblyFilePaths; foreach (string pluginAssemblyFilePath in array3) { string pluginAssemblyFileName = Path.GetFileName(pluginAssemblyFilePath); if (loadedAssemblyFileNames.Contains(pluginAssemblyFileName)) { continue; } Extensions.Try(delegate { Assembly assembly = Assembly.ReflectionOnlyLoad(File.ReadAllBytes(pluginAssemblyFilePath)); loadedAssemblyFileNames.Add(pluginAssemblyFileName); if (mainAssemblyPublicKey == null) { mainAssemblyPublicKey = typeof(Constants).Assembly.GetName().GetPublicKey(); } if (assembly.GetName().GetPublicKey().SequenceRangeEquals(mainAssemblyPublicKey, mainAssemblyPublicKey.Length) && CustomAttributeData.GetCustomAttributes(assembly).Any((CustomAttributeData a) => a.Constructor.DeclaringType.Assembly.Location == typeof(PluginAttribute).Assembly.Location)) { Assembly item = Assembly.Load(assembly.GetName()); plugins.Add(item); } }); } } finally { AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= value; } return plugins; } }