打包dll到WPF程序中

By | 2020-12-24
参考:https://blog.csdn.net/m0_37862405/article/details/81532077

在WPF中,将dll作为嵌入的资源打包到exe中的步骤:

注:该方法不能将非C#类型的dll(比如:C++编译的dll)打包到exe

第一步:添加以下代码段到WPF项目的.csproj文件中(需添加到节点“Import”的后面)。个人理解这段代码的作用:设置项目引用的dll为嵌入的资源(经测试,单独手动设置dll为嵌入的资源无效,必须添加这段代码到项目文件中,且需在节点“Import”的后面)

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

第二步:添加以下代码到Program.cs(若没有Program.cs,可以新建一个)

public class Program
    {
        /// <summary>
        /// 使用静态构造函数来绑定解析程序集失败事件
        /// </summary>
        static Program()
        {
            AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
        }

        [STAThreadAttribute]
        public static void Main()
        {
            App.Main(); //启动WPF项目
        }

        //解析程序集失败,会加载对应的程序集
        private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
        {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = new AssemblyName(args.Name);

            var path = assemblyName.Name + ".dll";
            //判断程序集的区域性
            if (!assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture))
            {
                path = string.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
            }

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

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

第三步:在项目属性中,修改项目的启动对象为Program.cs

发表评论

邮箱地址不会被公开。 必填项已用*标注