// 根据 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; }
/// <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); }
// 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); } }
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()); }
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); } } } }
internal UnaffectedAddinResolution(AddinRecord old) { _old = old; OperationStatus = AddinOperationStatus.Unaffected; }
internal IndirectlyAffectedAddinResolution(AddinRecord old) { _old = old; OperationStatus = AddinOperationStatus.IndirectlyAffected; }
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); }
internal AddinFile(AddinRecord addinRecord) { _addinRecord = addinRecord; }
string GetAbsolutePath(AddinRecord addinRecord, AssemblyFileRecord assemblyFileRecord) { return(Path.Combine(addinRecord.ManifestFile.Directory, assemblyFileRecord.FilePath)); }
internal AddinExtension(AddinRecord addinRecord, AddinEngine addinEngine, DefaultAddinContext addinContext) { _addinRecord = addinRecord; _addinEngine = addinEngine; _addinContext = addinContext; }
void DoUninstall(AddinRecord addinRecord) { }