在构建 csproj 文件之前自动修复 ProjectReference Include 路径

发布于 2024-12-08 01:58:47 字数 792 浏览 0 评论 0原文

我有一个 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>

我想它使用 Project 元素中的 GUID 来唯一标识解决方案中的项目,从而允许它修复路径。

另一方面,MSBuild 似乎没有修复这条路径,并且构建解决方案失败。

有没有办法让 MSBuild 修复路径或使用其他工具或命令将其作为预构建步骤,以便正确构建解决方案?

谢谢!

I have a VS 2010 solution with a number of projects in it.
Projects reference other projects within the solution.
I have noticed that when I have a wrong project reference path in a csproj file like this:

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

Visual studio would fix this on opening the solution:

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

I suppose it uses the GUID from the Project element to uniquely identify the project within the solution which allows it to fix the path.

MSBuild on the other hand doesn't seem to fix this path and building the solution fails.

Is there a way to make MSBuild fix the path or do it as a pre-build step with some other tool or command so that the solution builds correctly?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绾颜 2024-12-15 01:58:47

这是 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);
}

}

}

This is part of the VisualStudio functionality. But you can call a tool to solve the references before the build. Here is a draft code that you can elaborate:

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);
}

}

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文