如何将DLL与.exe文件结合在一个wpf / winforms应用程序中(带图片) [英] How to combine DLLs with .exe inside of a wpf / winforms application (with pictures)

查看:109
本文介绍了如何将DLL与.exe文件结合在一个wpf / winforms应用程序中(带图片)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将多个dll组合到主.exe文件? (不使用第三方程序)

解决方案

更新



if您需要一个简单的工具来合并程序集,而无需担心任何工作,然后


5 - 现在到代码部分:

首先导入此命名空间



vb.net

  Imports System.Reflection 

c# / p>

 使用System.Ref经文; 

在构造函数(vB中的[Sub New])中添加此代码



Vb.net

  Public Sub New()
AddHandler AppDomain.CurrentDomain.AssemblyResolve ,AddressOf OnResolveAssembly
End Sub

c#.net

  public App()
{
AppDomain.CurrentDomain.AssemblyResolve + = OnResolveAssembly;
}

然后添加 OnResolveAssembly 功能

vb.net

 '''< summary> 
'''告诉程序它正在寻找的程序集位于嵌入式资源中通过使用
'''< see cref =Assembly.GetManifestResourceNames/>函数获取所有资源
'''< / summary>
'''< param name =sender>< / param>
'''< param name =args>< / param>
'''< returns>< / returns>
'''< remarks>请注意,如果dll与应用程序位于同一文件夹(有时)< / remarks>,则此事件不会触发。
私有共享函数OnResolveAssembly(sender As Object,args As ResolveEventArgs)As Assembly
尝试
'获取主程序集
Dim parentAssembly = Assembly.GetExecutingAssembly()
' args.Name将是这样的
'[MahApps.Metro,Version = 1.1.3.81,Culture = en-US,PublicKeyToken = null]
'所以我们以大会的名称(MahApps。 Metro)然后添加(.dll)
Dim finalname = args.Name.Substring(0,args.Name.IndexOf(,c))& .dll
'这里我们搜索我们的dll的资源并获得第一个匹配
Dim ResourcesList = parentAssembly.GetManifestResourceNames()
Dim OurResourceName As String = Nothing
'(你可以用[Find]或[First]的LINQ扩展名代替这个。
对于i As Integer = 0到ResourcesList.Count - 1
Dim name = ResourcesList(i)
如果名字.EndsWith(finalname)然后
'获取名称,然后关闭循环以获取第一个发生值
OurResourceName = name
退出
结束如果
下一个

如果不是String.IsNullOrWhiteSpace(OurResourceName)然后
'获取表示我们资源的流,然后将其加载为字节
使用流As Stream = parentAssembly.GetManifestResourceStream(OurResourceName)
'in vb.net use [New Byte(stream.Length - 1)]
'in c#.net use [new byte [stream.Length]; ]
Dim block As Byte()=新的字节(stream.Length - 1){}
stream.Read(block,0,block.Length)
返回Assembly.Load(块)
结束使用
Else
返回没有
结束If
Catch ex As Exception
返回没有
结束尝试
结束函数

c#.net

 code> ///< summary> 
///告诉程序它的Seeking所在的程序位于嵌入式资源中通过使用
///< see cref =Assembly.GetManifestResourceNames/>功能获取所有资源
///< / summary>
///< param name =sender>< / param>
///< param name =args>< / param>
///< returns>< / returns>
///< remarks>请注意,如果dll与应用程序位于同一文件夹(有时)< / remarks>,则此事件不会触发。
private static Assembly OnResolveAssembly(object sender,ResolveEventArgs args)
{
try {
//获取主程序集
var parentAssembly = Assembly.GetExecutingAssembly();
//args.Name将是这样的
// [MahApps.Metro,Version = 1.1.3.81,Culture = en-US,PublicKeyToken = null]
//所以我们采取大会的名称(MahApps.Metro)然后添加(.dll)
var finalname = args.Name.Substring(0,args.Name.IndexOf(','))+.dll;
//这里我们搜索我们的dll的资源并获得第一个匹配
var ResourcesList = parentAssembly.GetManifestResourceNames();
string OurResourceName = null;
//(你可以用[Find]或[First]的LINQ扩展名代替这个)
for(int i = 0; i< = ResourcesList.Count - 1; i ++){
var name = ResourcesList(i);
if(name.EndsWith(finalname)){
//获取名称,然后关闭循环以获取第一个发生值
OurResourceName = name;
break;
}
}

if(!string.IsNullOrWhiteSpace(OurResourceName)){
//获取表示我们资源的流,然后将其加载为字节
使用(Stream stream = parentAssembly.GetManifestResourceStream(OurResourceName)){
// in vb.net use [New Byte(stream.Length - 1)]
// in c#.net use [new byte [ stream.Length]; ]
byte [] block = new byte [stream.Length];
stream.Read(block,0,block.Length);
return Assembly.Load(block);
}
} else {
return null;
}
} catch(Exception ex){
return null;
}
}

6 - 现在发布应用程序或构建它您的DLL将嵌入到一个EXE文件中(延迟一些毫秒级以加载它们)



更新DLL



1 - 只需将新的dll拖放到解决方案资源管理器中,就像旧的DLL一样,然后接受覆盖(请确保检查[Build Action = Embedded Resources]和[Copy To Output Directory = Do不复制])





添加新的DLL



只需重复步骤1 => 3



Credits:



http://richarddingwall.name/2009/05/14/wpf-how-to-combine-mutliple-assemblies-into-a-single -exe /



*随时问你是否有任何pr oblem


How to combine multiple dlls into the main .exe file? (without using third-party programs)

解决方案

Update

if you want an easy tool to merge the assemblies without worrying about doing ANY work at all then Fody.Costura is the best choice you have, as all you need to do is just include the dlls and change their Build Action to Embedded Resource and it will work right away.


1 - make a folder that contains all of the Dlls or place them separately as you like

2 - Click on each DLL from the "Solution Explorer" and make sure they have these properties

  • Build Action = Embedded Resources

  • Copy To Output Directory = Do not copy

3 - Go to : Project > Properties > References , And make sure every Dll you add has the same name as the assembly like this :

In References :-

In Solution Explorer :-

Note :-

It's Better to Make copy local = True in references as it will give you an updated DLL each time you publish the project

Now at this point you have your DLLs added to the EXE , all is remaining now is to tell the program how to read these DLLs from the EXE (that's why we made build action = Embedded resources)

4 - In Solution Explorer Open your (Application.xaml.vb) file ([App.xaml.cs] in c#)
OR
Go To : Project > Properties > Application > View Application Events

Now in this page we are going to handle the very first event of the application (Construction event) to tell the program how to handle the assemblies we add as DLLs before loading/reading them by using the AssemblyResolve Event

Check this MSDN page for more Info about the AssemblyResolve Event https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve(v=vs.110).aspx

5 - Now to The code part :
first of all Import this namespace

vb.net

Imports System.Reflection  

c#

using System.Reflection;

In the Constructor ([Sub New] in vb) add this code

Vb.net

 Public Sub New()
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf OnResolveAssembly           
 End Sub

c#.net

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;       
}

Then add the OnResolveAssembly Function
vb.net

''' <summary>
''' Tells the program that the Assembly it's Seeking is located in the Embedded resources By using the
''' <see cref="Assembly.GetManifestResourceNames"/> Function To get All the Resources
''' </summary>
''' <param name="sender"></param>
''' <param name="args"></param>
''' <returns></returns>
''' <remarks>Note that this event won't fire if the dll is in the same folder as the application (sometimes)</remarks>
Private Shared Function OnResolveAssembly(sender As Object, args As ResolveEventArgs) As Assembly
    Try
        'gets the main Assembly
        Dim parentAssembly = Assembly.GetExecutingAssembly()
        'args.Name will be something like this
        '[ MahApps.Metro, Version=1.1.3.81, Culture=en-US, PublicKeyToken=null ]
        'so we take the name of the Assembly (MahApps.Metro) then add (.dll) to it
        Dim finalname = args.Name.Substring(0, args.Name.IndexOf(","c)) & ".dll"
        'here we search the resources for our dll and get the first match
        Dim ResourcesList = parentAssembly.GetManifestResourceNames()
        Dim OurResourceName As String = Nothing
        '(you can replace this with a LINQ extension like [Find] or [First])
        For i As Integer = 0 To ResourcesList.Count - 1
            Dim name = ResourcesList(i)
            If name.EndsWith(finalname) Then
                'Get the name then close the loop to get the first occuring value
                OurResourceName = name
                Exit For
            End If
        Next

        If Not String.IsNullOrWhiteSpace(OurResourceName) Then
            'get a stream representing our resource then load it as bytes
            Using stream As Stream = parentAssembly.GetManifestResourceStream(OurResourceName)
                'in vb.net use [ New Byte(stream.Length - 1) ]
                'in c#.net use [ new byte[stream.Length]; ]
                Dim block As Byte() = New Byte(stream.Length - 1) {}
                stream.Read(block, 0, block.Length)
                Return Assembly.Load(block)
            End Using
        Else
            Return Nothing
        End If
    Catch ex As Exception
        Return Nothing
    End Try
End Function

c#.net

/// <summary>
/// Tells the program that the Assembly its Seeking is located in the Embedded resources By using the
/// <see cref="Assembly.GetManifestResourceNames"/> Function To get All the Resources
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <returns></returns>
/// <remarks>Note that this event won't fire if the dll is in the same folder as the application (sometimes)</remarks>
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
    try {
        //gets the main Assembly
        var parentAssembly = Assembly.GetExecutingAssembly();
        //args.Name will be something like this
        //[ MahApps.Metro, Version=1.1.3.81, Culture=en-US, PublicKeyToken=null ]
        //so we take the name of the Assembly (MahApps.Metro) then add (.dll) to it
        var finalname = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
        //here we search the resources for our dll and get the first match
        var ResourcesList = parentAssembly.GetManifestResourceNames();
        string OurResourceName = null;
        //(you can replace this with a LINQ extension like [Find] or [First])
        for (int i = 0; i <= ResourcesList.Count - 1; i++) {
            var name = ResourcesList(i);
            if (name.EndsWith(finalname)) {
                //Get the name then close the loop to get the first occuring value
                OurResourceName = name;
                break;
            }
        }

        if (!string.IsNullOrWhiteSpace(OurResourceName)) {
            //get a stream representing our resource then load it as bytes
            using (Stream stream = parentAssembly.GetManifestResourceStream(OurResourceName)) {
                //in vb.net use [ New Byte(stream.Length - 1) ]
                //in c#.net use [ new byte[stream.Length]; ]
                byte[] block = new byte[stream.Length];
                stream.Read(block, 0, block.Length);
                return Assembly.Load(block);
            }
        } else {
            return null;
        }
    } catch (Exception ex) {
        return null;
    }
}

6 - now publish the application or build it and all your dlls will be embedded in a single EXE file (with some extra milliseconds delay to load them)

To Update the DLLs

1 - Simply drag and drop your new dll to the Solution Explorer as the same folder as the old dll then accept the override (make sure to check that [Build Action = Embedded Resources] AND [Copy To Output Directory = Do not copy])

To Add New DLLs

just repeat step 1 => 3

Credits :

http://richarddingwall.name/2009/05/14/wpf-how-to-combine-mutliple-assemblies-into-a-single-exe/

*Feel free to ask if you had any problem

这篇关于如何将DLL与.exe文件结合在一个wpf / winforms应用程序中(带图片)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆