Загрузите и запустите WPF DLL в другой исполняемый файл WPF

1

Моя основная проблема, как я сказал в названии.

WPF_APP1 → Я создал dll этого проекта wpf после исключения App.xaml
WPF_APP2 → Обычный WPF exe. которому необходимо запустить вышеупомянутую dll WPF_APP1 и открыть форму WPF_APP1 MainWindow с использованием отражения.

Почему я говорю для размышления - WPF_APP2 сначала открывает последнюю версию WPF_APP1.dll, поэтому не может добавить ссылку на dll. должны использовать только отражение.

Когда я использую приведенную выше DLL в проекте cmd, все в порядке. он откроет окно CMD, а затем запустит форму WPF_APP1 MainWindow как окно.

Но теперь мне нужно открыть эту оконную форму не в cmd, а в WPF_APP2.

Пожалуйста, помогите мне.

Проект CMD использует приведенный ниже код для открытия WPF_APP1 MainWindow.

    static void Main(string[] args)
    {            
        Thread t = new Thread(ThreadProc);
        t.SetApartmentState(ApartmentState.STA);
        t.IsBackground = true;
        t.Start();

        Console.ReadLine();                   
    }


    private static void ThreadProc()
    {
        string loc = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName
                      + "\\AutoUpdateTesting.dll";

        Assembly dll = Assembly.LoadFile(loc);

        foreach (Type type in dll.GetExportedTypes())
        {                
            if (type.Name.Equals("MainWindow"))
            {                   
                dynamic n = null;
                n = Activator.CreateInstance(type);
                n.InitializeComponent();
                System.Windows.Application apprun = new System.Windows.Application();
                apprun.Run(n);

                break;
            }
        }

    }

Я не могу использовать строку -

    System.Windows.Application apprun = new System.Windows.Application();

В WPF_APP2 из-за AppDomain (нашел эту причину в Google). Попробуйте другую альтернативу, но не повезло.

Пожалуйста, взгляните и поделитесь своими знаниями. :)

ожидая ваших комментариев и ответа.

благодаря

  • 0
    Вы также пытались загрузить то же самое в новом домене приложения?
  • 0
    Да, я пытаюсь .. Я создал новый домен приложения .. но пытаюсь загрузить - Could not load file or assembly 'XXXX\\XXXX\\AutoUpdateTesting.dll' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047) .. и при попытке выполнить это говорит, что нет точки входа ..
Показать ещё 4 комментария
Теги:
dll
wpf

2 ответа

2
Лучший ответ

Загрузите окно WPF из приложения форм:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        ThreadProc();
        Application.Run(); // Keep on running!
    }

    private static void ThreadProc()
    {
        if (System.Windows.Application.Current == null)
            new System.Windows.Application();
        try
        {
            string assemblyName = string.Format("{0}\\AutoUpdateTesting.dll", new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName);
            System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
            {
                Window wnd = LoadAssembly(assemblyName, "OtherWindow");
                wnd.Show();
            }));
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(string.Format("Failed to load window from{0} - {1}", "OtherWindow", ex.Message));
            throw new Exception(String.Format("Failed to load window from{0} - {1}", "OtherWindow", ex.Message), ex);
        }
    }

    private static Window LoadAssembly(String assemblyName, String typeName)
    {
        try
        {
            Assembly assemblyInstance = Assembly.LoadFrom(assemblyName);
            foreach (Type t in assemblyInstance.GetTypes().Where(t => String.Equals(t.Name, typeName, StringComparison.OrdinalIgnoreCase)))
            {
                var wnd = assemblyInstance.CreateInstance(t.FullName) as Window;
                return wnd;
            }
            throw new Exception("Unable to load external window");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(string.Format("Failed to load window from{0}{1}", assemblyName, ex.Message));
            throw new Exception(string.Format("Failed to load external window{0}", assemblyName), ex);
        }
    }
}

Это делает трюк для форм! Помните, что вам нужно добавить ссылки на базовые сборки WPF (PresentationCore, WindowBase+++)

WPF загружает внешнее окно (читайте ваше сообщение неправильно, поэтому здесь у вас есть wpf и wpf)

public partial class App : Application
{
    App()
    {
        Startup += App_Startup;
    }

    void App_Startup(object sender, StartupEventArgs e)
    {
        try
        {
            string assemblyName = string.Format("{0}\\AutoUpdateTesting.dll", new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName);
            Window wnd = LoadAssembly(assemblyName, "OtherWindow");
            wnd.Show();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(string.Format("Failed to load window from{0} - {1}", "OtherWindow", ex.Message));
            throw new Exception(String.Format("Failed to load window from{0} - {1}", "OtherWindow", ex.Message), ex);

        }
    }

    private Window LoadAssembly(String assemblyName, String typeName)
    {
        try
        {
            Assembly assemblyInstance = Assembly.LoadFrom(assemblyName);
            foreach (Type t in assemblyInstance.GetTypes().Where(t => String.Equals(t.Name, typeName, StringComparison.OrdinalIgnoreCase)))
            {
                var wnd = assemblyInstance.CreateInstance(t.FullName) as Window;
                return wnd;
            }
            throw new Exception("Unable to load external window");
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(string.Format("Failed to load window from{0}{1}", assemblyName, ex.Message));
            throw new Exception(string.Format("Failed to load external window{0}", assemblyName), ex);
        }
    }
}

Надеюсь, поможет!

ура

Stian

  • 1
    Спасибо чувак.. !! очень ценю .. :) Я хотел бы спросить еще одну вещь .. пожалуйста ..! it worked as I want.. perfect.. only thing when I open parent form and then it creates the instance of WPF inside dll and show it as window, perfect..!! can you please let me know how to dispose the parent wpf form after starting the wpf from dll
  • 0
    @DeepakSharma NP! :) Стоит просто вызвать wnd.Close (); Возможно, вам придется удалить ссылки на него, если вы храните его где-то (не в области стека), вы должны удалить ссылку, чтобы убедиться, что она получает мусор. Это с учетом того, что я вас правильно понимаю, а вы просто хотите закрыть окно? Если вы хотите выйти из приложения, вы можете вызвать Application.Exit (), чтобы закрыть приложение форм.
Показать ещё 2 комментария
0

Не ответ, а предложение:

Я бы поменял:

foreach (Type type in dll.GetExportedTypes())
{                
    if (type.Name.Equals("MainWindow"))
    {                   
        dynamic n = null;
        n = Activator.CreateInstance(type);
        n.InitializeComponent();
        System.Windows.Application apprun = new System.Windows.Application();
        apprun.Run(n);

        break;
    }
}

с:

// replacing the loop, brackets and break with:
var main_win = dll.GetExportedTypes().Where(t => t.Name.Equalts("MaindWindow");

dynamic n = null;
n = Activator.CreateInstance(type);
n.InitializeComponent();
System.Windows.Application apprun = new System.Windows.Application();
apprun.Run(n);

Пусть linq беспокоится об этом и сделает ваш код более удобным для чтения и обслуживания.

  • 0
    хе-хе .. хороший .. но здесь я ищу ответ, а не рефрейминг кода .. ну, я достаточно хорош в linq, просто чтобы сделать нестабильным для каждого, кто не знает linq ..
  • 0
    Вот почему я начал с: «Не ответ, а предложение» :). Это также делает ваш код более читабельным. Кроме того, есть вероятность, что, поскольку это не тривиальная вещь, любой человек, который может дать вам правильный ответ, будет знать достаточно linq, чтобы прочитать предложение .Where :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню