Автоматическое исправление ProjectReference Включить пути перед созданием файла csproj - PullRequest
4 голосов
/ 04 октября 2011

У меня есть решение VS 2010 с несколькими проектами.Проекты ссылаются на другие проекты в рамках решения.Я заметил, что когда у меня неправильный путь ссылки на проект в файле csproj, например:

<ProjectReference Include="..\..\..\..\WrongFolder\OtherProject.csproj">
    <Project>{CD795AA6-9DC4-4451-A8BA-29BACF847AAC}</Project>
    <Name>OtherProject</Name>
</ProjectReference>

Visual Studio исправит это при открытии решения:

<ProjectReference Include="..\..\..\..\RightFolder\OtherProject.csproj">
    <Project>{CD795AA6-9DC4-4451-A8BA-29BACF847AAC}</Project>
    <Name>OtherProject</Name>
</ProjectReference>

Я полагаюиспользует GUID из элемента Project для уникальной идентификации проекта в решении, что позволяет ему исправить путь.

С другой стороны, MSBuild, похоже, не исправляет этот путь, и сборка решения не удалась.

Есть ли способ заставить MSBuild исправить путь или сделать это в качестве шага перед сборкой с помощью другого инструмента или команды для правильного построения решения?

Спасибо!

1 Ответ

1 голос
/ 11 января 2013

Это часть функциональности VisualStudio.Но вы можете вызвать инструмент для решения ссылок перед сборкой.Вот черновик кода, который вы можете разработать:

using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;

namespace FixProjectReferences
{

class Program
{

// License: This work is licensed under a Creative Commons
// Attribution-ShareAlike 3.0 Unported License.
// Author: Marlos Fabris
// Summary: Updates the project references in csproj.
// Param:
// args[0] = Main project (c:\mainProject.csproj)
// args[1] = Folder to scan other projects (c:\other)
static void Main(string[] args)
{
    string mainProject = args[0];
    string folder = args[1];
    FileInfo mainPrjInfo = new FileInfo(mainProject);
    string currentDir = Directory.GetCurrentDirectory();

    // Lists all project files in the directory specified
    // and scans the GUID's.
    DirectoryInfo info = new DirectoryInfo(folder);
    FileInfo[] projects = info.GetFiles("*.csproj",
        SearchOption.AllDirectories);

    Dictionary<Guid, string> prjGuids = new Dictionary<Guid, string>();

    foreach (var project in projects)
    {
        if (project.FullName == mainPrjInfo.FullName)
            continue;

        Regex regex = new Regex("<ProjectGuid>(\\{.*?\\})</ProjectGuid>");
        Match match = regex.Match(File.ReadAllText(project.FullName));
        string guid = match.Groups[1].Value;

        prjGuids.Add(new Guid(guid), project.FullName);
    }

    // Loads the main project and verifies if the references are valid.
    // If not, updates with the correct ones from the list
    // previously generated.
    XmlDocument doc = new XmlDocument();
    doc.Load(mainPrjInfo.FullName);
    XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
    ns.AddNamespace("ns",
        "http://schemas.microsoft.com/developer/msbuild/2003");
    var nodes = doc.SelectNodes("//ns:ProjectReference", ns);
    foreach (XmlNode node in nodes)
    {
        string referencePath = node.Attributes["Include"].Value;
        string path = Path.Combine(mainPrjInfo.Directory.FullName,
            referencePath);
        if (File.Exists(path))
            continue;

        string projectGuid = node.SelectSingleNode("./ns:Project",
            ns).InnerText;
        Guid tempGuid = new Guid(projectGuid);
        if (prjGuids.ContainsKey(tempGuid))
        {
            node.Attributes["Include"].Value = prjGuids[tempGuid];
        }
    }

    doc.Save(mainPrjInfo.FullName);
}

}

}
...