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);
            }
        }
Exemplo n.º 2
0
        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();
            }
        }