【问题标题】:How to transform log4net config like web.config?如何像 web.config 一样转换 log4net 配置?
【发布时间】:2011-07-30 07:05:24
【问题描述】:

来自我的 .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...

不管什么原因

$(目标文件名)

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

更新

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

【问题讨论】:

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


    【解决方案1】:

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

    在尝试了许多不同的解决方案后,我深入研究了 web.Config 转换是如何发生的......这是我发现的最优雅的解决方案。

    首先从您的项目中排除您的 log4net.config 文件,除非您真正了解项目 XML,否则您最终可能会得到一个非常混乱的重复引用。不要删除文件,只是排除它们(我们将通过项目编辑器将它们包括在内)。

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

    <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 转换完全一样。

    【讨论】:

    • 当我尝试这个解决方案并在 VS 2012 中重建时,我得到:“exists”函数只接受一个标量值,但它的参数“$(PackageSourceManifest)”计算为“...\obj\ Debug\Package\AssetService.SourceManifest.xml;...\obj\Debug\Package\AssetService.SourceManifest.xml“这不是一个标量值。”(...是我的项目文件夹的完整路径)。似乎
    • 这是一个旧答案,但为了完整起见,我想补充一点,您需要在配置转换文件中声明“xdt”命名空间:schemas.microsoft.com/XML-Document-Transform">
    【解决方案2】:

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

    【讨论】:

    • 这不是微软添加的,是微软员工自己写的。微软根本不认可 SlowCheetah。仅供参考...
    • 这样更好吗@KevinDonde
    【解决方案3】:

    【讨论】:

    • 看起来非常接近我正在做的事情,除了它使用不同的目标名称和任务名称......我认为这两种方法都应该工作......
    • 我认为如果您使用博客文章进行轻微的混合和匹配,那么它会起作用 - 对我来说,博客文章在我的书签中,因为自从我第一次看到它以来它就非常有用
    • 我试过了,但结果一样。几乎就像代码永远不会被击中:/
    • 我想看看我能从你的脚本中得到什么
    • 谢谢。我更新了我的答案,现在这只是我认为的文件的命名问题。
    【解决方案4】:

    最终使用 http://mint.litemedia.se/2010/01/29/transforming-an-app-config-file/ 进行应用配置和 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> 
    

    【讨论】:

    • 请务必阅读 Steve re: SlowCheetah Xml Transform 的评论
    • 我是那篇博文的作者。它是在 XDT 转换存在之前完成的,我强烈建议您改用 SlowCheetah。
    【解决方案5】:

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

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

    如果您有 $(Configuration) 以外的其他属性,您可以随意使用您需要的属性。 我们使用 publishprofiles 并在我们的 CI 构建中使用这个 msbuild 命令

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

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

    【讨论】:

    • 但这会将 log4net.config 内容替换为转换后的内容。原来的 log4net.config 呢?它的内容在转换中丢失了。
    【解决方案6】:

    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>
    

    【讨论】:

      猜你喜欢
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多