原文:.NET 将 .config 文件嵌入到程序集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Iron_Ye/article/details/83979628

.NET 将 .config 文件嵌入到程序集

最近,团队中的一位同事实现了一个小程序,供主程序调用。为了小程序分发的方便性,使用了 Costura.Fody 将其依赖的 dll 都嵌入到了 exe 中。但是,其中的 log4net.dll 又需要一个 *.config 文件才能正常工作,而 Costura.Fody 又不支持此类文件的嵌入。

我们先来复现一下问题场景,关于 Costura.Fodylog4net 的使用可以参考:

首先,在一个 C# 控制台程序中通过 NuGet 引用 log4netCostura.Fody 两个组件,然后在程序的 App.config 文件中添加如下配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<root>
<level value="WARN" />
<appender-ref ref="LogFileAppender" />
</root>
<logger name="mylogger">
<level value="ALL"/>
</logger>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
<param name="File" value="log-file.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout"/>
</appender>
</log4net>
</configuration>

这些配置用于指定 log4net 如何工作,需要在程序的入口处加载这些配置信息:

static void Main(string[] args)
{
// 从默认的配置文件(App.config)中读取配置信息
log4net.Config.XmlConfigurator.Configure(); var logger = LogManager.GetLogger("mylogger");
logger.Info("Starting..."); Console.ReadLine();
}

然后,为 Costura.Fody 添加一个 FodyWeavers.xml 文件,文件内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<Costura/>
</Weavers>

最后,编译此项目。你会发现 log4net.dll 并未出现在生成目录中,而是被合并到了 MyConsoleApp.exe 中。同时,生成目录中还有一个 MyConsoleApp.exe.config 文件(App.config)生成的。如果删除该文件,MyConsoleApp.exe 中的 log4net 不能正常工作。

因此,如果要实现 MyConsoleApp.exe 单文件分发,就要将 App.config 嵌入到该 exe 中,并且 log4net 要能识别嵌入的文件。

Embedded Resource

好在 Visual Studio 支持将项目中的某个文件的 Build Action 设置为 Embedded Resource(嵌入资源),这样一来,文件将作为资源被嵌入到程序集中。

并且,可以在运行时通过 Assembly.GetManifestResourceStream() 方法取文件内容:

var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyCompany.MyProduct.MyFile.txt"; using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}

这只是其中一种将文件作为资源嵌入到程序集的方法,欲了解更多方法,可参考 Various Build Actions in Visual Studio

Configure(Stream configStream)

查资料发现,log4net 支持从 Stream 中加载配置文件:

log4net.Config.XmlConfigurator.Configure(Stream configStream);

那么,结合 Embedded Resource,问题就非常简单了:

static void Main(string[] args)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyConsoleApp.App.config"; using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
// 从 Stream 中读取 log4net 的配置信息
log4net.Config.XmlConfigurator.Configure(stream);
} var logger = LogManager.GetLogger("mylogger");
logger.Info("Starting..."); Console.ReadLine();
}

再次编译项目,MyConsoleApp.exe.config 也从生成目录中消失了,单独的一个 MyConsoleApp.exe 也能正常运行了。

总结

本文只是以 *.config 文件为例来说明如何将文件作为资源嵌入到程序集中,其它格式的文件也是支持的,并且还有其它的嵌入方式,感兴趣的可以通过 Build Action 去探索更多的方法。

参考资料

.NET 将 .config 文件嵌入到程序集的更多相关文章

  1. C#项目中关于多个程序集下App.config文件的问题

    在项目中我们会经常用到App.config文件,有的是自动生成的,比如引用webservice.wcf服务时生成:也有手动建立的配置文件直接默认名就为app.config.这些配置有的保存当前程序集用 ...

  2. Debug目录、Release目录,bin目录、obj目录,vshost.exe.config文件、.exe.config文件分析【C#】

    原文地址:http://blog.csdn.net/itwit/article/details/6803338 今天写程序的时候,需要更改.exe.config文件中的引用的webservice地址, ...

  3. 如何更改c#项目的App.config文件

    动态修改App.Config 和web.Config 首先假设你的应用程序配置文件如下: <?xml version="1.0" encoding="utf-8&q ...

  4. IOC注入框架——Unity中Web.Config文件的配置与调用

    Unity 应用程序块可以从 XML 配置文件中读取配置信息.配置文件可以是 Windows Forms 应用程序的 App.config 或者 ASP.NET 应用程序的 Web.config.当然 ...

  5. WPF程序中App.Config文件的读与写

    WPF程序中的App.Config文件是我们应用程序中经常使用的一种配置文件,System.Configuration.dll文件中提供了大量的读写的配置,所以它是一种高效的程序配置方式,那么今天我就 ...

  6. Unity中Web.Config文件的配置与调用

    在上一篇文章“Unit简单依赖注入”我们可以实现构造对象和被依赖对象之间的 松耦合,使我们的抽象层(Player)能够保持稳定,但是在并没有把客户类和Player类之间彻底解耦,即当我们不想使用MP3 ...

  7. Rabbit MQ config文件解析

    Rabbit MQ config文件解析 tcp_listeners:用于监听AMQP连接的端口或主机名/对(不带TLS),默认端口:5672 2.numtcpacceptors :将接受TCP侦听器 ...

  8. 一步步开发自己的博客 .NET版(11、Web.config文件的读取和修改)

    Web.config的读取 对于Web.config的读取大家都很属性了.平时我们用得比较多的就是appSettings节点下配置.如: 我们对应的代码是: = ConfigurationManage ...

  9. 【Win 10应用开发】把文件嵌入到XML文档

    把文件内容嵌入(或存入)到XML文档中,相信很多朋友会想到把字节数组转化为Base64字符串,再作为XML文档的节点.不过,有人会说了,转化后的base64字符串中含有像“+”这样的符号,写入到XML ...

随机推荐

  1. Django(part3)

    URLConf:负责url到view的map,就是一个urls.py module,通常在project和app级别都要定义, #mysite/urls.py from django.conf.url ...

  2. 编程语言与Python学习(一)

    1.1 编程与编程语言 1.1.1 编程语言 计算机的发明,是为了用机器解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而达到让计算机能够像人脑一样自动执行 ...

  3. hiho 1590 - 紧张的会议室。区间问题

    题目链接 小Hi的公司最近员工增长迅速,同时大大小小的会议也越来越多:导致公司内的M间会议室非常紧张. 现在小Hi知道公司目前有N个会议,其中第i个会议的时间区间是(Si, Ei). 注意这里时间区间 ...

  4. 3ds Max灯光教程之卧室灯光布局实例

    对于设计师来说要做好一张好的作品效果图包括很多比如:“造型.色彩搭配.灯光气氛.构图角度等等,上次给大家详细的分析了下产品渲染中摄像机的构图及原理.本期教程来跟大家讨论一下max场景灯光布局问题.以卧 ...

  5. apicloud 上传/更新App版本到 ios store 流程步骤

    app更新 上传APP的地址: https://itunesconnect.apple.com/login 苹果开发者中心: https://developer.apple.com/ app正式包更新 ...

  6. CF1015F Bracket Substring (KMP+DP)

    题目大意:给你一个长度为$n$的括号序列$T$,要求你构造一个长度为$2n$的括号序列$S$,保证这个括号序列在插入数字后一定是正确的,并且$T$是$S$的一个子串 还以为是什么纯粹的数学构造题,一通 ...

  7. JAVA 程序生成jar包运行报错 Exception in thread "Thread-1" java.lang.NoClassDefFoundError: javax/xml/rpc 的解决方法

    最近开发支付宝生活缴费的项目,java程序要使用.NET 的WebService服务,后来正式部署出现这错误,网上查资料是少了一个“jaxrpc.jar”文件,但是我本地调试正常,最后是删除我目前导出 ...

  8. 05004_Linux的其他命令和权限命令

    1.其他命令 (1)显示当前所在位置 命令:pwd (2)搜索命令 a.命令:grep 要搜索的字符串 要搜索的文件 示例:搜索/etc/sudu.conf文件中包含字符串to的行 b.搜索/etc/ ...

  9. 如何用一次性密码通过 SSH 安全登录 Linux

    有人说,安全不是一个产品,而是一个过程.虽然 SSH 协议被设计成使用加密技术来确保安全,但如果使用不当,别人还是能够破坏你的系统:比如弱密码.密钥泄露.使用过时的 SSH 客户端等,都能引发安全问题 ...

  10. HDOJ 4975 A simple Gaussian elimination problem.

    和HDOJ4888是一样的问题,最大流推断多解 1.把ISAP卡的根本出不来结果,仅仅能把全为0或者全为满流的给特判掉...... 2.在残量网络中找大于2的圈要用一种类似tarjian的方法从汇点開 ...