如何像web.config一样转换log4net配置?

时间:2011-04-05 20:10:00

标签: asp.net visual-studio-2010 configuration msbuild slowcheetah

来自我的.csproj文件:

<Content Include="log4net.config">
  <SubType>Designer</SubType>
</Content>
<Content Include="log4net.Release.config">
  <DependentUpon>log4net.config</DependentUpon>
</Content>
<Content Include="log4net.Debug.config">
  <DependentUpon>log4net.config</DependentUpon>
</Content>
<Content Include="log4net.Live.config">
  <DependentUpon>log4net.config</DependentUpon>   
</Content>
<Content Include="log4net.Demo.config">
  <DependentUpon>log4net.config</DependentUpon>   
</Content>  

在.csproj文件的底部:

  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    <Target Name="AfterCompile" Condition="exists('log4net.$(Configuration).config')">
      <TransformXml Source="log4net.config"
        Destination="$(IntermediateOutputPath)$(TargetFileName).config"
        Transform="log4net.$(Configuration).config" />
      <ItemGroup>
        <AppConfigWithTargetPath Remove="log4net.config"/>
        <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
          <TargetPath>$(TargetFileName).config</TargetPath>
        </AppConfigWithTargetPath>
      </ItemGroup>
    </Target>

来自log4net.config

<connectionString name="ConnName" 
value="Data Source=localhost\sqlexpress;Initial Catalog=localdb;Persist Security Info=True;Integrated Security=SSPI;" />

来自log4net.Live.config (删除敏感数据)

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionString name="ConnName" value="Data Source=127.0.0.1;Initial Catalog=DBName;Persist Security Info=True;User ID=userid;Password=pword"
        providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)" />
</configuration>

我检查了msbuild输出,我发现它正确地转换了我的web.config,但是我没有看到它改变了log4net的输出。此外,当我在发布后检查log4net.config文件时,它具有原始连接字符串。

我做错了什么:)?

谢谢!

更新

我在msbuild输出的代码中出现了一些错误,这些错误是我没有看到的警告。 我修复了这些,现在我从MSBuild获得了一些输出:

  

AfterCompile:转换源代码   文件:log4net.config       应用转换文件:log4net.Live.config       输出文件:obj \ Live \ Common.UI.Web.dll.config
  转型成功

这仍然是一个问题,因为该文件应该命名为log4net.config,而不是Common.UI.Web.dll.config ...

无论出于何种原因

  

$(TargetFileName)

正在使用.csproj文件名的名称。如果我用log4net替换它,那么它输出正确

更新

文件卡在obj文件夹中,并且在发布时没有被提取。

6 个答案:

答案 0 :(得分:15)

更新:对于Visual Studio 2012(这些更新也适用于VS2010)

在尝试了许多不同的解决方案后,我深入研究了web.Config转换的发生方式......以下是我找到的最优雅的解决方案。

首先从您的项目中排除您的log4net.config文件,除非您真正理解项目XML,否则您最终会得到一个非常令人困惑的重复引用。不要删除文件只是排除它们(我们将通过项目编辑器包含它们)。

现在卸载你的项目,然后编辑它......或者你选择进入proj xml。确保您有一个导入Microsoft.WebApplication.targets的节点。如果您在Web项目中,可能已经为您添加了...搜索此节点

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

拥有此节点后,您只需添加一个ItemGroup节点...

<ItemGroup>
  <WebConfigsToTransform Include="log4net.config">
    <DestinationRelativePath>log4net.config</DestinationRelativePath>
    <Exclude>False</Exclude>
    <TransformFileFolder>$(TransformWebConfigIntermediateLocation)\original</TransformFileFolder>
    <TransformFile>log4net.$(Configuration).config</TransformFile>
    <TransformOriginalFolder>$(TransformWebConfigIntermediateLocation)\original</TransformOriginalFolder>
    <TransformOriginalFile>$(TransformWebConfigIntermediateLocation)\original\%(DestinationRelativePath)</TransformOriginalFile>
    <TransformOutputFile>$(TransformWebConfigIntermediateLocation)\transformed\%(DestinationRelativePath)</TransformOutputFile>
    <TransformScope>$(_PackageTempDir)\%(DestinationRelativePath)</TransformScope>
    <SubType>Designer</SubType>
  </WebConfigsToTransform>
  <None Include="log4net.Debug.config">
    <DependentUpon>log4net.config</DependentUpon>
  </None>
  <None Include="log4net.Release.config">
    <DependentUpon>log4net.config</DependentUpon>
  </None>
</ItemGroup>

我已将依赖文件包含在ItemGroup中,虽然这不是必需的,但它将事物保持在一起。请注意,您没有创建新任务或目标,现在转换处理完全像web.config转换一样。

答案 1 :(得分:7)

Microsoft员工在空闲时间添加了为所有文件执行此操作的功能,就像使用web.config一样,在名为SlowCheetah的扩展中。查看评论SlowCheetah Xml Transformvsi extension download

答案 2 :(得分:2)

答案 3 :(得分:2)

使用http://mint.litemedia.se/2010/01/29/transforming-an-app-config-file/结束app app和log4net配置。工作得非常好。

对于log4net配置,将其添加到csproj:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Target Name="ApplyConfiguration" Condition="Exists('log4net.$(Configuration).config')">  
       <XslTransformation XmlInputPaths="log4net.config" XslInputPath="log4net.$(Configuration).config" OutputPaths="log4net.config_output" />  
       <Copy SourceFiles="log4net.config_output" DestinationFiles="log4net.config" />  
   </Target>  
   <Target Name="BeforeBuild">  
       <CallTarget Targets="ApplyConfiguration"/>  
   </Target> 

答案 4 :(得分:1)

对我来说,这个解决方案效果最好(VS2013):

  <Target Name="ApplyLoggingConfiguration" BeforeTargets="BeforeBuild" Condition="Exists('log4net.$(Configuration).config')">
    <TransformXml Source="log4net.config" Transform="log4net.$(Configuration).config" Destination="log4net.config" />
  </Target>

如果您拥有除$(配置)之外的其他属性,则可以自由使用所需内容。 我们使用publishprofiles并在我们的CI构建中使用此msbuild命令

msbuild ConfigTransform.sln /p:DeployOnBuild=true;PublishProfile=Test;Configuration=Release

在这种情况下,只需用$(PublishProfile)替换$(Configuration)

答案 5 :(得分:0)

ms007的回答几乎让我在那里虽然我在文件上遇到访问被拒绝的问题,因为构建服务器已将其设置为只读。这是我的解决方案。

  <Target Name="ApplyLoggingConfiguration" BeforeTargets="BeforeBuild" Condition="Exists('log4net.$(Configuration).config')">

    <TransformXml Source="log4net.config"
                  Transform="log4net.$(Configuration).config"
                  Destination="temp_log4net.config" />
    <Copy SourceFiles="temp_log4net.config"
          DestinationFiles="log4net.config"
          OverwriteReadOnlyFiles="True" />

    <Delete Files="temp_log4net.config" />
  </Target>