internal LoaderAssemblyExtension(string path) : base(path) { var dd = Loader.CreateAssemblyDescriber(); var describer = dd.Item2; try { _assemblyName = describer.LoadFrom(path); TypeDescriptor[] assemblyTypes = null; if (GetAssemblyName() != null) { foreach (var missing in describer.GetReferencedAssemblies(GetAssemblyName()) .Where(x => Loader.FindAssemblyPath(x) == null && !GAC.IsInGAC(x)) .ToList()) { AddMissingDependency(missing); } if (MissingDependencies.Count > 0) { return; } assemblyTypes = describer.GetTypes(GetAssemblyName()); } if (assemblyTypes == null || assemblyTypes.Length == 0) { throw new NotAnExtensionException(); } // TODO: check thumbprint of assembly instead of path if (Path.Contains("Test\\Extensions")) { var permissions = new PermissionSet(PermissionState.Unrestricted); //permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.RemotingConfiguration)); //permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.NoFlags)); //permissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); //permissions.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, // Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))); //permissions.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, // Environment.GetFolderPath(Environment.SpecialFolder.MyComputer))); //permissions.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE")); //permissions.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_CURRENT_USER")); //permissions.AddPermission(new RegistryPermission(RegistryPermissionAccess.Write, "HKEY_CURRENT_USER\\Software\\twomindseye\\Commando\\extensions")); var setup = new AppDomainSetup(); setup.ApplicationBase = Loader.EngineDirectory; _domain = AppDomain.CreateDomain("Extension: " + _assemblyName.FullName, null, setup, permissions); _clientSponsor = new ClientSponsor(); Loader.InitDomainLoader(_domain); } Description = describer.GetAssemblyTitle(GetAssemblyName()) ?? System.IO.Path.GetFileName(Path); Initialize(describer, assemblyTypes); } finally { AppDomain.Unload(dd.Item1); } }
static void Refresh() { var loaded = new ConcurrentBag <LoaderExtension>(); lock (s_refreshLock) { var items = (from directory in s_directories from path in Directory.EnumerateFiles(directory) where IsExtensionPath(path) let existing = Extensions.FirstOrDefault(x => x.Path == path) where existing == null || !existing.IsReady || existing.IsUpdated(path) let isScript = Path.GetExtension(path).ToLower() == ".js" orderby isScript select new { Existing = existing, Path = path, IsScript = isScript }).ToArray(); #if NO var dd = CreateAssemblyDescriber(); try { var names = new Dictionary <string, AssemblyName>(); var dependencies = new Dictionary <string, AssemblyName[]>(); foreach (var item in items.Where(x => !x.IsScript)) { var name = dd.Item2.LoadFrom(item.Path); names[item.Path] = name; dependencies[item.Path] = dd.Item2.GetReferencedAssemblies(name).Where(x => !GAC.IsInGAC(x)).ToArray(); } foreach (var item in items.Where(x => !x.IsScript)) { var itemDependencies = dependencies[item.Path]; if (itemDependencies.Any(x => FindAssemblyPath(x) == null)) { // TODO: can't load this one continue; } // trim down dependencies to those we're about to load itemDependencies = dependencies[item.Path] = dependencies[item.Path] .Intersect(names.Values, TypeDescriptor.AssemblyNameComparer) .ToArray(); } var loadOrder = new List <string>(); loadOrder.AddRange(dependencies.Where(x => x.Value.Length == 0).Select(x => x.Key)); foreach (var item in dependencies.Where(x => x.Value.Length > 0).OrderBy(x => x.Value.Length)) { } } finally { AppDomain.Unload(dd.Item1); } #endif Parallel.ForEach(items, item => { if (item.Existing != null && item.Existing.IsReady) { item.Existing.Unload(); } var extension = Load(item.Path, loaded.ToList()); if (extension != null) { lock (loaded) { if (!IsExtensionLoaded(extension, loaded.ToList())) { loaded.Add(extension); } } } }); var loadedList = loaded.ToList(); Parallel.ForEach(loaded, extension => { // perf check if (!IsExtensionLoaded(extension, Extensions) && extension.OnLoadCompleting(loadedList)) { lock (s_extensions) { // definitive check if (!IsExtensionLoaded(extension, Extensions)) { s_extensions.Add(extension); } } } }); foreach (var extension in loaded) { extension.OnLoadComplete(); } } if (!loaded.IsEmpty) { FireLoadComplete(); } }