加载并运行WPF DLL到另一个WPF exe

时间:2014-08-30 06:23:55

标签: c# wpf dll

我的主要问题是我在标题中所说的。

WPF_APP1 - >在排除App.xaml之后我创建了这个wpf项目的dll WPF_APP2 - >正常的WPF exe。需要运行上面的WPF_APP1 dll并使用反射打开WPF_APP1 MainWindow表单。

我为什么要说反思是 - WPF_APP2 首先获取最新的 WPF_APP1.dll 然后打开,这样就无法添加dll的引用。必须只使用反射。

当我在cmd项目中使用上面的dll时没关系。它打开CMD窗口,然后以窗口形式启动 WPF_APP1 MainWindow

但是现在我需要在 WPF_APP2 中打开不在cmd中的窗口。

请帮帮我。

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;
            }
        }

    }

我不能使用line -

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

在WPF_APP2中因为AppDomain(在google上找到了这个原因)。尝试其他选择,但没有运气。

请查看并分享您的知识。 :)

等待你的评论并回复。

由于

2 个答案:

答案 0 :(得分:3)

从表单应用程序加载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 :(得分: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担心它,让您的代码更易于阅读和维护。