/// <summary> /// Returns true if a new file was generated, false if an existing one is returned. /// </summary> /// <param name="baseOutputDir"></param> /// <param name="publicKeyData"></param> /// <param name="signedTaskItem"></param> /// <returns></returns> public bool TrySign(string baseOutputDir, PublicKeyData publicKeyData, out ITaskItem signedTaskItem) { if (IsSigned) { signedTaskItem = InitialTaskItem; return(false); } // Replace the assemblydefinition with an open one for the duration of the write calls. using (_assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(InitialTaskItem.ItemSpec, GetReaderParameters())) { var outputFile = GetOutputFile(baseOutputDir); signedTaskItem = new TaskItem(InitialTaskItem) { ItemSpec = outputFile }; if (File.Exists(outputFile)) { // If the file already exists, assume we already fixed it up correctly. return(false); } SetPublicKeyTokenOnReferences(publicKeyData.PublicKeyToken); FixInternalsVisibleTo(publicKeyData); try { _assemblyDefinition.Write(outputFile, GetWriterParameters(publicKeyData.StrongNameKeyPair)); } catch (Exception e) { Debugger.Launch(); } return(true); } }
private void FixInternalsVisibleTo(PublicKeyData publicKeyData) { var internalsVisibleToAttributes = _assemblyDefinition.CustomAttributes.Where(attr => attr.AttributeType.FullName == typeof(InternalsVisibleToAttribute).FullName).ToList(); foreach (var att in internalsVisibleToAttributes) { // TODO [DaS] Assume for now that InternalsVisibleToAttribute is only used // for tests. The problem here is that we need a list of assembly name to public key token // since unsigned assemblies generally don't add the public key token when // setting the InternalsVisibleToAttribute. _assemblyDefinition.CustomAttributes.Remove(att); //if (att.ConstructorArguments.Count != 1) //{ // throw new InvalidOperationException("InternalsVisibleToAttribute does not have a single constructor argument."); //} //var assemblyNameArgument = att.ConstructorArguments.First(); //var assemblyName = (string) assemblyNameArgument.Value; //if (!assemblyName.Contains("PublicKey")) //{ // assemblyName = $"{assemblyName},PublicKey={publicKeyData.PublicKeyTokenAsString}"; // att.ConstructorArguments.Clear(); // att.ConstructorArguments.Add(new CustomAttributeArgument(assemblyNameArgument.Type, assemblyName)); //} } }
private void SignAllAssemblies() { // If this is renamed also fix the reference in the cleanup task in Das.StrongNameSigner.targets var signedAssemblyDirectory = Path.Combine(OutputPath.ItemSpec, "DaS.StrongNameSigner"); var copyLocalReferencesDirectory = Path.Combine(signedAssemblyDirectory, "copyLocalReferences"); var referencesDirectory = Path.Combine(signedAssemblyDirectory, "references"); CreateDirectoryIfNotExists(signedAssemblyDirectory); CreateDirectoryIfNotExists(copyLocalReferencesDirectory); CreateDirectoryIfNotExists(referencesDirectory); _publicKeyData = GetPublicKeyData(); _probingPaths = References.Union(ReferenceCopyLocalPaths) .Select(reference => Path.GetDirectoryName(reference.ItemSpec)) .ToImmutableList(); _assemblyResolver = GetAssemblyResolver(); SignedReferenceCopyLocalPaths = ReferenceCopyLocalPaths .Select(reference => SignAssembly(copyLocalReferencesDirectory, reference)) .ToArray(); SignedReferences = References .Select(reference => SignAssembly(referencesDirectory, reference)) .ToArray(); }