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

发布于 2024-10-30 12:10:49 字数 2961 浏览 1 评论 0原文

来自我的 .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< /strong> (删除敏感数据)

<?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 文件夹中,并且在发布时不会被拾取。

From my .csproj file:

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

At the bottom of my .csproj file:

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

From log4net.config

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

From log4net.Live.config (removed sensitive data)

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

I checked msbuild output and I see that it transformed my web.config correctly, but I see no output for it transforming log4net. Also, when I check the log4net.config file after publish, it has the original connection string.

What am I doing wrong :)?

Thanks!

Update

I had some errors in the code that msbuild were outputting as warnings that I didn't see.
I fixed those and now I get some output from MSBuild:

AfterCompile: Transforming Source
File: log4net.config
Applying Transform File: log4net.Live.config
Output File: obj\Live\Common.UI.Web.dll.config
Transformation succeeded

This is still a problem, because the file should be named log4net.config, not Common.UI.Web.dll.config...

For whatever reason

$(TargetFileName)

is taking on the name of the .csproj file name. If I replace it with just log4net, then it outputs correctly

Update

File is stuck in obj folder and is not getting picked up when publishing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

病女 2024-11-06 12:10:49

更新:对于 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 转换完全相同。

UPDATED: For Visual Studio 2012 (these updates work in VS2010 also)

After attempting many different solutions I dug into how web.Config transformations happen... Here is what I find the most elegant solution.

First off exclude your log4net.config files from your project, unless you truly understand the project XML you might end up with a very confusing duplicate reference. Do NOT delete the files just exclude them (we will be including them through the project editor).

Now unload your project and then edit it... or however you choose to get to the proj xml. Ensure that you have a node importing Microsoft.WebApplication.targets. If you are in a web project it might have been added for you... search for this node

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

Once you have this node you only need to add an ItemGroup node...

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

I have included the dependent files with in the ItemGroup, although this is not necessary, but it keeps things together. Notice that you didn't create a new task or target, now the transformation is handled EXACTLY like the web.config transformations.

若言繁花未落 2024-11-06 12:10:49

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

A Microsoft employee on his free time has added the ability to do this for all files now, like you could with web.config, in an extension called SlowCheetah. Check out the review SlowCheetah Xml Transform and the vsi extension download.

[浮城] 2024-11-06 12:10:49

对我来说,这个解决方案效果最好(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)

For me this solution worked best (VS2013):

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

If you have other properties than $(Configuration) you are free to use what you need.
We use publishprofiles and use this msbuild command in our CI build

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

in this case just replace $(Configuration) with $(PublishProfile)

心头的小情儿 2024-11-06 12:10:49

最终使用 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> 

Ended up using http://mint.litemedia.se/2010/01/29/transforming-an-app-config-file/ for both the app config and the log4net config. Works very nicely.

For the log4net config, add this to the 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> 
梦一生花开无言 2024-11-06 12:10:49

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>

ms007's answer nearly got me there though I was getting an access denied issue on the file as the build server had set it to read only. Here is my solution.

  <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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文