Created
April 18, 2019 04:35
-
-
Save decay88/05f0ebf5a35b28d90487594992a010eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Reflection; | |
using System.Security.Cryptography; | |
/// <summary> | |
/// A class for loading an Embedded Assembly | |
/// </summary> | |
/// <remarks> | |
/// Before any coding started, the DLLs have to be added into the project. | |
/// First, add the DLL as Reference. | |
/// Then, add the same DLL as file into the project. Right click the project's name > Add > Existing Item... | |
/// for Referenced DLL, in the properties explorer, change Copy Local = False | |
/// for Added DLL as File, in the properties explorer, change Build Action = Embedded Resource | |
/// If you have any other unmanaged / native DLL that is not able to be referenced, then you won't have to reference it, just add the Unmanaged DLL as embedded resource. | |
/// Obtain EmbeddedAssembly.cs and add it into project. | |
/// | |
/// Load the DLL from Embedded Resource into Memory. Use EmbeddedAssembly.Load to load it into memory. | |
/// static class Program | |
/// { | |
/// static void Main() | |
/// { | |
/// EmbeddedAssembly.Load("MyApp.System.Data.SQLite.dll", "System.Data.SQLite.dll"); | |
/// } | |
/// } | |
/// | |
/// Take note about the format of the resource string. Example: | |
/// MyApp.System.Data.SQLite.dll | |
/// This string is the Embedded Resource address in the project. | |
/// | |
/// MyApp is the project name, followed by the DLL filename. If the DLL is added inside a folder, the folder's name must be included in the resource string. Example: | |
/// MyApp.MyFolder.System.Data.SQLite.dll | |
/// | |
/// The DLLs are not distributed with the application. | |
/// When the application fails to locate the DLL, it raises an Event of AppDomain.CurrentDomain.AssemblyResolve. | |
/// AssemblyResolve request the missing DLL. The Rest is handled by EmbeddedAssembly.cs. | |
/// </remarks> | |
namespace GistBook | |
{ | |
public static class EmbeddedAssembly | |
{ | |
static Dictionary<string, Assembly> Index = new Dictionary<string, Assembly>(); | |
static EmbeddedAssembly() | |
{ | |
AppDomain.CurrentDomain.AssemblyResolve += (s, e) => | |
{ | |
if (Index == null || Index.Count == 0) return null; | |
if (Index.ContainsKey(e.Name)) return Index[e.Name]; | |
return null; | |
}; | |
} | |
static void Add(Assembly assembly) { Index.Add(assembly.FullName, assembly); } | |
/// <summary> | |
/// Load Assembly, DLL from Embedded Resources into memory. | |
/// </summary> | |
/// <param name="EmbeddedResource">Embedded Resource string. Example: WindowsFormsApplication1.SomeTools.dll</param> | |
/// <param name="FileName">File Name. Example: SomeTools.dll</param> | |
public static void Load(string EmbeddedResource, string FileName) | |
{ | |
byte[] ByteArray = null; | |
using (Stream ResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(EmbeddedResource)) | |
{ | |
// Either the file is not existed or it is not mark as embedded resource | |
if (ResourceStream == null) throw new Exception(EmbeddedResource + " was not found in Embedded Resources."); | |
// Get byte[] from the file from embedded resource | |
ByteArray = new byte[(int)ResourceStream.Length]; | |
ResourceStream.Read(ByteArray, 0, (int)ResourceStream.Length); | |
try | |
{ | |
// Add the assembly/dll into dictionary | |
Add(Assembly.Load(ByteArray)); | |
return; | |
} | |
catch | |
{ | |
bool FileNotWritten = true; | |
// Define the temporary storage location of the DLL/assembly | |
string TempFilePath = Path.GetTempPath() + FileName; | |
using (SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider()) | |
{ | |
// Get the hash value from embedded DLL/assembly | |
string HashValue = BitConverter.ToString(SHA1.ComputeHash(ByteArray)).Replace("-", string.Empty); | |
// Determines whether the DLL/assembly is existed or not | |
if (File.Exists(TempFilePath)) | |
{ | |
// Get the hash value of the existed file | |
string HashValueOfExistingFile = BitConverter.ToString( | |
SHA1.ComputeHash(File.ReadAllBytes(TempFilePath))).Replace("-", string.Empty); | |
// Compare the existed DLL/assembly with the Embedded DLL/assembly | |
if (HashValue == HashValueOfExistingFile) FileNotWritten = false; | |
} | |
} | |
// Create the file on disk | |
if (FileNotWritten) File.WriteAllBytes(TempFilePath, ByteArray); | |
// Add the loaded DLL/assembly into dictionary | |
Add(Assembly.LoadFrom(TempFilePath)); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment