2009-05-27 61 views
4

爲了處理不同部署目標的設置,我將應用程序設置從app.config移到了它自己的文件中,並通過configSource將該文件包含在app.config中。我還創建用於每個target.Here一個設置文件是一個例證:多個.NET配置文件和安裝項目問題

Project A 
    app.config (references settings.config) 
    settings.config 
    settings.Release.config 
    settings.Debug.config 

在生成後,我複製適當的設置{配置}的.config到輸出目錄。目前爲止工作正常,我可以在項目輸出目錄中看到settings.config文件,其中包含當前版本配置的設置:發佈,調試等。

但是,我遇到了安裝項目的問題,有這個項目(項目A)。最初,它不包括settings.config文件。因此,我將settings.config文件的構建操作設置爲內容,並將項目A的內容文件添加到安裝項目中。這確保了setup.config文件包含在設置中。但是,由於安裝項目似乎是從項目目錄而不是輸出目錄中選取settings.config文件,因此設置中包含的settings.config文件不是它應該包含的內容。我希望輸出目錄中的那個包含在安裝程序中,因爲那一個對於當前的構建配置是正確的。我嘗試了以下方法:

  • 將settings.config添加爲安裝項目的文件。但是,似乎我只能指定絕對路徑。因此,當我從特定構建配置(..bin \ debug \ settings.config)的輸出目錄中添加它時,它在其他構建配置中不起作用,因爲(..bin \ debug \ settings.config)確實存在於指定的目錄。我研究了在安裝項目中使用相對路徑或動態路徑,其中構建配置可以被指定爲路徑的一部分,但我找不到任何東西。

我認爲使用預生成事件實際修改在項目目錄的settings.config文件,然後把它複製了輸出目錄通過其「複製到輸出目錄」設置爲始終複製或是否有更新的複製。這應該確保將相應的settings.config複製到輸出目錄,就像基於後構建的解決方案一樣,並且還應該確保settings.config文件的內容在安裝項目包含之前已更新。但是,我不喜歡這個解決方案,因爲我必須確保settings.config文件是可寫的,然後才能進行任何更改,因爲它是源代碼管理的。如果它是隻讀的,那麼我需要將其翻轉爲可寫,進行更改,然後將其設置爲只讀。這增加了額外的複雜性。

我想知道是否有人有一個更好的主意或知道一個安裝項目的技巧,允許我包括settings.config文件適合當前生成配置在安裝程序。

感謝

+0

我不知道這可能對你有多大幫助,但是你可以試試MSBuild腳本,在編譯projet之前實現你的配置文件「開關」。 2年前,我看到了類似這樣的東西,但是它嵌入了Pearl的幾條線中,以達到目前爲止我所見過的最複雜的構建腳本之一。但是你應該能夠爲你的項目做更簡單的事情。 – 2009-05-27 17:03:25

回答

1

如果我必須解決這個問題,我會通過問以下的問題開始:

爲什麼的settings.config必須要進行源代碼控制,如果settings.Debug.config或settings.Release.config提供相同的信息?

答案是,如果我正確地讀你的問題,是因爲你需要強制一個settings.config文件作爲生成輸出的一部分出現。我猜這是因爲你的設置項目正在使用內置的「主輸出」選項。

您可以改爲將該文件添加到安裝項目中作爲顯式文件引用。右鍵單擊安裝項目並選擇添加/文件,然後選擇要包含的文件。正如你會注意到的(除非它在VS2008中被修復,遺憾的是我還沒有被允許在工作中使用),對手動添加的文件存在一個非常惱人的限制 - 沒有辦法讓路徑構建配置知道。您可以通過將相應的settings.config文件複製到一個公共位置(例如bin/Configuration)並從中選擇它來解決此問題。這確實會限制您按順序構建Debug和Release版本,而不是並行執行,但對於許多人來說,這可能不是一個大問題。

如果你不使用VS安裝項目所需要的,我強烈建議你看看維克斯(Windows安裝XML - 見http://wix.sourceforge.net/獲取更多信息)。這很容易讓你完成必要的任務,但如果你不熟悉Microsoft Installer的內部工作,初始學習曲線可能會有點陡峭。 Microsoft使用WiX自己進行一些非常重要的設置任務(例如Office 2007,SQL Server等)。人們一直希望WiX能夠成爲Visual Studio的一部分(VS 2010),但遺憾的是不再是這種情況。

+0

感謝您的回答。 settings.config不需要在源代碼控制之下。我將它包含在內,以便它成爲輸出的一部分,並且可以作爲資源包含在安裝程序中。將它作爲文件引用從公共位置添加的問題是文件的路徑在安裝程序中是絕對路徑(C:\ MyWorkspace \ Solution \ ProjectA \ Config \ settings.config)。但是,開發人員擁有不同的工作空間,並且構建計算機(TeamBuild)具有自己的目錄結構。因此,除非親屬會這樣,否則這就是我遇到的問題。任何方式使它相對? – 2009-06-11 16:35:20

1

我決定以不同的方式實現相同的結果(能夠針對不同的目標環境進行不同的配置設置)。所以這裏是我如何實現它,它運作良好。我在SO上閱讀了一些關於從MSBuild Community Tasks開始的XmlMassUpdate任務的帖子,並決定使用它。下面是我做的:

1)對於需要根據各自的目標環境不同的設置每一個項目,我添加了一個XML文件名爲app.config.substitutions.xml或web.config.substitutions.xml到項目。因此,該項目看起來像

Project A 
app.config 
app.config.substitutions.xml 

app.config.substitutions.xml文件具有設置取代。XmlMassUpdate將處理和適用於App.config文件。下面是我用一個樣本替換文件:

<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate"> 
    <substitutions> 
    <Development> 
     <appSettings> 
     <add xmu:key="key" key="SomeSetting" value="DevValue" /> 
     </appSettings> 
    </Development> 
    <Test> 
     <appSettings> 
     <add xmu:key="key" key="SomeSetting" value="TestValue" /> 
     </appSettings> 
    </Test> 
    <Release> 
     <appSettings> 
     <add xmu:key="key" key="SomeSetting" value="ReleaseValue" /> 
     </appSettings> 
    </Release> 
    </substitutions> 
</configuration> 

有關如何指定換人,看看對XmlMassUpdate的文檔,或者只是做就可以了搜索的細節。

2)現在我需要運行XmlMassUpdate作爲構建自動化(TeamBuild/MSBuild)的一部分。因此,在BeforeCompile在TeamBuild構建定義文件(基本上是PROJ文件),我增加了以下內容上有一個相應的.substitution.xml文件

<PropertyGroup> 
    <SubstitutionFileExtension>.substitutions.xml</SubstitutionFileExtension> 
    <TargetEnvironment>Test</TargetEnvironment> 
    </PropertyGroup> 

    <Target Name="BeforeCompile" Condition="'$(IsDesktopBuild)'!='true'"> 
    <CreateItem Include="$(SolutionRoot)\**\app.config;$(SolutionRoot)\**\web.config"> 
     <Output ItemName="ConfigurationFiles" TaskParameter="Include"/> 
    </CreateItem> 
    <CreateItem Include="@(ConfigurationFiles)" Condition="Exists('%(FullPath)$(SubstitutionFileExtension)')"> 
     <Output ItemName="ConfigFilesWithSubstitutions" TaskParameter="Include"/> 
    </CreateItem> 
    <Message Text="Updating configuration files with deployment target specific settings..."/> 
    <XmlMassUpdate 
     ContentFile="%(ConfigFilesWithSubstitutions.FullPath)" 
     SubstitutionsFile="%(ConfigFilesWithSubstitutions.FullPath)$(SubstitutionFileExtension)" 
     ContentRoot="/configuration" 
     SubstitutionsRoot="/configuration/substitutions/$(TargetEnvironment)"/> 
    </Target> 

注意,配置文件是隻讀的,在配置文件運行XmlMassUpdate構建,我確保在運行此任務之前將它們設置爲可寫。我實際上有另一個自定義的MSBuild任務,它在XmlMassUpdate之前運行,可處理所有配置文件(如連接字符串)中的常見設置。該任務使配置文件可寫。我也不檢查修改的配置文件回到源代碼管理。它們是安裝程序中包含的(適用於部署目標的適當配置文件)。