WPF Cefsharp instance/object reference in class not working - c#

I am spending too much time trying to solve this issue: i am trying to create a Core, because the project is already confusing me and it is not that big. The Core is a Class outside the main Thread. On the main Thread i named the Browser, browser :
<cefSharp:ChromiumWebBrowser x:Name="browser" x:FieldModifier="public" />
In the class i call it like this:
public class Core : MainWindow
{
public void winstenVerlies()
{
var currentdirectory = "https://www.google.nl";
this.browser.Address = currentdirectory;
}
}
I have tried numerous ways, this is the way i like it but they all give me the same message:
"object reference is not set on an instance of an object."
Any help is appreciated.

Problem solved. i researched it for weeks now, from what i can see is the problem is the root, when i use this or the object/function name when calling it, it does not get passed the root of the class, instead of the root of the project. here is how you bypass it.
pass the object trough the class.
public void winstenVerlies(ChromiumWebBrowser b)
{
var currentdirectory = "https://www.google.nl";
b.Address = currentdirectory;
}
then call it like so.
Core Menu = new Core();
Menu.winstenVerlies(browser);
Now i try'd this befor, it gave me error messages the last time, i did not trace the source of the problems.
All i know is it working now, and i am happy.
Have a nice day.

Related

WebView2 AddHostObjectToScript in UWP crashes

I'm trying to pass a C# object to a WebView2 using AddHostObjectToScript. After not succeeding to retrieve the object from the webview, I've used the debugger and found out that the AddHostObjectToScript call is never completing.
Here is the full code snippet:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Example
{
public string Prop { get; set; } = "example";
}
namespace Example_UWP
{
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
InitializeAsync();
}
public async Task InitializeAsync()
{
await ExampleView.EnsureCoreWebView2Async();
ExampleView.Source = new Uri("http://localhost:3000");
ExampleView.CoreWebView2.OpenDevToolsWindow();
ExampleView.CoreWebView2.AddHostObjectToScript("example", new Example());
}
}
}
The example object is as a result not available in chrome.webview.hostObjects or chrome.webview.hostObjects.sync. The function throws the following error:
The group or resource is not in the correct state to perform the requested operation.
I've tried different alternatives without success, such as:
Keeping a reference to the Example instance in an attribute inside Example_UWP to avoid potential GC
Adding the host object before and after each of the previous steps within InitializeAsync
Wait for the event NavigationCompleted to add the host object.
Wait for 5 seconds before adding the host object.
I'm using Microsoft.Web.WebView2 version 1.0.1264.42
In order to interact with your third-party lib, you need to add a very specific C++ project, Windows Runtime Component (C++/WinRT), to your solution that must be called WinRTAdapter.
Next, you must install a lib to your C++ project from NuGet called Microsoft.Web.WebView2:
After this is done, you must your third-party lib as a reference.
Next, go to your C++ project properties go to Common Properties and choose WebView2:
Here you have to do four changes:
Set Use WebView2 WinRT APIs to No.
Set Use the wv2winrt tool to Yes.
Set Use Javascript case to Yes.
Edit Include filters and add the following ones:
Windows.System.UserProfile
Windows.Globalization.Language
CallJSInterface
CallJSInterface is the name of my third-party's namespace.
You click on OK and build your C++ lib.
After you have built your C++ lib (WinRTAdapter), you must add it to your main project as a reference.
Now, we need to do some changes to be able to invoke the functions from our third-party lib. The first one is to register it. We do it in the same LoadLocalPage() function from before or on NavigationCompleted:
var namespacesName = "CallJSInterface";
var dispatchAdapter = new WinRTAdapter.DispatchAdapter();
core_wv2.AddHostObjectToScript(namespacesName, dispatchAdapter.WrapNamedObject(namespacesName, dispatchAdapter));
Where CallJSInterface is your namespace. After this, you need to register your function in your JS like this:
var callJS;
if (chrome && chrome.webview) {
chrome.webview.hostObjects.options.defaultSyncProxy = true;
chrome.webview.hostObjects.options.forceAsyncMethodMatches = [/Async$/];
chrome.webview.hostObjects.options.ignoreMemberNotFoundError = true;
window.CallJSInterface = chrome.webview.hostObjects.sync.CallJSInterface;
callJS = new CallJSInterface.CallJSCSharp();
}
Where CallJSInterface is one more time your namespace. Now, you can invoke JS like this (the async() is mandatory):
callJS.async().KeepScreenOn()
If you need more details, I have a full tutorial on my website:
https://supernovaic.blogspot.com/2022/10/from-webview-to-webview2-in-uwp.html

Unable to load one or more of the requested types - but not the normal error

Okay, so this is a really bizarre one that has been bugging me. It will be hard to explain so please bear with me!
I am using autofac to register some components by scanning references.
public static void RegisterHandlersKeyedByEnum(this ContainerBuilder builder, Assembly[] assembliesToScan, Type typeToRegister)
{
var handlers = assembliesToScan.SelectMany(a => a.GetTypes()).Where(t => t.GetInterfaces().Contains(typeToRegister));
foreach (var handler in handlers)
{
var handlesAttributes = handler.GetCustomAttributes(typeof(HandlesEnumOf), true).Cast<HandlesEnumOf>();
foreach (var handlesAttribute in handlesAttributes)
{
if (handlesAttribute != null)
{
builder.RegisterType(handler).AsImplementedInterfaces().Keyed(handlesAttribute.Value, typeToRegister);
}
}
}
}
With assemblesToScanBeing:
var assembliesToScan = AppDomain.CurrentDomain.GetAssemblies();
When I run the web app, I get the following error:
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
I know what the error is, and have fixed it many times. However if I just refresh the page after ~10-15 seconds, the error no longer appears and the web app is okay to use from then on.
When I looked into this further and inspected LoaderExceptions, the following type was failing to load "Viper.ViewModels.Users.ADUserViewModel". This is where it get's weird. That file does NOT exist, anywhere. Not by searching for files, not even by searching for text. I found out it was a class that was created on a completely separate branch that was never actually merged into master (using GIT).
Now to make it even more weird, if I add in the class ADUserViewModel to Viper.ViewModels/Users folder and even leave the class completely empty. The project runs without any issues/errors whatsoever.
I mean, I could leave the empty class there, it's not doing any harm. But it will really bug me that A) It's unnecessary and B) I don't actually know why this is happening.
Any ideas would be greatly appreciated and put my mind at rest! I'm not sure what code can be posted to help explain this better, but more than happy to provide some if needed.

The name 'AutomationId' does not exist in the current context

I have assembly with UI automation tests (White).
I've introduced a class with all Autination Id's to be reused in this assembly:
public static class AutomationId
{
public static class Toolbar
{
public const string MyControl = "MyControlId";
}
}
And now i'm trying to use it in my test class (the same assembly):
var control = mainWindow.Get<Button>(AutomationId.Toolbar.MyControl);
This code can be compiled locally. But on TeamCity I'm getting a such error:
The name 'AutomationId' does not exist in the current context
It's a C# 6 feature. Similar problem: The name 'nameof' does not exist in the current context
I encountered this problem just now, which lead me here. My research indicates that you need to update Teamcity:
http://dave.ninja/2015/08/06/upgrading-teamcity-to-support-visual-studio-2015/
We still have to do this, as well. The post above shows a lot of solutions to issues that they encountered while upgrading. Didn't seem a too painful process.

Deleted class still works - VS 2012

I wanted to implement a simple activation function to my C# application. It was something like this:
class Activation
{
public Activation()
{
Some code...
}
public void SomeFunction()
{
Some code...
string s = NumberOfDaysToExpire();
}
}
The complete code is not a problem. The class sets some values to the Windows registry. I decided to launch the instance of this class in the main form's constructor and it worked fine.
The problem appeared when I decided to exclude this class from the project. The code shouldn't work but it still works !!! There is no declaration of this class in the whole project - so why does it still work ? I think this is a Visual Studio 2012 problem. Please help me.
Regards,
Mariusz

Is it possible to use Gephi compiled with IKVM in a website?

I'm currently trying to load and use the Gephi Toolkit from within a .Net 4 C# website.
I have a version of the toolkit jar file compiled against the IKVM virtual machine, which works as expected from a command line application using the following code:
var controller = (ProjectController)Lookup.getDefault().lookup(typeof(ProjectController));
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
The three instances are correctly instantiated in a form similar to org.gephi.project.impl.ProjectControllerImpl#8ddb93.
If however I run the exact same code, with the exact same using statements & references, the very first line loading the ProjectController instance returns null.
I have tried a couple of solutions
Firstly, I have tried ignoring the Lookup.getDefault().lookup(type) call, instead trying to create my own instances:
var controller = new ProjectControllerImpl();
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
This fails at the line controller.newProject();, I think because internally (using reflector) the same Lookup.getDefault().lookup(type) is used in a constructor, returns null and then throws an exception.
Secondly, from here: Lookup in Jython (and Gephi) I have tried to set the %CLASSPATH% to the location of both the toolkit JAR and DLL files.
Is there a reason why the Lookup.getDefault().lookup(type) would not work in a web environment? I'm not a Java developer, so I am a bit out of my depth with the Java side of this.
I would have thought it possible to create all of the instances myself, but haven't been able to find a way to do so.
I also cannot find a way of seeing why the ProjectController load returned null. No exception is thrown, and unless I'm being very dumb, there doesn't appear to be a method to see the result of the attempted load.
Update - Answer
Based on the answer from Jeroen Frijters, I resolved the issue like this:
public class Global : System.Web.HttpApplication
{
public Global()
{
var assembly = Assembly.LoadFrom(Path.Combine(root, "gephi-toolkit.dll"));
var acl = new AssemblyClassLoader(assembly);
java.lang.Thread.currentThread().setContextClassLoader(new MySystemClassLoader(acl));
}
}
internal class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{ }
}
The code ikvm.runtime.Startup.addBootClassPathAssemby() didn't seem to work for me, but from the provided link, I was able to find a solution that seems to work in all instances.
This is a Java class loader issue. In a command line app your main executable functions as the system class loader and knows how to load assembly dependencies, but in a web process there is no main executable so that system class loader doesn't know how to load anything useful.
One of the solutions is to call ikvm.runtime.Startup.addBootClassPathAssemby() to add the relevant assemblies to the boot class loader.
For more on IKVM class loading issues see http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader

Categories