You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Roslyn获取解决方案中的.shproj Shared Project并修改?

解决Roslyn无法识别并修改.shproj共享项目的问题

Roslyn的MSBuildWorkspace默认仅加载与特定编程语言关联的项目(如.csproj、.vbproj),而.shproj(共享项目)本质是一个代码共享容器,本身不参与编译,也没有关联的语言服务,因此直接通过Roslyn加载会抛出“扩展名未关联语言”的错误。

解决方案:间接操作共享项目的代码

共享项目的代码最终会被引用它的“宿主项目”(如普通C#项目)包含编译,因此可以通过以下两种方式操作:

1. 直接解析并修改.shproj文件

利用MSBuild的API直接读取和编辑.shproj的项目内容,因为它本质是标准的MSBuild项目文件。

示例代码:

using Microsoft.Build.Evaluation;
using System.IO;
using System.Linq;

// 加载共享项目
string shprojPath = @"C:\Repo\Shared.shproj";
var projectCollection = new ProjectCollection();
var sharedProject = projectCollection.LoadProject(shprojPath);

// 添加新的类文件到共享项目
string newClassFileName = "NewSharedClass.cs";
sharedProject.AddItem("Compile", newClassFileName);

// 保存修改
sharedProject.Save();

// 写入新类的内容
string sharedProjectDir = Path.GetDirectoryName(shprojPath);
string newClassPath = Path.Combine(sharedProjectDir, newClassFileName);
string classContent = @"namespace ProjectX.Shared
{
    public class NewSharedClass
    {
        // 自定义内容
    }
}";
File.WriteAllText(newClassPath, classContent);

2. 通过引用共享项目的宿主项目间接操作

如果需要使用Roslyn的语法分析、重构等功能,可以打开引用该共享项目的宿主项目,通过宿主项目访问共享项目的代码文件,再进行修改。

示例代码:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.Build.Locator;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

// 初始化Roslyn
MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();

// 打开引用共享项目的宿主项目
string targetCsprojPath = @"C:\Repo\ProjectX.csproj";
var targetProject = await workspace.OpenProjectAsync(targetCsprojPath);

// 指定共享项目的目录
string sharedProjectDir = @"C:\Repo\Shared";

// 创建新的类文件
string newClassPath = Path.Combine(sharedProjectDir, "NewSharedClass.cs");
var newClassText = SourceText.From(@"namespace ProjectX.Shared
{
    public class NewSharedClass
    {
        // 类内容
    }
}");

// 将新文件添加到解决方案中,Roslyn会自动识别共享项目关联
var updatedSolution = targetProject.Solution.AddDocument(
    Path.GetFileName(newClassPath),
    newClassText,
    filePath: newClassPath
);

// 应用修改到Workspace
await workspace.TryApplyChanges(updatedSolution);

// 同步更新.shproj文件,确保共享项目能识别新文件
var projectCollection = new ProjectCollection();
var sharedProject = projectCollection.LoadProject(Path.Combine(sharedProjectDir, "Shared.shproj"));
sharedProject.AddItem("Compile", Path.GetFileName(newClassPath));
sharedProject.Save();

关键注意事项

  • .shproj本身不生成编译输出,所有代码的有效性依赖于引用它的宿主项目,修改后需确保宿主项目能正确编译。
  • 使用Roslyn操作时,共享项目的文件会作为宿主项目的一部分被加载,因此可以直接通过宿主项目的Documents集合访问共享代码的语法树。
  • 修改.shproj后,建议刷新宿主项目的Workspace,确保Roslyn能及时识别新添加的文件。

内容的提问来源于stack exchange,提问作者ndrespulido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:20:20