c# - 控制台程序 合并Dll 不使用任何第三方插件

准备工作:

1. 新建一个控制台程序Project:CombinedDlls.

2. 再新建一个Class Library Project: ThirdPartyTool,新建一个类Util.cs, 在其中实现一个static的SayHelloTo(string name)方法。

3. CombinedDlls引用ThirdPartyTool,并在代码中调用SayHelloTo方法。

SayHelloTo方法。

using System;

namespace ThirdPartyTool
{
    public class Util
    {
        public static void SayHelloTo(string name)
        {
            Console.WriteLine("Hello " + name);
        }
    }
}

在控制台程序工程(CombinedDlls)的Main()中调用:SayHelloTo方法。 

using System;
using System.Linq;
using System.Reflection;
using ThirdPartyTool;

namespace CombineDlls
{
    class Program
    {
        static void Main(string[] args)
        {
            Util.SayHelloTo("Peter");
            Console.ReadLine();
        }
    }
}

这时我们Build程序,可是看到Build之后的文件如下图所示。

运行之后如下图所示:

开始改造:

1. 编辑CombineDlls.csproj,在文件中增加以下代码,目的是将引用的dll增加到控制台程序的Resource中。

  <Target Name="AfterResolveReferences">
    <ItemGroup>
      <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
        <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.FileName)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
      </EmbeddedResource>
    </ItemGroup>
  </Target>

增加之后如图所示:

2. 在控制台程序(CombinedDlls)中增加定位在resource中dll的代码,修改完成之后的代码如下:

using System;
using System.Linq;
using System.Reflection;
using ThirdPartyTool;

namespace CombineDlls
{
    class Program
    {
        static Program()
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        }

        static void Main(string[] args)
        {
            Util.SayHelloTo("Peter");
            Console.ReadLine();
        }

        private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            var currentAssembly = Assembly.GetExecutingAssembly();
            var requiredDllName = $"{(new AssemblyName(args.Name).Name)}.dll";
            var resource = currentAssembly.GetManifestResourceNames().Where(s => s.EndsWith(requiredDllName)).FirstOrDefault();

            if (resource != null)
            {
                using (var stream = currentAssembly.GetManifestResourceStream(resource))
                {
                    if (stream == null)
                        return null;

                    var block = new byte[stream.Length];
                    stream.Read(block, 0, block.Length);
                    return Assembly.Load(block);
                }
            }
            else
            {
                return null;
            }
        }
    }
}

3. 这时我们Build之后,在output中看到的文件 如下:

我们发现并没有什么不同,我们直接执行结果如下图所示:

我们删掉ThirdPartyTool.dll, ThirdPartyTool.dll.config,ThirdPartyTool.pdb之后,执行结果不变,仍如下图所示:

 

因为我们已经将ThirdPartyTool.dll添加到CombinedDll.exe中了,因此直接使用CombinedDll.exe即可。

完整代码:https://github.com/yuxuac/CombinedDll

发布了130 篇原创文章 · 获赞 20 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/yuxuac/article/details/103334220