public void Process(ProjectProcessorContext context) { var doc = context.Document; var fullPath = context.Project.FullPath; // Remove .Windows (if any) fullPath = fullPath.Replace(".Windows", string.Empty); // Add current platform instead fullPath = Path.Combine(Path.GetDirectoryName(fullPath), Path.GetFileNameWithoutExtension(fullPath) + "." + projectType + Path.GetExtension(fullPath)); if (File.Exists(fullPath)) { // Already exists, let's synchronize! context.Modified = true; // First, let's load project var newDoc = XDocument.Load(fullPath); var ns = newDoc.Root.Name.Namespace; var mgr = new XmlNamespaceManager(new NameTable()); mgr.AddNamespace("x", ns.NamespaceName); // Let's load ItemGroup items from previous and new items var oldItemGroups = doc.XPathSelectElements("/x:Project/x:ItemGroup", context.NamespaceManager).ToArray(); var newItemGroups = newDoc.XPathSelectElements("/x:Project/x:ItemGroup", mgr).ToArray(); // Remove non-tagged item from new document foreach (var itemGroup in newItemGroups) { var nonTaggedElements = GetUserElements(itemGroup); foreach (var nonTaggedElement in nonTaggedElements) { nonTaggedElement.Remove(); } } // Copy back non-tagged item from old document // Try to insert in second ItemGroup (usually first one is Reference) var insertionItemGroup = newItemGroups.Length >= 2 ? newItemGroups[1] : newItemGroups[0]; foreach (var itemGroup in oldItemGroups) { var nonTaggedElements = GetUserElements(itemGroup); foreach (var nonTaggedElement in nonTaggedElements) { var element = new XElement(nonTaggedElement); // fixup namespace (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/how-to-change-the-namespace-for-an-entire-xml-tree) foreach (var el in element.DescendantsAndSelf()) { el.Name = ns.GetName(el.Name.LocalName); var atList = el.Attributes().ToList(); } insertionItemGroup.Add(element); } } // Clear empty item groups foreach (var itemGroup in newItemGroups.ToArray()) { if (!itemGroup.HasElements) { itemGroup.Remove(); } } // Set newly generated document context.Document = newDoc; } }
public void Process(ProjectProcessorContext context) { var doc = context.Document; var ns = context.Document.Root.Name.Namespace; var fullPath = context.Project.FullPath; // Remove .Windows (if any) fullPath = fullPath.Replace(".Windows", string.Empty); // Add current platform instead fullPath = Path.Combine(Path.GetDirectoryName(fullPath), Path.GetFileNameWithoutExtension(fullPath) + "." + projectType + Path.GetExtension(fullPath)); if (File.Exists(fullPath)) { // Already exists, let's synchronize! context.Modified = true; // First, let's load project var newDoc = XDocument.Load(fullPath); // Let's load ItemGroup items from previous and new items var oldItemGroups = doc.XPathSelectElements("/x:Project/x:ItemGroup", context.NamespaceManager).ToArray(); var newItemGroups = newDoc.XPathSelectElements("/x:Project/x:ItemGroup", context.NamespaceManager).ToArray(); // Remove non-tagged item from new document foreach (var itemGroup in newItemGroups) { var nonTaggedElements = GetUserElements(itemGroup); foreach (var nonTaggedElement in nonTaggedElements) { nonTaggedElement.Remove(); } } // Copy back non-tagged item from old document // Try to insert in second ItemGroup (usually first one is Reference) var insertionItemGroup = newItemGroups.Length >= 2 ? newItemGroups[1] : newItemGroups[0]; foreach (var itemGroup in oldItemGroups) { var nonTaggedElements = GetUserElements(itemGroup); foreach (var nonTaggedElement in nonTaggedElements) { insertionItemGroup.Add(new XElement(nonTaggedElement)); } } // Clear empty item groups foreach (var itemGroup in newItemGroups.ToArray()) { if (!itemGroup.HasElements) { itemGroup.Remove(); } } if (projectType == ProjectType.iOS) { // Remove ProjectReference/Private (seems they cause problem for iOS deployment of unit tests) foreach (var projectReferencePrivate in newDoc.XPathSelectElements("/x:Project/x:ItemGroup/x:ProjectReference/x:Private", context.NamespaceManager).ToArray()) { projectReferencePrivate.Remove(); } } // Set newly generated document context.Document = newDoc; } }