So, to add properly a reference into a given .csproj here's what I do:
var CsprojDoc = new XmlDocument(); CsprojDoc.LoadXml("*your_csproj_content*"); var Nsmgr = new XmlNamespaceManager(CsprojDoc.NameTable); Nsmgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003"); IPackage packageInfos = GetNugetPackage(packageId, packageRepositoryUri); XmlNode referenceNode = CsprojDoc.CreateNode(XmlNodeType.Element, "Reference", XmlNamespaceValue); XmlAttribute includeAttribute = CsprojDoc.CreateAttribute("Include"); var targetFwProfile = CsprojDoc.SelectSingleNode("//x:TargetFrameworkProfile", Nsmgr); string targetFrameworkProfile = string.Empty; if (!string.IsNullOrEmpty(targetFwProfile?.InnerXml)) { targetFrameworkProfile = targetFwProfile.InnerXml; } var targetFwAttribute = GetTargetFrameworkFromCsproj(); Regex p = new Regex(@"\d+(\.\d+)+"); Match m = p.Match(targetFwAttribute.FrameworkName); Version targetFwVersion = Version.Parse(m.Value); // Get the package's assembly reference matching the target framework from the given '.csproj'. var assemblyReference = packageInfos.AssemblyReferences .Where(a => a.TargetFramework.Identifier.Equals(targetFwAttribute.FrameworkName.Split(',').First())) .Where(a => a.TargetFramework.Profile.Equals(targetFrameworkProfile)) .Last(a => (a.TargetFramework.Version.Major.Equals(targetFwVersion.Major) && a.TargetFramework.Version.Minor.Equals(targetFwVersion.Minor)) || a.TargetFramework.Version.Major.Equals(targetFwVersion.Major)); DownloadNugetPackage(packageInfos.Id, packageRepositoryUri, packagesFolderPath, packageInfos.Version.ToFullString()); string dllAbsolutePath = Path.GetFullPath($"{packagesFolderPath}\\{packageInfos.GetFullName().Replace(' ', '.')}\\{assemblyReference.Path}"); var assemblyInfos = Assembly.LoadFile(dllAbsolutePath); includeAttribute.Value = $"{assemblyInfos.FullName}, processorArchitecture=MSIL"; referenceNode.Attributes.Append(includeAttribute); XmlNode hintPathNode = CsprojDoc.CreateNode(XmlNodeType.Element, "HintPath", XmlNamespaceValue); XmlNode privateNode = CsprojDoc.CreateNode(XmlNodeType.Element, "Private", XmlNamespaceValue); hintPathNode.InnerXml = $"$(SolutionDir)\\packages\\{assemblyReference.Path}"; privateNode.InnerXml = "True"; referenceNode.AppendChild(hintPathNode); referenceNode.AppendChild(privateNode); var itemGroupNode = CsprojDoc.SelectSingleNode("//x:Project/x:ItemGroup/x:Reference", Nsmgr).ParentNode; itemGroupNode.AppendChild(referenceNode);
Here's my DownloadNugetPackage method:
private static void DownloadNugetPackage(string packageId, Uri repoUri, string packagesFolderPath, string version) { IPackageRepository packageRepository = PackageRepositoryFactory.Default.CreateRepository(repoUri.ToString()); PackageManager packageManager = new PackageManager(packageRepository, packagesFolderPath); packageManager.InstallPackage(packageId, SemanticVersion.Parse(version)); }
My GetTargetFrameworkFromCsproj
public static TargetFrameworkAttribute GetTargetFrameworkFromCsproj() { XmlNode targetFrameworkNode = CsprojDoc.SelectSingleNode("//x:TargetFrameworkVersion", Nsmgr); return new TargetFrameworkAttribute($".NETFramework, Version={targetFrameworkNode.InnerXml}"); }
And my GetNugetPackage method:
public static IPackage GetNugetPackage(string packageId, Uri repoUri, string version = null) { IPackageRepository packageRepository = PackageRepositoryFactory.Default.CreateRepository(repoUri.ToString()); IPackage package; if (!string.IsNullOrEmpty(version)) { package = packageRepository.FindPackagesById(packageId).SingleOrDefault(p => p.Version.ToFullString().Equals(version)); } else { package = packageRepository.FindPackagesById(packageId).SingleOrDefault(p => p.IsLatestVersion); } return package; }
Note: This time, I'm using the official NuGet package: Nuget.core 2.14: https://www.nuget.org/packages/NuGet.Core/
Note 2: When I add a new Reference node, in the processorArchitecture attribute, I've hardcoded the value: MSIL
If you want to test it, you might tweak it a bit.
This worked fine for me.