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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章