有時候咱們引用了一個小型的類庫文件,可是若是發佈程序,就須要帶一個類庫文件,感受有點累贅,那該怎麼辦?
一些第三方的混淆工具自帶類庫集成,是一個不錯的解決辦法。
可是若是我只想使用本身的解決方法,那麼能夠嘗試將類庫文件以資源嵌入的方式,集成入程序集內!工具
可是我在測試這個辦法的時候,常常會發現程序沒法正確加載類庫。
以下面的代碼,實際上每次在執行時都會發生錯誤:測試
Sub Main() Dim dllName As String = "程序命名空間.類庫文件.dll" Dim dllStream As IO.Stream = Reflection.Assembly.GetEntryAssembly.GetManifestResourceStream(dllName) Dim dllbytes(dllStream.Length - 1) As Byte dllStream.Read(dllbytes, 0, dllStream.Length) dllStream.Close() Reflection.Assembly.Load(dllbytes) Application.EnableVisualStyles() Application.Run(New Main) End Sub
當執行以上代碼,程序能夠正確加載位於程序集內部的類庫文件,在啓動時不會發生任何錯誤。
可是當咱們在窗體內執行類庫內的代碼,就會發生沒法引用類庫的錯誤。
究竟錯在了哪裏?讓我百思不得其解。google
後來我google了一下問題緣由,發現.NET程序並非在使用時纔開始解析並生成本地代碼,而是在以前就已經生成了各類對象的引用指針。
可是在引用時,若是發現對象並不存在,則會引起一個 AppDomain.AssemblyResolve
事件,所以能夠經過 AssemblyResolve
來在發生類庫引用錯誤時,動態地返回類庫程序集實例。spa
因此咱們只須要將加載事件改動到 AssemblyResolve
中就能夠了。ssr
Sub main() AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf assresolve Application.EnableVisualStyles() Application.Run(New Form1) End Sub Private Function assresolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly Dim aName As String = New Reflection.AssemblyName(args.Name).FullName If aName = "類庫完整描述名" Then Dim dllName As String = "程序命名空間.類庫文件.dll" Dim dllStream As IO.Stream = Reflection.Assembly.GetEntryAssembly.GetManifestResourceStream(dllName) Dim dllbytes(dllStream.Length - 1) As Byte dllStream.Read(dllbytes, 0, dllStream.Length) dllStream.Close() Return Reflection.Assembly.Load(dllbytes) End If Return Nothing End Function
這樣,當加載類庫發生錯誤之時,就會自動的加載內嵌的DLL文件到程序中。指針