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

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

一、前言 Foreword

在微软的工作过程中,免不了要跟Visual Studio打交道,就做了些学习记录。

其实在大部分时候,并不需要对Visual Studio解决方案文件(*.sln*)要求足够的理解,因为宇宙最强IDE已经对该文件的自我修复能力已经拉满了。

出于了解,介绍下该文件的格式内容。可以参考官方文档

二、 概述 Overview

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

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

除了版本号之外,项目信息和全局信息有较多内容是关联的。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30111.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Solution.Demo", "Solution.Demo\Solution.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 = {F05207D3-0956-46BE-AEEA-51B9F2531A53}
EndGlobalSection
EndGlobal

下面我们来一一说明。

三、各部分详讲

3.1 版本信息

1
2
3
4
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30111.22
MinimumVisualStudioVersion = 10.0.40219.1

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

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

3.1 项目信息

Project

Project是一个项目的开始和结束位置的关键字,是配对出现的。

1
2
3
Project
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Solution.Demo", "Solution.Demo\Solution.Demo.csproj", "{DC0B1D44-5DF4-4590-BBFE-072183677A78}"
EndProject

其格式为:

1
2
Project("{项目类型}") = "项目名称", "项目路径", "项目 Id"
EndProject
  • 项目类型ID:
    .Net/C#项目类型分为SDK风格, 传统风格传统解决方案等等。更多类型可以参考visual-studio-project-type-guids StackOverflow
  • 项目名称&项目路径:
    项目名称,也就是文件夹名字。项目路径就是csproj的路径。
  • 项目ID:
    在解决方案创建项目的过程中生成的一个新的GUID,每个项目都不一样。对于 SDK 风格的 C# 项目文件,csproj 中可以指定项目依赖,而如果没有直接的项目依赖,而只是解决方案编译级别的依赖,那么也可以靠 sln 文件中的项目 Id 来指定项目的依赖关系。另外,也通过项目 Id 来对项目做一些编译上的解决方案级别的配置。
ProjectSection

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

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

1
2
3
4
5
6
7
8
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 还可以记录项目依赖关系(非项目之间的真实依赖,而是解决方案级别的编译依赖):

1
2
3
4
5
6
7
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Solution.Demo", "Solution.Demo\Solution.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}") = "Solution.Demo2", "Solution.Demo2\Solution.Demo2.csproj", "{98FF9756-B95A-4FDB-9858-5106F486FBF3}"
EndProject

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

关于设置项目依赖关系的方法,除了 sln 文件里面的设置之外,还有通过设置项目依赖属性的方式,这里不增加描述。

3.3 全局信息

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9A19103F-16F7-4668-BE54-9A1E7A4F7556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A19103F-16F7-4668-BE54-9A1E7A4F7556}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A19103F-16F7-4668-BE54-9A1E7A4F7556}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A19103F-16F7-4668-BE54-9A1E7A4F7556}.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),DebugRelease,平台都是 Any CPU。同时也为每个项目指定了单独的配置种类,可供选择,每一行都是 项目的配置 = 解决方案的配置 表示此项目的此种配置在解决方案的某个全局配置之下。

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

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

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

https://minram.github.io/visual-studio/visualstudio-solutionfile-sln/

作者

MinRam

发布于

2022-06-27

更新于

2022-07-17

Licensed under

评论