WinForm实现多个可执行文件的合并和执行

1 引言<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
这种情况,常常出现在我们的变态需求里,因为客户常常是“无理”的。他们不希望见到过多的文件,尤其是过多的可执行文件,对于很多陌生的计算机用户来说,仅仅点击一次就可以完成所有的事情。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
你看,我们的老王主任(虚拟人物,如有雷同,纯属虚构)不满意项目组提交的服务启动程序了,因为原来的实现并没有考虑太多的用户体验,我们要求客户首先设置必要的参数和启动条件,然后再启动专门的服务程序。就是这两次简单的操作,老王主任火冒三丈,因为他总是点错了顺序倒置程序加载问题,从而顺便迁怒到我们辛苦做了10个月的系统上。“你的东西太烂了,连打开就都这么费劲”,我读懂了老王的潜台词,然后默默的回去解决这个不是问题的问题。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
对需求来说,客户永远是对的。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
2 实现的步骤<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
2.1 基本步骤<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 准备好外部加载的可执行文件(Anytao_Insidenet_QuickLink.exe),新建项目
  • 将可执行文件加载到资源文件
    • 新建资源文件(ExeRes.resx)
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
    • 将可执行文件加载到资源文件:打开资源文件ExeRes.resx,选择Add Existing File,并加载准备好的可执行程序
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
    • 访问资源文件:.NET中资源文件的访问非常方便,Visual Studio会自动生成对于资源文件的逻辑代码,类似于实体化处理。例如打开ExeRes.Designer.cs可以看到(省略部分代码)
    internal class ExeRes {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                internal ExeRes() {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                internal static byte[] Anytao_Insidenet_QuickLink {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            get {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                object obj = ResourceManager.GetObject("Anytao_Insidenet_QuickLink", resourceCulture);                return ((byte[])(obj));<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
    }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
因此,对于资源文件的访问可以是:<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            byte[] bytesExe = ExeRes.Anytao_Insidenet_QuickLink;<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
由此,就可以成功的将一个可执行文件加载到资源文件,并通过静态属性来访问。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 应用文件流还原可执行文件
应用文件流还原可执行文件,是个简单的操作,不必做过多的交代:<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Copyright  : http://www.anytao.com/<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Author      : Anytao,http://www.anytao.com/<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Release    : 2008/05/24 1.0<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        public void GetExeFromBytes(byte[] buffer, string fileName)<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            FileStream fs = new FileStream(fileName, FileMode.Create);<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            BinaryWriter writer = new BinaryWriter(fs);<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            try<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                writer.Write(buffer, 0, buffer.Length);<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            catch (IOException ex)<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                Trace.WriteLine(ex.Message);<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            finally<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                writer.Close();<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
                fs.Close();<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
可以通过buffer来指定要处理的资源文件,通过fileName来指定要生成的目标路径,一个活生生的可执行文件就这样呱呱落地了。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 在程序中打开外部可执行文件
对于释放的可执行文件,通过应该程序来打开通常是以Process组件来完成的,例如:<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Copyright  : http://www.anytao.com/<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Author      : Anytao,http://www.anytao.com/<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        // Release    : 2008/05/24 1.0<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        public void RunExe(string fileName)<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        {<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            Process myProc = new Process();<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            myProc.StartInfo.FileName = fileName;<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            myProc.Start();<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
            myProc.WaitForExit();<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
        }<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
基本的过程,就是如此简单,而对于实现老王主任的变态需求,已经算是“最简单的方式了”。小王用10分钟交了答卷,还有什么好办法呢,可能思考还未停止。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 你还可以有更多的操作:删除释放的可执行文件,加载和释放更多的可执行程序。
具体的实现,见源码下载来具体了解。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
2.2 原理分析<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
纵观整个解决方案,其实应用.NET的基本原理并不复杂,而将这些简单的原理进行组合应用,就有了简单有效的解决方案。以本文为例,我们涉及的基础性内容主要包括:<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 资源文件
关于资源文件,我将以专题形式来讲解,展现一个全面而有深度的理解,大家敬请关注吧:-) <º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 文件流处理
讲得太多了,还需要吗,或许吧,但不是现在。 <º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • 外部程序加载
示例中已经有很清楚的描述了,可以参见相关的实例进一步了解。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
三个不是很负责的技术点,解决一个其实也并不复杂的变态需求,如何技术永远可以停留在这里,那就没什么意思了。最重要的是,技巧性的背景下,可以挖掘更多的思考,这才是重要的。  <º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
3 其他的方式<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
其实,一定有很多的大牛,不屑于这种呆板的解决思路,你可以理直气壮的提出至少以下几种方案来解决“老王的烦恼”,例如:<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
  • WinRar自解压模式
  • Windows Install安装程序
  • Install Shield安装程序
  • 其他安装程序
对于轻量型的需求来说,采用本文的方案不失为一种选择,至少在程序中控制对于其他可执行文件的控制,可以提高更多的需求适应。不过,前提是加载到资源文件的可执行文件和相关文件是轻量级的,不然蜗牛般的打开速度,同样使老王主任投去不懈的表情,他的眼神很有杀伤力。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
而本文的方案,并不仅仅只能应付可执行文件这样的花招上,将思路和眼界放得更加开阔时,采用资源文件和文件流处理方式,可以灵活的应对很多的问题和方案。而这些思考,就用不着由小王来代劳,全看大家了。<º’|Y€'}\9www.netcsharp.cn•óŒ_x0ѯô
posted on 2008-11-08 13:55  markbum  阅读(233)  评论(0)    收藏  举报