My main issue is as I stated in title.
WPF_APP1 --> I created dll of this wpf project after excluding App.xaml
WPF_APP2 --> Normal WPF exe. which needs to run the above WPF_APP1 dll and open the WPF_APP1 MainWindow form using reflection.
Why I am saying for reflection is -
WPF_APP2 first get the latest WPF_APP1.dll then open so can not add the reference of dll. have to use the Reflection only.
When I use the above dll in cmd project its okay. it open the CMD window then launch the WPF_APP1 MainWindow as Window form.
But Now I need to open this window form not in cmd, in WPF_APP2.
Please help me out.
CMD project use the below code to open the 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;
}
}
}
I can not use line -
System.Windows.Application apprun = new System.Windows.Application();
In WPF_APP2 because of AppDomain(found this reason on google). Try other alternative but no luck.
Please have a look and share your knowledge. :)
waiting for your comments and reply.
Thanks
Load WPF window from forms application:
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);
}
}
}
That does the trick for forms! Remember that you need to add references to the base WPF assemblies(PresentationCore, WindowBase+++)
WPF loading external window (Read your post wrong, so here you have wpf to wpf as well)
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);
}
}
}
Hope it helps!
Cheers
Stian
Not an answer, but a suggestion:
I would change :
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;
}
}
with:
// 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);
Let linq worry about it, and make your code easier to read and maintain.