zoukankan      html  css  js  c++  java
  • Loader for loading embedded assemblies z

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
     
    namespace Utility
    {
    public class Loader
    {
    const string LibsFolder = "Libs";
     
    static readonly Dictionary<string, Assembly> Libraries = new Dictionary<string, Assembly>();
    static readonly Dictionary<string, Assembly> ReflectionOnlyLibraries = new Dictionary<string, Assembly>();
     
    public static void Start()
    {
    AppDomain.CurrentDomain.AssemblyResolve += FindAssembly;
     
    PreloadUnmanagedLibraries();
     
    var app = new App();
    app.Run();
    }
     
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string dllToLoad);
     
    private static void PreloadUnmanagedLibraries()
    {
    // Preload correct library
    var bittyness = "x86";
    if (IntPtr.Size == 8)
    bittyness = "x64";
     
    var assemblyName = Assembly.GetExecutingAssembly().GetName();
     
    var libraries = Assembly.GetExecutingAssembly().GetManifestResourceNames()
    .Where(s => s.StartsWith(String.Format("{1}.{2}.{0}.", bittyness, assemblyName.Name, LibsFolder)))
    .ToArray();
     
    var dirName = Path.Combine(Path.GetTempPath(), String.Format("{2}.{1}.{0}", assemblyName.Version, bittyness, assemblyName.Name));
    if (!Directory.Exists(dirName))
    Directory.CreateDirectory(dirName);
     
    foreach (var lib in libraries)
    {
    string dllPath = Path.Combine(dirName, String.Join(".", lib.Split('.').Skip(3)));
     
    if (!File.Exists(dllPath))
    {
    using (Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(lib))
    {
    // Copy the assembly to the temporary file
    try
    {
    using (Stream outFile = File.Create(dllPath))
    {
    stm.CopyTo(outFile);
    }
    }
    catch
    {
    // This may happen if another process has already created and loaded the file.
    // Since the directory includes the version number of this assembly we can
    // assume that it's the same bits, so we just ignore the excecption here and
    // load the DLL.
    }
    }
    }
     
    // We must explicitly load the DLL here because the temporary directory
    // is not in the PATH.
    // Once it is loaded, the DllImport directives that use the DLL will use
    // the one that is already loaded into the process.
    LoadLibrary(dllPath);
    }
    }
     
    internal static Assembly LoadAssembly(string fullName)
    {
    Assembly a;
     
    var executingAssembly = Assembly.GetExecutingAssembly();
     
    var assemblyName = executingAssembly.GetName();
     
    var shortName = new AssemblyName(fullName).Name;
    if (Libraries.ContainsKey(shortName))
    return Libraries[shortName];
     
    var resourceName = String.Format("{0}.{2}.{1}.dll", assemblyName.Name, shortName, LibsFolder);
    var actualName = executingAssembly.GetManifestResourceNames().FirstOrDefault(n => string.Equals(n, resourceName, StringComparison.OrdinalIgnoreCase));
     
    if (string.IsNullOrEmpty(actualName))
    {
    // The library might be a mixed mode assembly. Try loading from the bitty folders.
    var bittyness = "x86";
    if (IntPtr.Size == 8)
    bittyness = "x64";
     
    resourceName = String.Format("{0}.{3}.{1}.{2}.dll", assemblyName.Name, bittyness, shortName, LibsFolder);
    actualName = executingAssembly.GetManifestResourceNames().FirstOrDefault(n => string.Equals(n, resourceName, StringComparison.OrdinalIgnoreCase));
     
    if (string.IsNullOrEmpty(actualName))
    {
    Libraries[shortName] = null;
    return null;
    }
     
    // Ok, mixed mode assemblies cannot be loaded through Assembly.Load.
    // See http://stackoverflow.com/questions/2945080/ and http://connect.microsoft.com/VisualStudio/feedback/details/97801/
    // But, since it's an unmanaged library we've already dumped it to disk to preload it into the process.
    // So, we'll just load it from there.
    var dirName = Path.Combine(Path.GetTempPath(), String.Format("{2}.{1}.{0}", assemblyName.Version, bittyness, assemblyName.Name));
    var dllPath = Path.Combine(dirName, String.Join(".", actualName.Split('.').Skip(3)));
     
    if (!File.Exists(dllPath))
    {
    Libraries[shortName] = null;
    return null;
    }
     
    a = Assembly.LoadFile(dllPath);
    Libraries[shortName] = a;
    return a;
    }
     
    using (var s = executingAssembly.GetManifestResourceStream(actualName))
    {
    var data = new BinaryReader(s).ReadBytes((int)s.Length);
     
    byte[] debugData = null;
    if (executingAssembly.GetManifestResourceNames().Contains(String.Format("{0}.{2}.{1}.pdb", assemblyName.Name, shortName, LibsFolder)))
    {
    using (var ds = executingAssembly.GetManifestResourceStream(String.Format("{0}.{2}.{1}.pdb", assemblyName.Name, shortName, LibsFolder)))
    {
    debugData = new BinaryReader(ds).ReadBytes((int)ds.Length);
    }
    }
     
    if (debugData != null)
    {
    a = Assembly.Load(data, debugData);
    Libraries[shortName] = a;
    return a;
    }
    a = Assembly.Load(data);
    Libraries[shortName] = a;
    return a;
    }
    }
     
    internal static Assembly ReflectionOnlyLoadAssembly(string fullName)
    {
    var executingAssembly = Assembly.GetExecutingAssembly();
     
    var assemblyName = Assembly.GetExecutingAssembly().GetName();
     
    string shortName = new AssemblyName(fullName).Name;
    if (ReflectionOnlyLibraries.ContainsKey(shortName))
    return ReflectionOnlyLibraries[shortName];
     
    var resourceName = String.Format("{0}.{2}.{1}.dll", assemblyName.Name, shortName, LibsFolder);
     
    if (!executingAssembly.GetManifestResourceNames().Contains(resourceName))
    {
    ReflectionOnlyLibraries[shortName] = null;
    return null;
    }
     
    using (var s = executingAssembly.GetManifestResourceStream(resourceName))
    {
    var data = new BinaryReader(s).ReadBytes((int)s.Length);
     
    var a = Assembly.ReflectionOnlyLoad(data);
    ReflectionOnlyLibraries[shortName] = a;
     
    return a;
    }
    }
     
    internal static Assembly FindAssembly(object sender, ResolveEventArgs args)
    {
    return LoadAssembly(args.Name);
    }
     
    internal static Assembly FindReflectionOnlyAssembly(object sender, ResolveEventArgs args)
    {
    return ReflectionOnlyLoadAssembly(args.Name);
    }
    }
    }
  • 相关阅读:
    音乐分类/生成杂记
    音视频编码笔记
    《The challenge of realistic music generation: modelling raw audio at scale》论文阅读笔记
    使用基于Caffe的MobileNet分类踩坑备忘录
    四大轻量化模型对比(转)
    WaveNet: 原始音频生成模型
    《SONG FROM PI: A MUSICALLY PLAUSIBLE NETWORK FOR POP MUSIC GENERATION》论文笔记
    上采样 及 Sub-pixel Convolution (子像素卷积)
    python之sys._getframe() 用于查看函数被什么函数调用以及被第几行调用及被调用函数所在文件
    11
  • 原文地址:https://www.cnblogs.com/zeroone/p/3737380.html
Copyright © 2011-2022 走看看