理解 Visual Studio 解决方案文件格式(.sln)

一般情况下我们并不需要关心 Visual Studio 解决方案文件格式(.sln),因为 Visual Studio 对解决方案文件的自动修复能力是非常强的。但是如果遇到自动解冲突错误或者编译不通过了,那么此文件还是需要手工修改的。

 

基本概念

Visual Studio的解决方案文件由这三个部分组成:

  • 版本信息
    • Microsoft Visual Studio Solution File, Format Version 12.00
    • # Visual Studio Version 16
    • VisualStudioVersion = 16.0.28606.126
    • MinimumVisualStudioVersion = 10.0.40219.1
  • 项目信息
    • Project
    • EndProject
  • 全局信息
    • Global
    • EndGlobal

 

虽然看起来是三个独立的部分,但其实除了版本号之外,项目信息和全局信息还是有挺多耦合部分的。

比如我们来看一个 sln 文件的例子,是一个最简单的只有一个项目的 sln 文件:

image

 

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo", "Walterlv.Demo\Walterlv.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {F2F1AD1B-207B-4731-ABEB-92882F89B155}
    EndGlobalSection
EndGlobal

下面我们来一一说明。

 

结构

版本信息

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1

记录文件的格式版本是 12.0。使用 Visual Studio 2019 编辑/创建。

 

这里有一个小技巧,这里的 VisualStudioVersion 版本号设置为 15.0 会使得打开 sln 文件的时候默认使用 Visual Studio 2017,而设置为 16.0 会使得打开 sln 文件的时候默认使用 Visual Studio 2019。

 

项目信息

Porject

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo", "Walterlv.Demo\Walterlv.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
EndProject

项目信息至少由两行组成,第一行标记项目信息开始,而最后一行表示信息结束。

其格式为:

Project("{项目类型}") = "项目名称", "项目路径", "项目 Id"
EndProject

 

项目类型详见:

https://www.yuque.com/docs/share/b8b2120d-b628-4ec1-b4fb-c1206fd54c9c?#

 

项目名称和项目路径不必多说,都知道。对于文件夹而言,项目名称就是文件夹的名称,而项目路径也是文件夹的名称。

 

项目 Id 是在解决方案创建项目的过程中生成的一个新的 GUID,每个项目都不一样。对于 SDK 风格的 C# 项目文件,csproj 中可以指定项目依赖,而如果没有直接的项目依赖,而只是解决方案编译级别的依赖,那么也可以靠 sln 文件中的项目 Id 来指定项目的依赖关系。另外,也通过项目 Id 来对项目做一些编译上的解决方案级别的配置。

 

PojectSection

Project和EndProject的内部还可以放ProjectSection。

 

比如对于解决方案文件夹,可以包含解决方案文件:

Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B002382D-4C9E-4F08-85E5-F12E2C061F5A}"
    ProjectSection(SolutionItems) = preProject
        .gitattributes = .gitattributes
        .gitignore = .gitignore
        README.md = README.md
        build\Version.props = build\Version.props
    EndProjectSection
EndProject

这个解决方案文件夹中包含了四个文件,其路径分别记录在了 ProjectSection 节点里面。

 

ProjectSection 还可以记录项目依赖关系(非项目之间的真实依赖,而是解决方案级别的编译依赖):

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo", "Walterlv.Demo\Walterlv.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
    ProjectSection(ProjectDependencies) = postProject
        {98FF9756-B95A-4FDB-9858-5106F486FBF3} = {98FF9756-B95A-4FDB-9858-5106F486FBF3}
    EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo2", "Walterlv.Demo2\Walterlv.Demo2.csproj", "{98FF9756-B95A-4FDB-9858-5106F486FBF3}"
EndProject

在这一段节点里面,我们的 Walterlv.Demo 项目依赖于另外一个 Walterlv.Demo2 项目。依赖是以 项目 Id = 项目 Id 的方式写出来的;如果有多个依赖,那么就写多行。不用吐槽为什么一样还要写两遍,因为这是一个固定的格式,后面我们会介绍一些全局配置里面会有两个不一样的。

 

关于设置项目依赖关系的方法,除了 sln 文件里面的设置之外,还有通过设置项目依赖属性的方式;

 

全局信息

一个全局信息的例子如下:

Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.Build.0 = Release|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {F2F1AD1B-207B-4731-ABEB-92882F89B155}
    EndGlobalSection
EndGlobal

在这个全局信息的例子中,为解决方案指定了两个配置(Configuration),Debug 和 Release,平台都是 Any CPU。同时也为每个项目指定了单独的配置种类,可供选择,每一行都是 项目的配置 = 解决方案的配置 表示此项目的此种配置在解决方案的某个全局配置之下。

 

如果我们将这两个项目放到文件夹中,那么我们可以额外看到一个新的全局配置 NestedProjects 字面意思是说 {DC0B1D44-5DF4-4590-BBFE-072183677A78} 和 {98FF9756-B95A-4FDB-9858-5106F486FBF3} 两个项目在 {20B61509-640C-492B-8B33-FB472CCF1391} 项目中嵌套,实际意义代表 Walterlv.Demo 和 Walterlv.Demo2 两个项目在 Folder 文件夹下。

GlobalSection(NestedProjects) = preSolution
    {DC0B1D44-5DF4-4590-BBFE-072183677A78} = {20B61509-640C-492B-8B33-FB472CCF1391}
    {98FF9756-B95A-4FDB-9858-5106F486FBF3} = {20B61509-640C-492B-8B33-FB472CCF1391}
EndGlobalSection

image

 

上图解决方案下的整个解决方案全部内容如下:

 

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo", "Walterlv.Demo\Walterlv.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
    ProjectSection(ProjectDependencies) = postProject
        {98FF9756-B95A-4FDB-9858-5106F486FBF3} = {98FF9756-B95A-4FDB-9858-5106F486FBF3}
    EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Walterlv.Demo2", "Walterlv.Demo2\Walterlv.Demo2.csproj", "{98FF9756-B95A-4FDB-9858-5106F486FBF3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Folder", "Folder", "{20B61509-640C-492B-8B33-FB472CCF1391}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {DC0B1D44-5DF4-4590-BBFE-072183677A78}.Release|Any CPU.Build.0 = Release|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {98FF9756-B95A-4FDB-9858-5106F486FBF3}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(NestedProjects) = preSolution
        {DC0B1D44-5DF4-4590-BBFE-072183677A78} = {20B61509-640C-492B-8B33-FB472CCF1391}
        {98FF9756-B95A-4FDB-9858-5106F486FBF3} = {20B61509-640C-492B-8B33-FB472CCF1391}
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {F2F1AD1B-207B-4731-ABEB-92882F89B155}
    EndGlobalSection
EndGlobal
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在将旧版本的解决方案(如.vs2010.sln)打开到 Visual Studio 2022 中时,可能会遇到一些常见的错误。以下是一些可能的错误和解决方法: 1. 兼容性问题:由于版本差异,某些项目或组件可能不再兼容 Visual Studio 2022。这可能导致编译错误或加载错误。解决方法是更新项目和组件以适应新版本的 Visual Studio,或者尝试使用旧版本的 Visual Studio 打开解决方案。 2. 缺少引用:在旧版本的解决方案中,可能使用了某些第三方库或组件。当打开解决方案时,Visual Studio 2022 可能无法找到这些引用导致编译错误。解决方法是检查并更新引用路径,确保它们指向正确的位置。 3. 插件不兼容:如果在旧版本的 Visual Studio 中安装了某些插件或扩展,这些插件可能不再与 Visual Studio 2022 兼容。在打开解决方案时,可能会出现加载插件失败或崩溃的问题。解决方法是禁用或卸载不兼容的插件,并尝试更新或找到替代的插件。 4. 平台工具集:在旧版本的解决方案中,可能使用了特定版本的平台工具集(Platform Toolset)。当打开解决方案时,Visual Studio 2022 可能无法找到该特定版本的工具集,导致编译错误。解决方法是更新项目设置,将平台工具集更改为适用于 Visual Studio 2022 的版本。 5. 编译选项:可能存在一些编译选项或配置在 Visual Studio 2022 中不再支持的情况。这可能导致编译错误或警告。解决方法是检查和更新项目的编译选项,确保它们与 Visual Studio 2022 兼容。 请注意,这只是一些常见问题的示例,实际情况可能因解决方案的复杂性而有所不同。对于特定的错误和问题,您可能需要根据具体情况进行进一步的研究和调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值