Ejemplo n.º 1
0
        public static PluginInfo LoadPluginFromConfig(string configFile, bool pendingRestart = false)
        {
            //read the file content
            var        fileContent = File.ReadAllText(configFile);
            PluginInfo pluginInfo;

            try
            {
                pluginInfo = JsonConvert.DeserializeObject <PluginInfo>(fileContent);
                if (pluginInfo == null)
                {
                    return(null);//invalid file found
                }
                //ignore any invalid ones
                if (IsNullEmptyOrWhitespace(pluginInfo.SystemName) || IsNullEmptyOrWhitespace(pluginInfo.Name) || IsNullEmptyOrWhitespace(pluginInfo.AssemblyName))
                {
                    return(null);
                }
                //is this plugin version supported?
                if (pluginInfo.SupportedVersions.All(x => !AppVersionEvaluator.IsVersionSupported(x)))
                {
                    return(null);
                }
            }
            catch
            {
                //something must be wrong with the file content. Ignore the file
                return(null);
            }

            var fileInfo = new FileInfo(configFile);

            pluginInfo.PluginDirectory = fileInfo.DirectoryName;
            var assemblyPath = Path.Combine(pluginInfo.PluginDirectory, pluginInfo.AssemblyName);

            if (!File.Exists(assemblyPath))
            {
                throw new System.Exception(
                          $"Can't load the assembly {assemblyPath} for the plugin {pluginInfo.Name} ({pluginInfo.SystemName})");
            }
            var mainAssemblyFileInfo = new FileInfo(assemblyPath);

            //copy the assembly file to bin directory
            SafeFileCopy(mainAssemblyFileInfo, Path.Combine(_binDirectory, mainAssemblyFileInfo.Name));
            var pluginAssembly = Assembly.LoadFile(Path.Combine(_binDirectory, mainAssemblyFileInfo.Name));
            //copy the dependent assemblies
            var dependentAssemblies = GetPluginDirectoryDlls(pluginInfo); //GetDependentAssemblies(pluginAssembly);
            var loadedAssemblies    = AppDomain.CurrentDomain.GetAssemblies();

            foreach (var da in dependentAssemblies)
            {
                if (loadedAssemblies.Any(x => x.FullName == da.Key))
                {
                    continue;
                }
                var dAssemblyPath = Path.Combine(pluginInfo.PluginDirectory, da.Value);
                if (!File.Exists(dAssemblyPath))
                {
                    continue;
                }
                var assemblyFileInfo = new FileInfo(dAssemblyPath);
                var targetPath       = Path.Combine(_binDirectory, da.Value);
                SafeFileCopy(assemblyFileInfo, targetPath);
            }
            //set the assembly to the copied one
            pluginInfo.Assembly   = pluginAssembly;
            pluginInfo.PluginType = TypeFinder.OfType <IPlugin>(pluginAssembly);

            //set startup
            var startupType = TypeFinder.OfType <IAppStartup>(pluginAssembly);

            if (startupType != null)
            {
                pluginInfo.Startup = (IAppStartup)Activator.CreateInstance(startupType);
            }

            //set container
            var diType = TypeFinder.OfType <IDependencyContainer>(pluginAssembly);

            if (diType != null)
            {
                pluginInfo.DependencyContainer = (IDependencyContainer)Activator.CreateInstance(diType);
            }

            _loadedPlugins.Add(pluginInfo);
            pluginInfo.PendingRestart = pendingRestart;

            return(pluginInfo);
        }
Ejemplo n.º 2
0
        public bool HandleZipUpload(byte[] fileBytes)
        {
            //get a temporary file from provided bytes
            var zipFile = _localFileProvider.GetTemporaryFile(fileBytes);

            //get temporary directory to extract the package
            var tempDirectory = _localFileProvider.GetTemporaryDirectory();

            try
            {
                //first extract the zip
                _localFileProvider.ExtractArchive(zipFile, tempDirectory);

                var metaJsonFile = _localFileProvider.CombinePaths(tempDirectory, "meta.json");
                if (!_localFileProvider.FileExists(metaJsonFile))
                {
                    _logger.Log <PluginAccountant>(LogLevel.Error, "Unsupported or damaged package uploaded");
                    return(false);
                }

                var packageMeta =
                    _dataSerializer.DeserializeAs <PackageMeta>(_localFileProvider.ReadAllText(metaJsonFile));
                if (packageMeta?.Items == null || !packageMeta.Items.Any())
                {
                    _logger.Log <PluginAccountant>(LogLevel.Error, "Unsupported or damaged package uploaded");
                    return(false);
                }

                var pluginsDirectory = ServerHelper.MapPath("~/Plugins");
                var themesDirectory  = ServerHelper.MapPath("~/Content/Themes");
                //extract each supported folder to themes and plugins
                foreach (var itemMeta in packageMeta.Items)
                {
                    //skip the version not supported
                    if (!AppVersionEvaluator.IsVersionSupported(itemMeta.SupportedVersion))
                    {
                        continue;
                    }

                    var itemDirectory        = _localFileProvider.CombinePaths(tempDirectory, itemMeta.Path);
                    var destinationDirectory = "";
                    destinationDirectory = _localFileProvider.CombinePaths(
                        packageMeta.Package == PackageMeta.PackageType.Plugin ? pluginsDirectory : themesDirectory,
                        packageMeta.PackageDirectoryName);

                    _localFileProvider.CopyDirectory(itemDirectory, destinationDirectory, true);

                    //load the package
                    var configFile = _localFileProvider.CombinePaths(destinationDirectory, "config.json");
                    if (packageMeta.Package == PackageMeta.PackageType.Plugin)
                    {
                        PluginLoader.LoadPluginFromConfig(configFile, true);
                    }
                    if (packageMeta.Package == PackageMeta.PackageType.Theme)
                    {
                        DependencyResolver.Resolve <IThemeProvider>().LoadTheme(destinationDirectory, true);
                    }
                }

                return(true);
            }
            catch (InvalidDataException ex)
            {
                _logger.Log <PluginAccountant>(LogLevel.Error, "The package doesn't appear to be a valid zip file.", ex);
                return(false);
            }
            catch (Exception ex)
            {
                _logger.Log <PluginAccountant>(LogLevel.Error, ex.Message, ex);
                return(false);
            }
            finally
            {
                _localFileProvider.DeleteDirectory(tempDirectory, true);
                _localFileProvider.DeleteFile(zipFile);
            }
        }