簡體   English   中英

多個.NET配置文件和安裝項目問題

[英]Multiple .NET Configuration Files and Setup Project Problem

為了處理不同部署目標的設置,我將應用程序設置從app.config移到了自己的文件中,並通過configSource將該文件包含在app.config中。 我還為每個目標創建了一個設置文件。

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

在構建后的過程中,我將適當的settings。{configuration} .config復制到輸出目錄。 到目前為止,這一切正常,我可以在項目輸出目錄中看到settings.config文件,其中包含當前構建配置的設置:Release,Debug等。

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

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

我考慮過使用預構建事件來實際修改項目目錄中的settings.config文件,然后通過將其“復制到輸出目錄”設置為始終復制或復制(如果較新),將其復制到輸出目錄中。 這應該確保將適當的settings.config復制到輸出目錄,就像基於生成后的解決方案一樣,並且還應該確保setup.config文件的內容在安裝項目包括它之前被更新。 但是,我不喜歡這種解決方案,因為我必須確保settings.config文件是可寫的,然后才能進行任何更改,因為它是源代碼控制的。 如果它是只讀的,那么我需要將其翻轉為可寫,進行更改,然后再次將其設置為只讀。 這增加了額外的復雜性。

我想知道是否有人有一個更好的主意或知道一個安裝項目的技巧,該技巧使我可以在安裝程序中包含適合當前構建配置的settings.config文件。

謝謝

如果必須解決此問題,請先詢問以下問題:

如果settings.Debug.config或settings.Release.config提供相同的信息,為什么settings.config必須在源代碼控制之下?

如果我正確閱讀了您的問題,答案是因為您需要強制將settings.config文件顯示為生成輸出的一部分。 我猜這是因為您的安裝項目正在使用內置的“主要輸出”選擇。

您可以做的是將該文件作為顯式文件引用添加到安裝項目中。 右鍵單擊安裝項目,然后選擇添加/文件,然后選擇要包含的文件。 您會注意到(除非VS2008中已對其進行修復,但遺憾的是我不允許在工作中使用它),手動添加的文件存在一個非常煩人的限制-無法使路徑構建配置知道。 您可以通過將適當的settings.config文件復制到一個公共位置(例如bin / Configuration)並從此處拾取它來解決此問題。 這的確限制了您順序構建Debug和Release版本,而不是並行構建,但是對於許多人來說,這可能不是一個大問題。

如果不需要使用VS安裝程序項目,強烈建議您看一下WiX(Windows Installer XML-有關更多信息,請參見http://wix.sourceforge.net/ )。 盡管如果您不熟悉Microsoft Installer的內部工作原理,那么最初的學習曲線可能會有些陡峭,這將輕松使您完成必要的工作。 Microsoft自己使用WiX完成一些非常重要的設置任務(例如Office 2007,SQL Server等)。 曾經希望WiX能夠成為Visual Studio(對於VS 2010)的一部分,但令人遺憾的是,情況已不再如此。

我決定以不同的方式實現相同的結果(能夠針對不同的目標環境使用不同的配置設置)。 因此,這就是我的實現方式,並且效果很好。 我從MSBuild社區任務中閱讀了SO上有關XmlMassUpdate任務的一些帖子,並決定使用它。 這是我所做的:

1)對於每個需要根據目標環境進行不同設置的項目,我在項目中添加了一個名為app.config.substitutions.xml或web.config.substitutions.xml的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)的一部分。 因此,在TeamBuild構建定義文件(基本上是proj文件)中的BeforeCompile中,我添加了以下內容以在具有相應.substitution.xml文件的配置文件上運行XmlMassUpdate。

  <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>

請注意,配置文件在構建期間是只讀的,在運行此任務之前,請確保將其設置為可寫。 實際上,我還有另一個自定義MSBuild任務,該任務在XmlMassUpdate之前運行,該任務處理所有配置文件(如連接字符串)中的通用設置。 該任務使配置文件可寫。 我也不會將修改后的配置文件簽回到源代碼管理中。 它們是(安裝目標的適當配置文件)包含在安裝程序中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM