WPF-App Embedd WPF window/control from other AppDomain - c#

I have an assembly which generates a Form (it is a client-software). I can build an app getting and starting (Show) that form without any problem. But I cannot start that Form twice because the assembly does not provide a clean capsuled solution. Every second start it would crash because several things will not initialize successful a second time. Unfortunately that assembly cannot be modified.
Now I have put that in a seperate AppDomain to be able to unload that assembly. This works fine and the hosting application can now start that Form multiple times.
Now the problem is: I have a WPF-app which should not show that assembly's Form, it should contain it in one of its own windows. The WinForms Form of the assembly is already in a WindowsFormHost and WPF-Window (with AssemblyAppDomain). But I cannot assign the WPF-Window as Content of one of the main WPF-app-windows. It is in the AssemblyAppDomain AppDomain (and object space is not shared with that).
As far as I searched up to now it should be possible to establish a connection between two WPF windows in different AppDomains because that is kind of the way System.AddIn works. Should work with a Pipeline, Contract and FrameworkElementAdapter. I am somewhat stuck and any more specific hints will be appreciated!

Have you checked the docs about WPF addins? Also check out this example.

Related

WebView2: Multiple instances of same application need to launch the same browser control

Problem
I recently replaced a System.Windows.Forms.WebBrowser-based control with one that relies on Microsoft.Web.WebView2.WinForms.WebView2 instead. This has been working well, except that my users want to have 2 instances of their application running at once, with both instances occasionally having that WebView2 form open at the same time. When they try this, one of the two instances fails to load the WebView2 control until the other one is closed.
Learned / attempted so far:
I've found WebView2 to be extremely finicky, so I've looked into alternatives like CefSharp, but haven't wanted to dedicate time to implementing them until I know they can solve the problem. So far as I can tell, CefSharp and WebView2 do very similar things as far as launching a Chromium-based browser, rendering to a WinForms control.
This blog post (read: advertisement) for paid alternative DotNetBrowser indicates that
You can initialize and use several Chromium engines simultaneously with different configurations [in DotNetBrowser], which is not possible in CefSharp.
I'm wondering if this same limitation applies to WebView2, and is the cause of my users' inability to have 2 instances of that same form loaded at once.
Context
I'm supporting an ancient desktop CRM that's set to be retired in favor of a modern alternative, but in the mean time, the old standard needs to integrate with new processes we're bringing in. One of those new processes is a web page from an external service that our call center users enter data into, then expect the CRM to pull entered data out of the web page.
The part of their process I did not know about is the 2-instance bit from above: they're used to being able to copy-and-paste from one embedded browser window to the other.
#Poul Bak in the comment on the question had it right: providing settings that differ per-instance of the application fixed the problem.
The setting I changed per-instance was the path of the user data folder: I was able to pass different values for the userDataFolder argument of the CoreWebView2Environment.CreateAsync method, branching based on a variable that holds different values between the instances that my users are running.

designer doesn't recognise usercotrols and classes

I had a User Control start doing weird things with its events; it didn't call the load and layout events at all. I looked at the designer code and everything seemed fine. tried recreating the events in the properties windows, and still nothing.
as I didn't have this problem with other user controls i decided to delete it and make a new one with the same name. then it all went haywire - the designer of the main window suddenly stopped recognizing all the user controls and classes i've built for the project.
the design window just shows the same error repeating once for each user control or class:
Could not find type 'Project Name.Class/User Control'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built using settings for your current platform or Any CPU.
I tried restarting the PC, rebuilding all, cleaning solution, deleting the user control that caused the kerfuffle, recreating it, and changing solution to x64 and x86.
edit: it's a windows form application.
how can i get it to work again?
It just randomly started working again. I literally haven't touched it since. but it's solved, I guess...

WPF ImageProcessor slow first time use

In my WPF application i need to make thumbs from photo the user add to the program. To do this i use the ImageProcessor package which works perfect for me.
Bu i have one small problem the first use in an application session always takes 5 a 10 seconds to complete every next thumb making in the same session only takes milliseconds.
It looks like the DLL is only loaded on first use.
Is there a way to make this faster?
I've tried replacing ImageProcessor with ImageResizer and also tried loading ImageProccesor on application startup both didn't work.
I talked to the owner.
It appear to be the plugin search routine which was checking all referenced assemblies. My project uses many DevExpress components which gives me a few dozen assemblies in the project folder.
The owner has made exceptions in the search routine.
Issue on GitHub

Issue with the window focus in WinRT

I've got an issue with the focus management in WinRT. The issue is specific for the application startup. Let me share the example of it:
If during the startup I change the focus (for instance I can start selecting some text in a browser), the runtime will decide that it doesn't need to show the application. The application is being started in a 'hidden mode'. It means that I do not see the UI, but I still can find it in process explorer.
So what I need here is to make the application be active in all possible cases. I tried to use several native functions such as ShowWindow, SetActiveWindow, SetForegroundWindow, but without any success.
I also noticed that any WinRT app is being started under WWAHOST.exe and mainwindowhandle is 0. The app shows up if I use 'Switch to' option in Process Explorer context menu.
WinRT applications are sandboxed and have very little control on the way the OS handles them, and almost no way to affect the behavior of other applications running on the same host. What I would suggest then is for you to design your application in such a way that it shows some UI as early as possible, then asynchronously you can load any other resources that your application may need.

Windows Form as child window of an unmanaged app

I am looking for a way to embed Windows Forms applications written in C# in a C++ windows application. The native application main window is subdivided into several panes. The C# app is supposed to appear within one of those panes, i.e. the root window of the C# component (the outermost form) must be a child window of the main application.
Can this be done? If so, how?
Some additional context: To my knowledge, there are two ways to go about this. First, host the CLR in the native app by using the .net hosting APIs (ICLRRuntimeHost, etc.). Second, host the CLR by putting the windows form in an ActiveX control.
Regarding the first approach, I have managed to get the CLR started up and to load a C# assembly (thanks largely to Mattias Högström). Where I am hitting a road block is that I see no way how to tell the component I am running in the CLR that it needs to be a child of a window passed in from the C++ side.
I have also experimented with the second method (using ActiveX and thanks to Daniel Yanovsky). It almost, but only almost, works for my purposes. I can let arbitrary Windows Forms components run in a child pane of the native app. BUT they always run on the main thread of the main app. This means they use the windows message loop of the main app. MSDN says this will not work reliably since the standard Windows message loops don't meet the requirements of Windows Forms (I wanted to post the link to MSDN here but have already used up my new-user-two-link-allotment).
The exceptions to the message loop issue are, according to MSDN, Internet Explorer and MFC apps. The native app I am using as a host is definitely not Internet Explorer. Also, it uses the windows API as wrapped by wxWidgets so MFC is not (or at least not a welcome) option.
The solutions Microsoft proposes involve letting the C# components run in their own message loops on their own threads. This, at least as far as I can tell, necessarily leads back to the first approach mentioned above. So I am back to the question of getting a Windows Form to work under a passed-in parent window.
Again, I am interested in any input that clarifies the child window issue, independent of the approaches I have mentioned here. But in light of the context I could reduce the general question to two specific questions (and I would need an answer to only one of them):
Given a Windows Form hosted in an ActiveX control, how can I allow the form to run in its own message loop on its own thread?
or
Given a Windows Form running in a CLR hosted by a native app, how can I make the form be a child window of a window in the native app?
yes, it can be done. We did the same thing years ago. This is our approach: .NET control also has native window handle, we get these handles through C++/CLI and pass them to Win32, and add these handles as the children of native windows. So the .NET controls run on the main thread of the main app, the problematic part is the message loop, as you have mentioned in your question. We need route the message between the nation and .NET windows if needed. As I remembered, we fixed a lot of bugs related to this, and still there were some mysterious problem we didn't figure out.
There's anothe way: using WPF interop. http://msdn.microsoft.com/en-us/library/ms742522.aspx . According to MS, this should fix the message problems, but we didn't try this approach. You can just use Win32 to host WPF, then use WPF to host Winform.
So for your last 2 questions:
You can't. Only one message loop.
Use handle. This article talks about the handle of Windows Forms: http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx

Categories