private void CreateNewBamlResourceIfNeeded(bool areCollectedStreamsWritten, BamlStreamCollector bamlStreamCollector) { // if there weren't any (BAML) resources in the original assembly, then we need to create a new resource if (areCollectedStreamsWritten || !bamlStreamCollector.HasBamlStreams) { return; } string resourceName = _repackContext.PrimaryAssemblyDefinition.Name.Name + ".g.resources"; EmbeddedResource resource = new EmbeddedResource(resourceName, ManifestResourceAttributes.Public, new byte[0]); var output = new MemoryStream(); var rw = new ResourceWriter(output); // do a final processing, if any, on the embeddedResource itself bamlStreamCollector.Process(resource, rw); rw.Generate(); output.Position = 0; _targetAssemblyMainModule.Resources.Add( new EmbeddedResource(resource.Name, resource.Attributes, output)); }
public void Perform() { _logger.Info("Processing resources"); // merge resources IEnumerable <string> repackList = new List <string>(); Dictionary <string, List <int> > ikvmExportsLists = new Dictionary <string, List <int> >(); if (!_options.NoRepackRes) { repackList = _repackContext.MergedAssemblies.Select(a => a.FullName).ToList(); } bool areCollectedStreamsWritten = false; var bamlStreamCollector = new BamlStreamCollector(_logger, _repackContext); var bamlResourcePatcher = new BamlResourcePatcher(_repackContext); var commonProcessors = new List <IResProcessor> { new StringResourceProcessor(_repackContext), new GenericResourceProcessor(_repackContext) }; var primaryAssemblyProcessors = new[] { bamlResourcePatcher }.Union(commonProcessors).ToList(); var otherAssemblyProcessors = new List <IResProcessor> { bamlResourcePatcher, bamlStreamCollector }.Union(commonProcessors).ToList(); // Primary Assembly *must* be the last one in order to properly gather the resources // from dependencies var assembliesList = _repackContext.OtherAssemblies.Concat(new[] { _repackContext.PrimaryAssemblyDefinition }); foreach (var assembly in assembliesList) { bool isPrimaryAssembly = assembly == _repackContext.PrimaryAssemblyDefinition; var assemblyProcessors = isPrimaryAssembly ? primaryAssemblyProcessors : otherAssemblyProcessors; foreach (var resource in assembly.Modules.SelectMany(x => x.Resources)) { if (resource.Name == ILRepackListResourceName) { if (!_options.NoRepackRes && resource is EmbeddedResource) { repackList = repackList.Union(GetRepackListFromResource((EmbeddedResource)resource)); } } else if (resource.Name == "ikvm.exports") { if (resource is EmbeddedResource) { ikvmExportsLists = MergeIkvmExports( ikvmExportsLists, GetIkvmExportsListsFromResource((EmbeddedResource)resource)); } } else { if (!_options.AllowDuplicateResources && _targetAssemblyMainModule.Resources.Any(x => x.Name == resource.Name)) { // Not much we can do about 'ikvm__META-INF!MANIFEST.MF' _logger.Warn("Ignoring duplicate resource " + resource.Name); } else { _logger.Verbose("- Importing " + resource.Name); var newResource = resource; switch (resource.ResourceType) { case ResourceType.AssemblyLinked: // TODO _logger.Warn("AssemblyLinkedResource reference may need to be fixed (to link to newly created assembly)" + resource.Name); break; case ResourceType.Linked: // TODO ? (or not) break; case ResourceType.Embedded: var er = (EmbeddedResource)resource; if (er.Name.EndsWith(".resources")) { // we don't want to write the bamls to other embedded resource files bool shouldWriteCollectedBamlStreams = isPrimaryAssembly && $"{assembly.Name.Name}.g.resources".Equals(er.Name); if (shouldWriteCollectedBamlStreams) { areCollectedStreamsWritten = true; } newResource = FixResxResource(assembly, er, assemblyProcessors, shouldWriteCollectedBamlStreams ? bamlStreamCollector : null); } break; } _targetAssemblyMainModule.Resources.Add(newResource); } } } } if (ikvmExportsLists.Count > 0) { _targetAssemblyMainModule.Resources.Add( GenerateIkvmExports(ikvmExportsLists)); } if (!_options.NoRepackRes) { _targetAssemblyMainModule.Resources.Add( GenerateRepackListResource(repackList.ToList())); } CreateNewBamlResourceIfNeeded(areCollectedStreamsWritten, bamlStreamCollector); }