Итак, чтобы правильно добавить ссылку в данный .csproj
, вот что я делаю:
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);
Вот мой DownloadNugetPackage
метод:
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));
}
Мой GetTargetFrameworkFromCsproj
public static TargetFrameworkAttribute GetTargetFrameworkFromCsproj()
{
XmlNode targetFrameworkNode = CsprojDoc.SelectSingleNode("//x:TargetFrameworkVersion", Nsmgr);
return new TargetFrameworkAttribute($".NETFramework, Version={targetFrameworkNode.InnerXml}");
}
И мой GetNugetPackage
метод:
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;
}
Примечание: на этот раз я использую официальный пакет NuGet: Nuget.core 2.14 : https://www.nuget.org/packages/NuGet.Core/
Примечание 2. При добавлении нового узла Reference
в атрибуте processorArchitecture
я жестко закодировал значение: MSIL
Если вы хотите протестировать его, вы можете немного его настроить.
Это хорошо сработало для меня.