Esempio n. 1
0
        /// <summary>
        /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
        /// and excluding the ones passed in and excluding the exclusion list filter, the results of this are
        /// cached for performance reasons.
        /// </summary>
        /// <param name="excludeFromResults">
        /// An <see cref="IEnumerable{Assembly}"/> to exclude.
        /// </param>
        /// <returns>The collection of local assemblies.</returns>
        internal static HashSet <Assembly> GetAssembliesWithKnownExclusions(
            IEnumerable <Assembly> excludeFromResults = null)
        {
            using (var locker = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker))
            {
                if (LocalFilteredAssemblyCache.Count > 0)
                {
                    return(LocalFilteredAssemblyCache);
                }

                locker.UpgradeToWriteLock();

                foreach (Assembly assembly in GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter))
                {
                    LocalFilteredAssemblyCache.Add(assembly);
                }

                return(LocalFilteredAssemblyCache);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan 
        /// and excluding the ones passed in and excluding the exclusion list filter, the results of this are
        /// cached for performance reasons.
        /// </summary>
        /// <param name="excludeFromResults">
        /// An <see cref="IEnumerable{Assembly}"/> to exclude.
        /// </param>
        /// <returns>The collection of local assemblies.</returns>
        internal static HashSet<Assembly> GetAssembliesWithKnownExclusions(
            IEnumerable<Assembly> excludeFromResults = null)
        {
            using (UpgradeableReadLock locker = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker))
            {
                if (LocalFilteredAssemblyCache.Any())
                {
                    return LocalFilteredAssemblyCache;
                }

                locker.UpgradeToWriteLock();

                IEnumerable<Assembly> assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
                foreach (Assembly assembly in assemblies)
                {
                    LocalFilteredAssemblyCache.Add(assembly);
                }

                return LocalFilteredAssemblyCache;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Lazily loads a reference to all assemblies and only local assemblies.
        /// This is a modified version of: 
        /// <see href="http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder"/>
        /// </summary>
        /// <remarks>
        /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been 
        /// loaded in the CLR, not all assemblies.
        /// See these threads:
        /// <see href="http://issues.umbraco.org/issue/U5-198"/>
        /// <see href="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/>
        /// <see href="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/>
        /// </remarks>
        /// <returns>
        /// The <see cref="HashSet{Assembly}"/>.
        /// </returns>
        internal static HashSet<Assembly> GetAllAssemblies()
        {
            using (UpgradeableReadLock locker = new UpgradeableReadLock(Locker))
            {
                if (allAssemblies == null)
                {
                    locker.UpgradeToWriteLock();

                    try
                    {
                        // NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have
                        // already been loaded in to the app domain, instead we will look directly into the bin folder and load each one.
                        string binFolder = IOHelper.GetRootDirectoryBinFolder();
                        List<string> binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
                        HashSet<Assembly> assemblies = new HashSet<Assembly>();

                        foreach (string file in binAssemblyFiles)
                        {
                            try
                            {
                                AssemblyName assemblyName = AssemblyName.GetAssemblyName(file);
                                assemblies.Add(Assembly.Load(assemblyName));
                            }
                            catch (Exception ex)
                            {
                                if (ex is SecurityException || ex is BadImageFormatException)
                                {
                                    // Swallow exception but allow debugging.
                                    Debug.WriteLine(ex.Message);
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }

                        // If for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
                        if (!assemblies.Any())
                        {
                            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                            {
                                assemblies.Add(assembly);
                            }
                        }

                        // Here we are trying to get the App_Code assembly
                        string[] fileExtensions = { ".cs", ".vb" };
                        DirectoryInfo appCodeFolder = new DirectoryInfo(IOHelper.MapPath("~/App_code"));

                        // Check if the folder exists and if there are any files in it with the supported file extensions
                        if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any()))
                        {
                            Assembly appCodeAssembly = Assembly.Load("App_Code");
                            if (!assemblies.Contains(appCodeAssembly))
                            {
                                assemblies.Add(appCodeAssembly);
                            }
                        }

                        // Now set the allAssemblies
                        allAssemblies = new HashSet<Assembly>(assemblies);
                    }
                    catch (InvalidOperationException e)
                    {
                        if (!(e.InnerException is SecurityException))
                        {
                            throw;
                        }

                        binFolderAssemblies = allAssemblies;
                    }
                }

                return allAssemblies;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Lazily loads a reference to all assemblies and only local assemblies.
        /// This is a modified version of:
        /// <see href="http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder"/>
        /// </summary>
        /// <remarks>
        /// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
        /// loaded in the CLR, not all assemblies.
        /// See these threads:
        /// <see href="http://issues.umbraco.org/issue/U5-198"/>
        /// <see href="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/>
        /// <see href="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/>
        /// </remarks>
        /// <returns>
        /// The <see cref="HashSet{Assembly}"/>.
        /// </returns>
        internal static HashSet <Assembly> GetAllAssemblies()
        {
            using (UpgradeableReadLock locker = new UpgradeableReadLock(Locker))
            {
                if (allAssemblies == null)
                {
                    locker.UpgradeToWriteLock();

                    try
                    {
                        // NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have
                        // already been loaded in to the app domain, instead we will look directly into the bin folder and load each one.
                        string             binFolder        = IOHelper.GetRootDirectoryBinFolder();
                        List <string>      binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
                        HashSet <Assembly> assemblies       = new HashSet <Assembly>();

                        foreach (string file in binAssemblyFiles)
                        {
                            try
                            {
                                AssemblyName assemblyName = AssemblyName.GetAssemblyName(file);
                                assemblies.Add(Assembly.Load(assemblyName));
                            }
                            catch (Exception ex)
                            {
                                if (ex is SecurityException || ex is BadImageFormatException || ex is IOException)
                                {
                                    // Swallow exception but allow debugging.
                                    Debug.WriteLine(ex.Message);
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }

                        // If for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
                        if (!assemblies.Any())
                        {
                            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                            {
                                assemblies.Add(assembly);
                            }
                        }

                        // Here we are trying to get the App_Code assembly
                        string[]      fileExtensions = { ".cs", ".vb" };
                        DirectoryInfo appCodeFolder  = new DirectoryInfo(IOHelper.MapPath("~/App_code"));

                        // Check if the folder exists and if there are any files in it with the supported file extensions
                        if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any()))
                        {
                            Assembly appCodeAssembly = Assembly.Load("App_Code");
                            if (!assemblies.Contains(appCodeAssembly))
                            {
                                assemblies.Add(appCodeAssembly);
                            }
                        }

                        // Now set the allAssemblies
                        allAssemblies = new HashSet <Assembly>(assemblies);
                    }
                    catch (InvalidOperationException e)
                    {
                        if (!(e.InnerException is SecurityException))
                        {
                            throw;
                        }

                        binFolderAssemblies = allAssemblies;
                    }
                }

                return(allAssemblies);
            }
        }