Пример #1
0
        // 根据 existingAddin 的状态,将其 Assets 注册到 ResolutionContext
        AddinResolution DoRegisterExistingAddin(ResolutionResult resolutionResult, ResolutionContext ctx, AddinCollision addinCollision,
                                                AddinRecord existingAddin, AddinOperationStatus operationStatus)
        {
            //AddinRecord addinRecord;
            //if (!AddinRelationManager.TryGetAddin(existingAddin.Guid, out addinRecord))
            //    throw new InconsistentStateException();

            ////AddinRelationManager.RemoveAddin(existingAddin);
            //AddinStorage.Remove(existingAddin);

            //if (operationStatus == AddinOperationStatus.NewOrUpdated)
            //{
            //    var ebs = existingAddin.GetAllExtensionBuilders();
            //    if (ebs != null)
            //    {
            //        foreach (var eb in ebs)
            //        {
            //            if (eb.ExtensionBuilderKind == ExtensionBuilderKind.Declared)
            //                ctx.RegisterExtensionBuilderPath(eb.Uid, eb.GetPath());
            //        }
            //    }
            //    return null;
            //}

            var adnResolution = FromPersistentObject(existingAddin, operationStatus);

            TryRegisterAddin(resolutionResult, ctx, adnResolution, addinCollision);
            DoRegisterExistingAssets(resolutionResult, ctx, adnResolution);
            // if the operation status of an addin not equals to unaffected (i.e, directly/indirectly affected addin), it need to
            // be resolved, so we add it to the addin resolution list.
            return(adnResolution);
            //return operationStatus == AddinOperationStatus.Unaffected ? null : adnResolution;
        }
Пример #2
0
        /// <summary>
        /// Create an <see cref="Addin"/> instance.
        /// </summary>
        /// <param name="addinEngine"></param>
        /// <param name="addinFramework"></param>
        /// <param name="addinRecord"></param>
        internal Addin(AddinEngine addinEngine, AddinFramework addinFramework, AddinRecord addinRecord)
        {
            _addinEngine = addinEngine;
            _addinRecord = addinRecord;

            _addinContext   = new DefaultAddinContext(addinFramework, this);
            _addinRuntime   = new AddinRuntime(addinEngine.RuntimeAssemblyResolver, this);
            _addinFile      = new AddinFile(addinRecord);
            _addinExtension = new AddinExtension(addinRecord, addinEngine, _addinContext);
        }
Пример #3
0
 // if there is any extension points has been loaded for which this addin extends, loads the extension builders and extensions of this addin [addinRecord]
 // that extending the extension point.
 internal void LoadIntoLoadedExtensionPoints(DefaultAddinContext adnContext, AddinRecord addinRecord)
 {
     if (_runtimeExtensionLoader.LoadedExtensionPointCount == 0)
     {
         return;
     }
     for (int i = 0; i < _runtimeExtensionLoader.LoadedExtensionPointCount; i++)
     {
         var loadedExtensionPointRecord = _runtimeExtensionLoader.GetLoadedExtensionPoint(i);
         LoadIntoExtensionPoint(adnContext, loadedExtensionPointRecord);
     }
 }
Пример #4
0
        bool DoRead(Stream stream)
        {
            if (stream.Length < _metadataTable.MinLength + SegmentLength)
            {
                return(false); // 虽然插件数据文件存在,但并未包含有效的数据
            }
            // 1. 读取各个分段的长度
            stream.Position = stream.Length - SegmentLength;
            var addinRecordSegmentLength           = stream.ReadInt64();
            var addinMetadataSegmentLength         = stream.ReadInt64();
            var invalidAddinFilePacksSegmentLength = stream.ReadInt64();
            var dataSegmentLength = stream.ReadInt64();

            if (dataSegmentLength + SegmentLength != stream.Length)
            {
                return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
            }
            // 2. 读取 AddinMetadata 分段 (AddinMetadataTable)
            stream.Position = addinRecordSegmentLength; // 指针指向 AddinMetadata 分段 (AddinMetadataTable) 的起始位置
            var hasAddins = _metadataTable.Read(stream);

            if (!hasAddins || _metadataTable.AddinCount == 0)
            {
                return(false); // 虽然插件数据文件存在,但并未包含有效的数据
            }
            // 3. 根据 AddinMetadata 读取 AddinRecord 分段,并进行验证
            foreach (var metadata in _metadataTable.Addins)
            {
                stream.Position = metadata.Position;
                var addin = new AddinRecord(metadata);
                addin.Read(stream);
                if (stream.Position - metadata.Position != metadata.Length || addin.Uid != metadata.AddinUid)
                {
                    return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
                }
                _addinRecords.Add(addin);
            }

            // 4. 读取 InvalidAddinFilePack 分段
            stream.Position        = addinRecordSegmentLength + addinMetadataSegmentLength; // 指针指向 InvalidAddinFilePack 分段的起始位置
            _invalidAddinFilePacks = RecordHelpers.Read(stream, ref AddinFilePack.Factory);
            if (stream.Position - (addinRecordSegmentLength + addinMetadataSegmentLength) != invalidAddinFilePacksSegmentLength)
            {
                return(false); // 插件数据文件已被破坏,返回 false 以便让系统重新解析插件
            }
            // 5. 读取 Uid 分段
            stream.Position = addinRecordSegmentLength + addinMetadataSegmentLength + invalidAddinFilePacksSegmentLength; // 指针指向 Uid 分段的起始位置
            UidStorage.Read(stream);

            return(true);
        }
        bool TryLoad(AddinRecord addinRecord, AssemblyFileRecord assemblyFileRecord, out AssemblyDefinition result)
        {
            result = null;
            var assemblyPath = GetAbsolutePath(addinRecord, assemblyFileRecord);

            try
            {
                result = AssemblyDefinition.ReadAssembly(assemblyPath, _cecilReaderParameters);
                return(true);
            }
            catch// (Exception e)
            {
                // log
                return(false);
            }
        }
        // Gets the required assembly references for this assembly, which is is provided by the application itself,
        // and it is not the the JointCode.AddIns.dll.
        internal AssemblyDependency[] GetRequiredApplicationAssemblyDependencies(AddinRecord addinRecord)
        {
            if (addinRecord.AssemblyFiles == null || addinRecord.AssemblyFiles.Count == 0)
            {
                return(null);
            }

            var result = new List <AssemblyDependency>();

            foreach (var assemblyFile in addinRecord.AssemblyFiles)
            {
                DoGetRequiredApplicationAssemblyDependencies(addinRecord, assemblyFile, ref result);
            }

            return(result.Count == 0 ? null : result.ToArray());
        }
Пример #7
0
        Addin GetOrCreateAddin(AddinRecord addinRecord)
        {
            Addin result;

            if (_addinFramework.Repository.TryGetAddin(ref addinRecord.AddinId._guid, out result))
            {
                return(result);
            }

            result = new Addin(this, _addinFramework, addinRecord);
            _addinFramework.Repository.AddAddin(result);

            // todo: 如果一个插件的任何一个父插件被停止、禁用,则该插件在启用时,都需要重新解析获取其父插件
            List <Addin> parentAddins = null, childAddins = null;

            var parentAddinRecords = _addinRelationManager.TryGetDependedAddins(addinRecord);

            if (parentAddinRecords != null)
            {
                parentAddins = new List <Addin>();
                foreach (var parentAddinRecord in parentAddinRecords)
                {
                    parentAddins.Add(GetOrCreateAddin(parentAddinRecord));
                }
            }

            var childAddinRecords = _addinRelationManager.TryGetAffectingAddins(addinRecord);

            if (childAddinRecords != null)
            {
                childAddins = new List <Addin>();
                foreach (var childAddinRecord in childAddinRecords)
                {
                    childAddins.Add(GetOrCreateAddin(childAddinRecord));
                }
            }

            result.SetParentAddins(parentAddins);
            result.SetChildAddins(childAddins);

            return(result);
        }
        void DoGetRequiredApplicationAssemblyDependencies(AddinRecord addinRecord, AssemblyFileRecord assemblyFileRecord,
                                                          ref List <AssemblyDependency> result)
        {
            AssemblyDefinition assemblyDef;

            if (!TryLoad(addinRecord, assemblyFileRecord, out assemblyDef))
            {
                return;
            }

            foreach (var module in assemblyDef.Modules)
            {
                if (!module.HasAssemblyReferences)
                {
                    continue;
                }

                foreach (var assemblyReference in module.AssemblyReferences)
                {
                    // if the referenced assembly is provided by runtime (.net, mono, etc) or application itself which can be loaded by probing
                    // mechanism, then the return value is not null; otherwise, returns null.
                    var applicationOrRuntimeAssembly = _assemblyResolver.ResolveAssembly(assemblyReference, _cecilReaderParameters);
                    if (applicationOrRuntimeAssembly == null ||
                        applicationOrRuntimeAssembly.IsRuntimeProvided ||
                        ReferenceEquals(applicationOrRuntimeAssembly.AssemblyDefinition, _thisAssembly))
                    {
                        continue;
                    }

                    // 这是应用程序本身提供的程序集,而且不是 JointCode.AddIns.dll 程序集自身
                    var assemblyDependency = AssemblyDependencyHelper.Create(assemblyReference);
                    if (!result.Contains(assemblyDependency))
                    {
                        result.Add(assemblyDependency);
                    }
                }
            }
        }
Пример #9
0
 internal UnaffectedAddinResolution(AddinRecord old)
 {
     _old            = old;
     OperationStatus = AddinOperationStatus.Unaffected;
 }
Пример #10
0
 internal IndirectlyAffectedAddinResolution(AddinRecord old)
 {
     _old            = old;
     OperationStatus = AddinOperationStatus.IndirectlyAffected;
 }
Пример #11
0
        static AddinRecord ToPersistentObject(AddinResolution adnResolution)
        {
            if (adnResolution.AddinId.Uid == UidStorage.InvalidAddinUid)
            {
                adnResolution.AddinId.Uid = UidStorage.GetNextAddinUid();
            }

            var addinFilePack  = ToAddinFilePack(adnResolution);
            var addinHeader    = ToPersistentObject(adnResolution.AddinHeader);
            var addinActivator = adnResolution.AddinActivator == null ? null : adnResolution.AddinActivator.ToRecord();
            var addinRecord    = new AddinRecord(addinHeader, addinFilePack, addinActivator)
            {
                Enabled = adnResolution.Enabled
            };

            if (adnResolution.ReferencedAssemblySets != null)
            {
                foreach (var referencedAssemblySet in adnResolution.ReferencedAssemblySets)
                {
                    addinRecord.AddReferencedAssembly(new ReferencedAssemblyRecord
                    {
                        Uid     = referencedAssemblySet.Uid,
                        Version = referencedAssemblySet.Version
                    });
                }
            }

            if (adnResolution.ExtendedAddins != null)
            {
                foreach (var extendedAddin in adnResolution.ExtendedAddins)
                {
                    addinRecord.AddExtendedAddin(new ExtendedAddinRecord
                    {
                        Uid     = extendedAddin.AddinId.Uid,
                        Version = extendedAddin.AddinHeader.Version
                    });
                }
            }

            if (adnResolution.ExtendedExtensionPoints != null)
            {
                foreach (var extendedExtensionPoint in adnResolution.ExtendedExtensionPoints)
                {
                    addinRecord.AddExtendedExtensionPoint(extendedExtensionPoint.Uid);
                }
            }

            if (adnResolution.ExtensionPoints != null)
            {
                foreach (var extensionPoint in adnResolution.ExtensionPoints)
                {
                    var epRecord = extensionPoint.ToRecord();
                    addinRecord.AddExtensionPoint(epRecord);
                }
            }

            if (adnResolution.ExtensionBuilderGroups != null)
            {
                foreach (var extensionBuilderGroup in adnResolution.ExtensionBuilderGroups)
                {
                    addinRecord.AddExtensionBuilderGroup(extensionBuilderGroup.ToRecord());
                }
            }

            if (adnResolution.ExtensionGroups != null)
            {
                foreach (var extensionGroup in adnResolution.ExtensionGroups)
                {
                    addinRecord.AddExtensionGroup(extensionGroup.ToRecord());
                }
            }

            return(addinRecord);
        }
Пример #12
0
 internal AddinFile(AddinRecord addinRecord)
 {
     _addinRecord = addinRecord;
 }
 string GetAbsolutePath(AddinRecord addinRecord, AssemblyFileRecord assemblyFileRecord)
 {
     return(Path.Combine(addinRecord.ManifestFile.Directory, assemblyFileRecord.FilePath));
 }
Пример #14
0
 internal AddinExtension(AddinRecord addinRecord, AddinEngine addinEngine, DefaultAddinContext addinContext)
 {
     _addinRecord  = addinRecord;
     _addinEngine  = addinEngine;
     _addinContext = addinContext;
 }
Пример #15
0
 void DoUninstall(AddinRecord addinRecord)
 {
 }