.NET

.net framework wpf 打包生成单个exe文件

2020-04-25  本文已影响0人  夜里的向日葵

如果直接编译wpf程序,会在bin/Release生成此程序的exe文件以及引用的一些dll文件,如下图

img

要想执行此exe程序,那么必须将引用的dll放到同一目录,一旦引用的程序集多起来了就比较麻烦了,程序发给别人可能需要压缩成zip

本文的目的是将此程序打包成单个exe文件,思路很简单,将引用的dll文件嵌入到exe中即可.

将dll程序集嵌入到exe文件

1.在项目csproj文件添加以下内容

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

2.App类添加以下代码

static App() {
    var assembly = typeof(App).Assembly;
    AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
}

private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) {
    var executingAssembly = Assembly.GetExecutingAssembly();
    var assemblyName = new AssemblyName(args.Name);

    var path = assemblyName.Name + ".dll";
    if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false)
        path = $@"{assemblyName.CultureInfo}\{path}";
    using var 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);
}

完成! 接下来我们编译项目,打开bin/Release目录


image.png

可以发现HelloWorld.exe体积变大了,因为dll文件已经嵌入到里面了, 这里我们只把exe复制出来, 是可以单独运行的. 到这里我们的目的就已经达到了. 但我们的bin/Release目录现在除了exe文件,其他文件是没有用处的, 通过下面的步骤我们可以去除其他的dll文件

删除exe以外的文件

在项目的csproj添加以下内容

   <Target Name="DeleteOtherFile" AfterTargets="AfterBuild">
        <ItemGroup>
            <OtherFiles Include="$(OutputPath)\*" Exclude="$(OutputPath)\$(AssemblyName).exe" />
        </ItemGroup>
        <Delete Files="@(OtherFiles)" />
    </Target>

接着再次编译项目, 打开bin/Release目录

image.png

可以看到里面就剩这么单个文件了,大功告成~

上一篇下一篇

猜你喜欢

热点阅读