.Net的WinForm程序有的时候让人很烦的是,在执行目录下总是一大堆的DLL,配置文件,最少则是个以下,多的时候怕有四五十个吧……,自己程序中的类库,第三方的类库……加载一起让人感觉乱糟糟的,非常不爽。在下虽然在个人卫生上没有什么洁癖,可是对于应用程序的这个样子确实没有一点容忍力的,是可忍孰不可忍啊!

处理这些DLL还是比较简单的,Configuration文件里就可以配置了。先将DLL分门别类,Core, Module, Misc等等,然后将这几个目录名称加入App.config中。如:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Castle;Core;Module;UI;Misc;"/>
</assemblyBinding>
</runtime>

嗯,现在看上去就舒服多了,各就各位的,清爽!慢……在主目录下,出了我们的应用程序Exe可执行文件外,还有一个例外,app.config…… 多少还是有点儿不爽,怎么办呢?我们建个Data目录,将config文件移动进去吧~!说做就做,我们就把app.config移动到下级目录了,开心啊,看看程序能运行不? 杯具发生了,程序运行毫无反应…… 用VS调试之,发现是找不到其他类库中的类型导致的。也是,我们刚刚在config文件中加了privatePath,现在有把这个文件移动了,怎么能加载到其他目录下的DLL呢?

知道原因了,当然就好解决。据说configuration文件的位置是可以指定的。AppDomainSetup.ConfiguraitonFile属性就是指的这个。让我们来试试……

分析一下:

要改config的路径,当然是要在使用config之前咯,而且越早越好…… 哪里比较早呢?嗯,Main函数,程序的入口是个不错的选择……

static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile = "Data\MyApp.Config"; Application.Run(new MyAppForm());
}
}

好,编译,信心满满的再次运行程序,可是杯具再一次啊发生了,依然没有反应……

……在此调试,惊奇的发现这个属性设置居然完全没有效果,语句执行完后,该属性值依然是默认值。于是查文档啊,百度啊,谷歌啊~ 最后终于知道设置config的正确方法。

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);

嗯,这个这个……不是微软在害人吗…… 好了,停下抱怨继续工作先…… 嗯,看到了,config文件的位置生效了,指向了我们预定的位置,可是………… 杯具毫无意外的再次发生……DLL依然不能加载!

虽然我已经在AppDomainSetup里看到了PrivateBinPath属性,可是我却一点兴奋感觉都没有,应该跟前面的结果类似把!

想想程序运行的过程,PrivateBinPath是AppDomain.Current.SetupInformation里的属性,而这个属性只有在AppDomain.Create的时候才会生效,在AppDomain已经建立后更改config的路径再去设置这个值,应该是不行的。看来只好代码里来设置了。可是如何下手呢?

关门, 放Reflector!呵呵,让我们看看AppDomain内部的情况。果其不然啊!SetupInforamtion只是其内部配置的一个Copy,这也就解释了为什么更改属性却没有生效的原因!

public AppDomainSetup SetupInformation
{
get
{
return new AppDomainSetup(this.FusionStore, true);
}
}

看起来不动用终极手段是不行的了!反射!更改内部字段来达到我们的目的!仔细检查了以下代码,发现AppDomain内部的Setup信息是保存在一个FunsionStore的Internal属性里的。好,我们就从这里动手把!

AppDomain.CurrentDomain.SetData("PRIVATE_BINPATH", "Castle;Core;Module;UI;Misc;");
AppDomain.CurrentDomain.SetData("BINPATH_PROBE_ONLY", "Castle;Core;Module;UI;Misc;");

这段代码确实就更改了AppDomain.CurrentDomain.SetupInformation.PrivateBinPath的值了,可是运行发现类型还是不能加载!可能内部还有个什么RefrefshConfiguraiton或UpdateCache之类的方法来刷新!继续找啊找的~ 终于发现了。是一个static extern的方法。呵呵……这下简单了,看代码!

在调试过程中,我们还发现Main方法不是最好的地方,所以我们将代码放在了Program的静态构造方法中,这里是除了静态字段外的最早的起始地了。

static Program()
{
AppDomain.CurrentDomain.SetData("PRIVATE_BINPATH", "Castle;Core;Module;UI;Misc;");
AppDomain.CurrentDomain.SetData("BINPATH_PROBE_ONLY", "Castle;Core;Module;UI;Misc;");
var m = typeof(AppDomainSetup).GetMethod("UpdateContextProperty", BindingFlags.NonPublic | BindingFlags.Static);
var funsion = typeof(AppDomain).GetMethod("GetFusionContext", BindingFlags.NonPublic | BindingFlags.Instance);
m.Invoke(null, new object[] { funsion.Invoke(AppDomain.CurrentDomain, null), "PRIVATE_BINPATH", "Castle;Core;Module;UI;Misc;" });
}

嗯,迫不及待的编译,运行!哇!毫不意外的,程序正常了,再看看应用程序目录,只有一个干干净净的exe文件的存在,真是爽到极点~

告诉你,exe文件就一个,我可以!哈哈!

最后提醒,如果Program里有静态字段,不要定义为用其他类库的类型,因为这个时候我们上述的方法还没有执行到,会因为找不到类型而出错的哦~

.Net代码控制PrivateBinPath和ConfigurationFile的位置的更多相关文章

  1. 代码控制PrivateBinPath和ConfigurationFile的位置

    原文:代码控制PrivateBinPath和ConfigurationFile的位置 .Net的WinForm程序有的时候让人很烦的是,在执行目录下总是一大堆的DLL,配置文件,最少则是个以下,多的时 ...

  2. 【iOS 开发】iOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)

    一. iOS 项目简介 1. iOS 文件简介 创建一个 HelloWorld 项目, 在这个 IOS 项目中有四个目录 : 如下图; -- HelloWorldTests 目录 : 单元测试相关的类 ...

  3. 控制input输入框光标的位置

    一:理解input, textarea元素在标准浏览器下两个属性selectionStart, selectionEnd. selectionStart: 该属性的含义是 选区开始的位置: selec ...

  4. C#中用鼠标移动页面功能的实现(代码控制滚动条)

    项目中需要实现以下功能: 打印预览控件中,可以用鼠标拖动页面,以查看超出显示范围之外的部分内容. 该功能本来可以通过拉动水平和垂直滚动条来实现,但实际使用中,用户更趋向于直接用鼠标拖动页面来实现,很多 ...

  5. iOS如何用代码控制以不同屏幕方向打开新页面?

    转载:http://blogread.cn/it/article/7765?f=wb#original 代码示例:https://github.com/johnlui/Swift-On-iOS/tre ...

  6. 使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面,然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller,是模型(model)-视图(view)-控制 ...

  7. 【转】代码控制UI,View

    [转]Android 步步为营 第5营 代码控制UI,View   http://www.cnblogs.com/vivid-stanley/archive/2012/08/22/2651399.ht ...

  8. 游戏开发之在UE4中编写C++代码控制角色

    当你运行我们上次做完的项目,你可能会意识到我们移动的摄像机还是默认的那个摄像机,这个默认的摄像机可以自由飞翔.这一节,我们要使得开始的角色是我们的一个Avatar类的实例对象,并且使用键盘控制我们的角 ...

  9. 关于Unity中Mecanim动画的动画状态代码控制与代码生成动画控制器

    对于多量的.复杂的.有规律的控制器使用代码生成 动画状态代码控制 1:每个动画状态,比如进入状态,离开状态, 等都有可能需要代码来参与和处理,比如,进入这个动画单元后做哪些事情,来开这个动画单元后做哪 ...

随机推荐

  1. Python解释器的安装

    Python解释器的安装 作者:Eric 微信:loveoracle11g 下载Python Python-3.7.0(64-bit)下载链接地址: https://www.python.org/ft ...

  2. Halcon 17与 c# 混合编程

    这篇主要是C#和Halcon的混合编程,在此基础上对按键不同功能的划分,以及图片适应窗口和从本地打开图片. halcon源程序:   dev_open_window(0, 0, 512, 512, ' ...

  3. 一台机器部署多个tomcat服务 nginx反向代理多个服务 笔记

    安装tomcat步骤           1. 下载apache-tomcat-8.0.30 ,下载下来的文件为apache-tomcat-8.0.30-windows-x64.zip         ...

  4. JAVA 8 函数式接口--Consumer

    从JDK8开始java支持函数式编程,JDK也提供了几个常用的函数式接口,这篇主要介绍Consumer接口.文本介绍的顺序依次为: 源码介绍 使用实例 jdk内对Consumer的典型使用 扩展类介绍 ...

  5. 学习excel的使用技巧统计文本出现的次数

    其实是使用一个函数来完成的 =ifcount(C1:C214,''test123") 统计c1到c214中出现的test123的次数

  6. py库:threading

    https://www.youtube.com/watch?v=DnTn3Yx-Nvg  join功能: import threading import time def thread_job2(): ...

  7. PHP批量保存图片

    关于这个问题网上也有回答,我只是把我在工作中用到的代码分解出来,供需要的朋友使用.以下代码都已经经过测试,所以没有任何问题.有问题请加QQ:1127173874 第一部分 数据库表结构 create ...

  8. undefined symbol: PyFPE_jbuf

    参考: https://blog.csdn.net/ture_dream/article/details/52733326 报错确实是Python的版本不一致. 但是我又不想删除anaconda. 怎 ...

  9. (ZT)算法杂货铺——分类算法之决策树(Decision tree)

    https://www.cnblogs.com/leoo2sk/archive/2010/09/19/decision-tree.html 3.1.摘要 在前面两篇文章中,分别介绍和讨论了朴素贝叶斯分 ...

  10. JS stacktrace(Node内存溢出)

    vscode运行项目时,保存.vue文件,项目突然终止运行.输入命令npm run dev重新运行后,终端显示下面的错误. 解决方案: 如果是run dev时报错,在package.json文件里的s ...