Встроить библиотеки DLL в форму Windows (система не может найти указанный файл.) - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь встроить сторонние библиотеки DLL в форму Windows.Стороннюю библиотеку можно найти здесь (Денис Магно - MetroFramework-Modern-UI)

Все работает правильно, если я запускаю приложение из папки bin, где / когда находятся библиотеки DLL MetroFrameworkподарок.Однако я не могу встроить их в свой exe.

Я попробовал несколько вещей:

  1. Я следовал этому учебнику (вручную установить DLL для встроенных ресурсов +обработчик кода)
  2. Я пытался использовать Costura.Fodi (установлен из Nuget)
  3. Я посмотрел на ILMerge

Я всегда получаю ту же ошибку при запускеприложение:

Не удалось загрузить файл или сборку 'MetroFramework, версия = 1.4.0.0, культура = нейтральная, PublicKeyToken = 5f91a84759bf584a' или одна из ее зависимостей.Система не может найти указанный файл.

Для справки вот код, который я использовал в качестве обработчика для первого опробованного мной варианта:

        AppDomain.CurrentDomain.AssemblyResolve += (Object sender, ResolveEventArgs args) =>
        {
            String thisExe = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            System.Reflection.AssemblyName embeddedAssembly = 
                                                           new System.Reflection.AssemblyName(args.Name);
            String resourceName = thisExe + "." + embeddedAssembly.Name + ".dll";

            using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            {
                Byte[] assemblyData = new Byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return System.Reflection.Assembly.Load(assemblyData);
            }
        };

РЕДАКТИРОВАТЬ 1: После того, как комментарии указали мне правильное направление, я изменил свой код так:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
       //Embed extra DLLs defined as 'embeddedResources' (MetroFramework)
       AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler;
       realMain();
    }

    [MethodImpl(MethodImplOptions.NoInlining)] 
    private static void realMain()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }


    public static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
    {
        String thisExe = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        System.Reflection.AssemblyName embeddedAssembly =
                                                       new System.Reflection.AssemblyName(args.Name);
        String resourceName = thisExe + ".libs." + embeddedAssembly.Name + ".dll";
        // String resourceName = embeddedAssembly.Name + ".dll";
        var debugStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
        string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames();

        using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return System.Reflection.Assembly.Load(assemblyData);
        }
    }
}

Регистрация события AssemblyResolve до всего остального и вызов остального кода из другого метода (realMain ()) решил эту проблему.

Но теперь то же исключение выдается из Models.Designer.cs (я использую .NET 3.5 и EF v1).Следующий код теперь приводит к исключению:

 public List<MyObj> selectGalLocation(string num) 
    {
        using (My_Entities db = new My_Entities())
        {
            //some PCs may be used for more than one stage/station....
            return db.MyObj.Include("L_Lookup").Include("P_DB").Where(x => x.no == num).ToList();
        }
    }

Код, который фактически генерирует исключение, генерируется автоматически:

 public partial class CTRS_Entities : global::System.Data.Objects.ObjectContext
{
    /// <summary>
    /// Initializes a new My_Entities object using the connection string found in the 'My_Entities ' section of the application configuration file.
    /// </summary>
    public My_Entities() : 
            base("name=My_Entities ", "My_Entities ")
    {
        this.OnContextCreated();
    }

Я не понимаю, почему этот код не связанMetroFramework, насколько я могу судить, бросает исключение.Там явно что-то я не правильно понимаю ...

Спасибо за помощь

...