Solution (.Sln) File

A solution is a structure for organizing projects in Visual Studio. It performs a function similar to Windows Program Group (.vbg) files in Visual Basic 6.0 and project workspace (.dsw) files in Visual C++ 6.0. The solution maintains the state information for projects in .sln (text-based, shared) and .suo (binary, user-specific solution options) files. For further information on .suo files, see Solution User Options (.Suo) File.

If your VSPackage is loaded as a result of being referenced in the .sln file, the environment calls ReadSolutionProps to read in the .sln file.

The .sln file contains text-based information the environment uses to find and load the name-value parameters for the persisted data and the project VSPackages it references. When a user opens a solution, the environment cycles through the preSolution, Project, and postSolution information in the .sln file to load the solution, projects within the solution, and any persisted information attached to the solution.

Each project's file contains additional information read by the environment to populate the hierarchy with that project's items. The hierarchy data persistence is controlled by the project; the data is not normally stored in the .sln file, although you can intentionally write project information to the .sln file if you choose to do so. For more information relating to persistence, see Project Persistence and Opening and Saving Project Items.

Solution File Contents

The .sln file consists of several sections as illustrated in the following code taken from an .sln file written for a solution saved under the Solution Extender sample. For more information related to the population of the Solution Notes section in this code, see Extending Solution Explorer.

Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Project1", "Project1.vbproj", "{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}"
EndProject
Global
  GlobalSection(SolutionNotes) = postSolution
       Name1 = Note2
       Issue1 = N
       Text1 = This is a shared note.
       Name2 = Note3
       Issue2 = N
       Text2 = This is also a shared note. The second of two shared notes.
       NumNotes = 2
  EndGlobalSection
  GlobalSection(SolutionConfiguration) = preSolution
       ConfigName.0 = Debug
       ConfigName.1 = Release
  EndGlobalSection
  GlobalSection(ProjectDependencies) = postSolution
  EndGlobalSection
  GlobalSection(ProjectConfiguration) = postSolution
   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.ActiveCfg = Debug|.NET
   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.Build.0 = Debug|.NET
   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.ActiveCfg = Release|.NET
   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.Build.0 = Release|.NET
  EndGlobalSection
  GlobalSection(ExtensibilityGlobals) = postSolution
  EndGlobalSection
  GlobalSection(ExtensibilityAddIns) = postSolution
  EndGlobalSection
EndGlobal

To load a solution, the environment performs the following sequence of tasks.

  1. The environment reads the Global section of the .sln file and processes all sections marked preSolution. In this case, there is one such statement:

      GlobalSection(SolutionConfiguration) = preSolution
           ConfigName.0 = Debug
           ConfigName.1 = Release
    

    When the environment reads the GlobalSection('name') tag, it maps the name to a VSPackage using the registry. The key name should exist in the registry under [HKLM\<Application ID Registry Root>\SolutionPersistence]. The keys' default value is the Package GUID (REG_SZ) of the VSPackage that wrote the entries.

  2. The environment loads the VSPackage, calls QueryInterface on the VSPackage for the IVsPersistSolutionProps interface, and calls the ReadSolutionProps method with the data in the section so the VSPackage can store the data. The environment repeats this process for each preSolution section.

  3. The environment iterates through the project persistence blocks. In this case, there is one project.

    Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Project1",
    "Project1.vbproj", "{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}"
    EndProject
    

    This statement contains the unique project GUID and the project type GUID. This information is used by the environment to find the project file or files belonging to the solution, and the VSPackage required for each project. The project GUID is passed to IVsProjectFactory to load the specific VSPackage related to the project, then the project is loaded by the VSPackage. In this case, the VSPackage that is loaded for this project is Visual Basic.

    Each project can persist a unique project instance ID so that it can be accessed as needed by other projects in the solution. Ideally, if the solution and projects are under source code control, the path to the project should be relative to the path to the solution. When the solution is first loaded, the project files cannot be on the user's machine. By having the project file stored on the server relative to the solution file, it is relatively simple for the project file to be found and copied to the user's machine. It then copies and loads the rest of the files needed for the project.

  4. Based on the information contained in the project section of the .sln file, the environment loads each project file. The project itself is then responsible for populating the project hierarchy and loading any nested projects.

  5. The environment then processes the global sections marked postSolution. One example from the code is the section for the SolutionNotes.

      GlobalSection(SolutionNotes) = postSolution
           Name1 = Note2
           Issue1 = N
           Text1 = This is a shared note.
           Name2 = Note3
           Issue2 = N
           Text2 = This is also a shared note. The second of two shared
                   notes.
           NumNotes = 2
      EndGlobalSection
    

    In this case, there are two shared notes contained in the .sln file. Note 1 is not contained in the file because it was marked as unshared. Its contents are placed in the .suo file. Each entry in the section consists of a name-value pair corresponding to the fields for each note. For more information on the implementation of Solution Notes, see Extending Solution Explorer.

  6. After all sections of the .sln file are processed, the solution is displayed in Solution Explorer and is ready for modification by the user.

If any VSPackage that implements a project in the solution fails to load, the OnProjectLoadFailure method is called and every other project in the solution is given a chance to ignore changes it might have made during loading. If parsing errors occur, as much information as possible is preserved with the solution files and the environment displays a dialog box warning the user that the solution is corrupted.

When the solution is saved or closed, the QuerySaveSolutionProps method is called and passed to the hierarchy to see if changes have been made to the solution that need to be entered into the .sln file. A null value, passed in to QuerySaveSolutionProps in VSQUERYSAVESLNPROPS, indicates that information is being persisted for the solution. If the value is not null, the persisted information is for a specific project, determined by the pointer to the IVsHierarchy interface.

If there is information to be saved, the IVsSolutionPersistence interface is called with a pointer to the SaveSolutionProps method. The WriteSolutionProps method is then called by the environment to retrieve the name-value pairs from IPropertyBag interface and write the information to the .sln file.

SaveSolutionProps and WriteSolutionProps objects are called recursively by the environment to retrieve information to be saved from the IPropertyBag interface until all changes have been entered into the .sln file. In this way, you can insure that the information will be persisted with the solution and available next time the solution is opened.

Every loaded VSPackage is enumerated to see if it has anything to save to .sln file. It is only at load time that the registry keys are queried. The environment knows about all of the loaded packages because they are in memory at the time the solution is saved.

Only the .sln file contains entries in the preSolution and postSolution sections. There are no similar sections in the .suo file since the solution needs this information to load properly. The .suo file contains user-specific options, such as private notes, that are not intended to be shared or placed under source code control.

See Also

Concepts

Solution User Options (.Suo) File

Reference

IVsPersistSolutionProps

Other Resources

Extending Solution Explorer

Solution Extender

Solutions