關於VS2008和VS2010中.sln文件(解決方案文件)的介紹MSDN中只有英文版,現翻譯供讀者參考,希望對您有幫助。水平有限文中難免有錯誤,歡迎大家指正,拜謝~
解決方案就是Visual Studio中用來組織項目的結構。他的作用類似於VB6.0中的Windows程序組(.vbg)文件以及VC6.0中的項目工作區(.dsw)文件。解決方案將項目的狀態信息保存在.sln文件(該文件是基於文本,而且是可共享的)和.suo文件(該文件是二進制的,而且是解決方案中可選的)中。更多關於.suo的信息請查看解決方案中用戶可選.suo文件。
如果你的VSPackage由於在.sln文件中被引用而加載,那么編譯環境調用ReadSolutionProps讀取.sln文件。
.sln文件包含基於文本的信息,編譯環境通過這些信息找到並且加載他引用到的持久數據和VSPackages項目。當用戶打開解決方案的時候編譯環境通過包含在.sln文件中的preSolution,Project,postSolution信息加載解決方案,包含在解決方案中的項目以及任何和解決方案有聯系的持久信息。
每個項目的文件都包含額外的信息,編譯環境通過讀取這些信息把項目中所需的項目補充完整。數據持久層是受項目控制的;所以數據一般不包含在.sln文件中。盡管你可以有意的將項目信息寫入.sln文件中。更多的信息請參考Project Persistence和Opening 和Saving Project Items。
解決方案文件內容
.sln的文件都是由幾部分如圖所示的下列代碼構成的,他被保存在解決方案瀏覽器的底部。更多有關解決方案注釋章節的信息,參見Extending Solution Explorer。
1: Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Project1", "Project1.vbproj", "{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}"2: EndProject3: Global4: GlobalSection(SolutionNotes) = postSolution5: Name1 = Note26: Issue1 = N7: Text1 = This is a shared note.8: Name2 = Note39: Issue2 = N10: Text2 = This is also a shared note. The second of two shared notes.11: NumNotes = 212: EndGlobalSection13: GlobalSection(SolutionConfiguration) = preSolution14: ConfigName.0 = Debug15: ConfigName.1 = Release16: EndGlobalSection17: GlobalSection(ProjectDependencies) = postSolution18: EndGlobalSection19: GlobalSection(ProjectConfiguration) = postSolution20: {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.ActiveCfg = Debug|.NET21: {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.Build.0 = Debug|.NET22: {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.ActiveCfg = Release|.NET23: {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.Build.0 = Release|.NET24: EndGlobalSection25: GlobalSection(ExtensibilityGlobals) = postSolution26: EndGlobalSection27: GlobalSection(ExtensibilityAddIns) = postSolution28: EndGlobalSection29: EndGlobal
編譯環境執行如下順序的工作去加載解決方案
1. 編譯環境讀取.sln文件的全局語句並且處理所有的標記為preSolution的語句。在上文的例子中,有這樣的聲明:
1: GlobalSection(SolutionConfiguration) = preSolution2: ConfigName.0 = Debug3: ConfigName.1 = Release
當編譯環境讀取到GlobalSection(‘name’)標記的時候,他通過注冊表將名字映射到VSPackage中。關鍵字name應該在注冊表的[HKLM/<Application ID Registry Root>/SolutionPersistence]目錄下。關鍵字的默認值是寫入VSPackage目錄的Package GUID (REG_SZ)中的。
2. 環境加載VSPackage的時候,為IVsPersistSolutionProps接口調用VSpackage的QueryInterface,並且通過文件中的數據調用ReadSolutionProps方法,所以VSPackage能夠存儲數據。編譯環境對每個有preSolution的地方重復做上面那樣的操作。
3. 編譯環境循環遍歷項目的模塊。那好,這里有一個項目(讓我們來分析一下)
1: Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Project1",2: "Project1.vbproj", "{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}"3: EndProject
上面這段代碼中包含獨一無二的項目全局唯一標識符(GUID)以及項目類型的全局唯一標識符(GUID)。這些信息被編譯環境用來尋找項目文件愛你或者那些屬於解決方案的文件,還有那些任何項目需要的特定的VSPackage。項目的全局唯一標識符(GUID)被傳遞到IVsProjectFactory用來加載和項目有關的特殊的VSPackage,然后這個項目被載入。在上面的代碼中被載入的VSPackage是Visual Basic。
每個項目中都存在一個唯一的項目實例ID,只有這樣這個項目才能被其他解決方案中需要他的項目使用。理想狀態下,如果解決方案和項目在源代碼控制之下,項目的路徑應該和解決方案的路徑是相關的。當解決方案被第一次加載時,項目文件不能夠存在於用戶的電腦中。將項目文件存放在和解決方案文件相關的服務文件中,通過這個方法將相對簡單的找到項目文件或者將項目文件復制到用戶的電腦中。然后編譯環境復制並加載剩下的項目所需文件。
4. 根據項目的.sln文件中包含的信息編譯環境加載每一個項目文件。項目本身很好的填充項目的層次而且加載任何嵌入的項目。
5. 然后編譯環境執行被標記為postSolution的那些全局語句。下面就是上文代碼片段中的一個例子。
1: GlobalSection(SolutionNotes) = postSolution2: Name1 = Note23: Issue1 = N4: Text1 = This is a shared note.5: Name2 = Note36: Issue2 = N7: Text2 = This is also a shared note. The second of two shared notes.8: NumNotes = 29: EndGlobalSection
正如上面的這種情況,在.sln文件中有兩個共享的note.Note1沒有包含在文件中,因為他標記為不共享。他的內容放在.suo文件中。語句中的每個有名字值組成的條目和每個note是一一對應的。更多有關實現解決方案Note的內容請查看Extending Solution Explorer。
6. 最后.sln文件執行完畢,解決方案在解決方案瀏覽器中顯示出來,並等待用戶的操作。
如果有關項目的任何VSPackage加載失敗, OnProjectLoadFailure方法將被調用而且每個解決方案中的項目將嘗試取消在加載過程中的改變。如果解析發生錯誤,盡可能的收集有關解決方案文件的資料而且編譯環境顯示一個對話框警告這個解決方案已經被破壞了。
當解決方案被保存或者被關閉的時候QuerySaveSolutionProps方法將被調用並傳到層次結構檢查解決方案中是否存在那些需要保存到.sln文件中的改變。在VSQUERYSAVESLNPROPS中傳遞到QuerySaveSolutionProps的一個空值表明這個信息將被保存。如果值不為空表明保存的信息是特殊的項目,這取決於IVsHierarchy接口
如果有信息被保存IVsSolutionPersistence接口將被指向SaveSolutionProps的方法調用。然后 WriteSolutionProps方法將被編譯環境調用,這個方法用來檢驗與來自IPropertyBag的接口對應的名字值並且將相關信息寫入.sln文件中。
為了檢驗來自IPropertyBag接口的信息是否被保存SaveSolutionProps和WriteSolutionProps對象被編譯環境遞歸調用,直到所有的更改被寫進.sln文件。用這種方法可以確保解決方案的信息可以保存並且下次可以順利打開解決方案。
每個加載的VSPackage都被列舉用來查看是否有需要保存到.sln文件的東西。只有在加載的時候才需要注冊碼。編譯環境知道所有的加載的包,因為當解決方案保存的時候他們就被記錄下來了。
只有.sln包含preSolution和postSolution中的條目。在.suo文件中沒有相似的語句,因為解決方案需要正確的被加載。.suo文件包含用戶的可選項,比如個人的注釋,這些是不需要被共享或者被源碼控制的。
