热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WPF程序将DLL嵌入到EXE的两种方法

WPF程序将DLL嵌入到EXE的两种方法这一篇可以看作是《VisualStudio版本转换工具WPF版开源了》的续,关于《VisualStudio版本转换工具WPF版开源了》可以参看

WPF程序将DLL嵌入到EXE的两种方法

这一篇可以看作是《Visual Studio 版本转换工具WPF版开源了》的续,关于《Visual Studio 版本转换工具WPF版开源了》可以参看地下地址(两篇是一样的):

  1. 开源中国 http://my.oschina.net/chinesedragon/blog/308336
  2. CNBLOGS http://www.cnblogs.com/luoshupeng/p/3946635.html

** 博客园的Markdown编辑器真的不行,还是麻烦大家稳步到http://my.oschina.net/chinesedragon/blog/309223观看吧 **

引言

前几一写了一个小工具————《Visual Studio版本转换工具》,由于使用了WPF做为界面,因此这个小程序运行必须附带两个DLL:Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll,同时由于自己也写了一个库,一个小程序需要附带3个DLL,这种体验真的很不爽,于是就着手把DLL嵌入到EXE中去。

挫折

对于C#程序,要把DLL嵌入到EXE中去,最权威和最常见的方法就是使用ILMerge这个工具,这是个命令行工具,有很多参数,可以将DLL很完美的嵌入到EXE中去,如果嫌命令行麻烦,也有人开源开发了图形界面ILMergeGUI,这两个工具的下载和帮助地址如下:

  1. ILMerge http://www.microsoft.com/en-us/download/details.aspx?id=17630
  2. ILMerge-GUI http://ilmergegui.codeplex.com/
    于是下载了这两个工具,却出现将DLL嵌入到EXE中错误的情况,在网上查了下原因,竟然是ILMerge不支持WPF程序,我勒了个去,微软,你让我说你什么好呢?
    ILMerge可以将Winform程序的DLL完美地嵌入到EXE中去(这一点我亲自测试了下,很不,点赞),但对WPF却不支持,原因是WPF的DLL中含有资源无法解决,微软,你好意思说这个工具是你开发的吗?

Winform程序将DLL嵌入到EXE中(一)——使用命令行 

下载ILMerge或者同时下载ILMerge-GUI,使用图形界面和使用命令行是同一个道理,只是图形界面简单些,所以这里以命令行说明。
我是下载ILMerge安装后,把ILMerge.exe复制到C:\Windows目录下去了,这样可以直接在命令行中使用而不用去设置环境变量,不管怎样,只要能够在命令行下使用这个工具就行。
ILMerge有很多参数,其中有几个比较重要:

  1. /target:目标,有library和Winexe两种选择,当将多个DLL整合成一个DLL时可以使用library,当要整合为EXE时,应该使用Winexe.
  2. /out:输出,最终生成文件的路径和名称.
  3. /log:输入,如果输入是EXE时可以不使用此参数直接写,而如果输入时DLL时,最好使用此参数
    还有其它一些参数,使用时可以百度或者google一下,这是我测试的一张图片:

Winform程序将DLL嵌入到EXE中(二)——使用ILMerge.MSBuild.Tasks

ILMerge也使用Nuget发布了工具,使用Nuget的好处想必大家都知道,所以推荐使用这种方法
第一步, 使用Nuget图形或Nuget命令下载ILMerge.MSBuild.Tasks

PM> Install-Package ILMerge.MSBuild.Tasks   

第二步, 把VS项目文件记事本或者其它文本编辑工具打开,我使用的是Sublime Text 3,并按照如下格式根据实际情况修改:

  
  
  
    
      
       
      
    
    
      $(ProjectDir)$(OutDir)MERGED_ASSEMBLY_NAME.exe
    
    
    

这样编译后就可以了。

WPF程序将DLL嵌入到EXE中(一)——将DLL自动转换为嵌入资源

第一步,修改项目文件,将DLL自动转换为嵌入资源。
把VS项目文件记事本或者其它文本编辑工具打开,我使用的是Sublime Text 3,并将下面内容添加到文件末尾:


    
      
        %(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)
      
    

第二步,修改App.xaml文件,在程序启动时加载资源

public partial class App : Application
{
    private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
    {
        Assembly executingAssembly = Assembly.GetExecutingAssembly();
        var executingAssemblyName = executingAssembly.GetName();
        var resName = executingAssemblyName.Name + ".resources";

        AssemblyName assemblyName = new AssemblyName(args.Name); string path = "";
        if (resName == assemblyName.Name)
        {
            path = executingAssemblyName.Name + ".g.resources"; ;
        }
        else
        {
            path = assemblyName.Name + ".dll";
            if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false)
            {
                path = String.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
            }
        }

        using (Stream stream = executingAssembly.GetManifestResourceStream(path))
        {
            if (stream == null)
                return null;

            byte[] assemblyRawBytes = new byte[stream.Length];
            stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
            return Assembly.Load(assemblyRawBytes);
        }
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
    }
}

第三步,dll嵌入exe后,目录中的dll就没用了,配置Post buid 脚本自动删除dll:

cd $(TargetDir)
del *.dll

有些情况下,以上方法也不行,那么可以尝试 Eazfuscator.NET
Eazfuscator.NET以前免费,现在已经变成收费软件了,不过找个免费的3.3版本也可以支持VS2010和VS2012

WPF程序将DLL嵌入到EXE中(二)——使用LibZ Container

LibZ是ILMerge的另外一个选择,它同样可以把DLL嵌入到EXE中去,在我的测试中它可以完成WPF程序的DLL嵌入到EXE中去,但好像这个组件使用的人不是很多。
LibZ Container的项目主页是http://libz.codeplex.com/
LibZ同样提供了Nuget下载,使用Nuget有很多好处,所以推荐使用这种方式
使用Nuget图形或者命令下载LibZ.Bootstrap

Install-Package LibZ.Bootstrap

然后,配置Post buid 脚本:

set LIBZ=$(SolutionDir)packages\LibZ.Bootstrap.1.1.0.2\tools\libz.exe
%LIBZ% inject-dll --assembly VSConverter.WPF.exe --include *.dll --move

编译通过后就可以了。这里需要注意的是--assembly后的参数是项目生成的文件名.
LibZ还有很多用法,可以到项目文档学习。

参考资料

  1. Combining multiple assemblies into a single EXE for a WPF application
  2. DLL嵌入exe中
  3. LibZ项目

Nuget是个十分强大的工具,使用Nuget在很多时候可以使解决方法变得简单,给Nuget赞一个!
再做下广告,Visual Studio版本转换工具WPF版的代码托管地址是:http://git.oschina.net/shupengluo/VSConverter,欢迎交流。

最后,再小小地鄙视下微软,^_^


推荐阅读
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • Python自动化测试入门:Selenium环境搭建
    本文详细介绍如何在Python环境中安装和配置Selenium,包括开发工具PyCharm的安装、Python环境的设置以及Selenium包的安装方法。此外,还提供了编写和运行第一个自动化测试脚本的步骤。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 本文详细介绍了流编辑器sed中的G、H、g、h命令,探讨了它们的工作原理及应用场景。通过实例解析和图解分析,帮助读者掌握这些高级命令的使用方法。 ... [详细]
  • 本文介绍了一个基于 Java SpringMVC 和 SSM 框架的综合系统,涵盖了操作日志记录、文件管理、头像编辑、权限控制、以及多种技术集成如 Shiro、Redis 等,旨在提供一个高效且功能丰富的开发平台。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
author-avatar
无V量_897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有