"Cef can only be initialized once" when registered js object - chromium-embedded

I'm using CefSharp.WinForm 51.0.0.
When I added code registring js object after Cef.Initialize(settings),
The exception occurs at runtime on Cef.Initialize(settings).
System.Exception was unhandled
HResult=-2146233088
Message=Cef can only be initialized once. Use Cef.IsInitialized to guard against this exception.
Source=CefSharp.Core
StackTrace:
위치: CefSharp.Cef.Initialize(CefSettings cefSettings, Boolean shutdownOnProcessExit, Boolean performDependencyCheck)
위치: CefSharp.Cef.Initialize(CefSettings cefSettings)
위치: PcAppCef_WinForm.AppForm.InitializeChromium() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\AppForm.cs:줄 82
위치: PcAppCef_WinForm.AppForm..ctor() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\AppForm.cs:줄 53
위치: PcAppCef_WinForm.AppViewport..ctor() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\AppViewport.cs:줄 15
위치: PcAppCef_WinForm.AppForm.InitializeChromium() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\AppForm.cs:줄 90
위치: PcAppCef_WinForm.AppForm..ctor() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\AppForm.cs:줄 53
위치: PcAppCef_WinForm.Program.Main() 파일 d:\VisualStuidoRepo\StocktalkPC\PcAppCef_WinForm\Program.cs:줄 19
However, I just called .RegisterJsObject() method after Cef.Initialize
and when I removed(or commented) my code chromeBrowser.RegisterJsObject then works very well.
I don't understand why error occurs at Initialize method not RegisterJsObject.
This is my code.
public void InitializeChromium()
{
System.Console.WriteLine("*** Initializing Chromium");
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
chromeBrowser = new ChromiumWebBrowser(WebAppUrl);
chromeBrowser.DownloadHandler = new FileDownloadHandler();
chromeBrowser.MenuHandler = new ContextMenuHandler();
//chromeBrowser.RequestHandler = new AppRequestHandler();
// I want to a add js object but when I add this code, an error occurs on Cef.Initialize() as the blackquote above.
chromeBrowser.RegisterJsObject("AppViewport", new AppViewport());
this.Controls.Add(chromeBrowser);
chromeBrowser.Dock = DockStyle.Fill;
}

Can you please check initial before. I think it help you:
public void InitializeChromium()
{
System.Console.WriteLine("*** Initializing Chromium");
if (!Cef.IsInitialized) // Check before init
{
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
}
chromeBrowser = new ChromiumWebBrowser(WebAppUrl);
chromeBrowser.DownloadHandler = new FileDownloadHandler();
chromeBrowser.MenuHandler = new ContextMenuHandler();
//chromeBrowser.RequestHandler = new AppRequestHandler();
// I want to a add js object but when I add this code, an error occurs on Cef.Initialize() as the blackquote above.
chromeBrowser.RegisterJsObject("AppViewport", new AppViewport());
this.Controls.Add(chromeBrowser);
chromeBrowser.Dock = DockStyle.Fill;
}

Related

OutOfMemoryError using MapContainer

After my splash screen, my mainform contains a MapContainer where I show a several points. It works well on Simulator. On device however, after some seconds, the phone just hangs and the app crashes. Does it have anything to do with the way I add multiple points? I have shown the code below. I have also added my LogCat stackTrace.
public void addMarkers(MapContainer mc)
{
Vector v= new Vector();
try
{
Style s = new Style();
s.setFgColor(0xff0000);
s.setBgTransparency(0);
FontImage markerImg = FontImage.createMaterial(FontImage.MATERIAL_PLACE, s, 7);
EncodedImage ei = EncodedImage.createFromImage(markerImg, false);
List lx = (List) Storage.getInstance().readObject("CASES");
Coord c = null;
for(Object m: lx)
{
Map p= (Map) m;
c = new Coord(Double.parseDouble(p.get("latitude").toString()), Double.parseDouble(p.get("longitude").toString()));
v.add(c);
mc.addMarker(ei, c, "Hi marker", "Optional long description", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
ToastBar.showMessage("You clicked the marker", FontImage.MATERIAL_PLACE);
}
});
}
mc.fitBounds(BoundingBox.create(v));
}catch(Exception er){er.printStackTrace();}
}
And my LogCat strackTrace below
01-29 00:06:24.407 21924-22089/com.jajitech.mobile.creporter E/AndroidRuntime: FATAL EXCEPTION: androidmapsapi-Snapshot
Process: com.jajitech.mobile.creporter, PID: 21924
java.lang.OutOfMemoryError: Failed to allocate a 1831692 byte allocation with 48112 free bytes and 46KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:975)
at android.graphics.Bitmap.createBitmap(Bitmap.java:946)
at android.graphics.Bitmap.createBitmap(Bitmap.java:913)
at com.google.maps.api.android.lib6.impl.a.b(:com.google.android.gms.dynamite_mapsdynamite#14366045#14.3.66 (040304-213742215):9)
at com.google.maps.api.android.lib6.impl.bk.run(:com.google.android.gms.dynamite_mapsdynamite#14366045#14.3.66 (040304-213742215):4)
at java.lang.Thread.run(Thread.java:818)

Crash on iOS when downloading and inserting in Database

I have a problem with my application on iOS only (iPad 9.7" 11.3.1), it works perfectly on the simulator and on Android device.
When the app is launched for the first time, the user has to log in. This works fine. After that, the menu form is launched and a Dialog is shown on onShowCompleted():
if (!Preferences.get("download", false)) {
dialog = new Dialog("...");
dialog.setLayout(new BorderLayout());
SpanLabel label = new SpanLabel("...");
dialog.addComponent(BorderLayout.CENTER, label);
dialog.show(Display.getInstance().getDisplayHeight() / 5, ..., ..., ...);
}
In the constructor, a method that downloads informations is launched :
if (!Preferences.get("download", false)) {
dlReferentiel();
}
The method :
public void dlReferentiel() {
source = DataSource.getInstance();
// I also tried with invokeAndBlock() but doesn't work
/*
Display.getInstance().invokeAndBlock(() -> requestS());
Display.getInstance().invokeAndBlock(() -> requestB());
Display.getInstance().invokeAndBlock(() -> requestZ());
Display.getInstance().invokeAndBlock(() -> requestA());
*/
requestS();
requestB();
requestZ();
requestA();
}
The requestX methods get informations from server with ConnectionRequest :
(Exemple with requestA() which needs to be the last because it disposes the dialog, it is the only one that calls the UI)
public void requestA() {
ConnectionRequest connectionRequest = new ConnectionRequest() {
ArrayList<A> as = new ArrayList<>();
#Override
protected void readResponse(InputStream in) throws IOException {
JSONParser json = new JSONParser();
Reader reader = new InputStreamReader(in, "UTF-8");
Map<String, Object> data = json.parseJSON(reader);
for (String s : data.keySet()) {
as.add(new A(s, (String) data.get(s)));
}
}
#Override
protected void postResponse() {
source.createAllA(as); // makes insertions with Transaction
ToastBar.showErrorMessage("Référentiel téléchargé", 10);
dialog.dispose();
Preferences.set("download", true);
}
};
connectionRequest.setUrl(URL_A);
connectionRequest.setPost(true);
NetworkManager.getInstance().addToQueue(connectionRequest);
}
I was able to see some logs with a Mac. Each time, the app crashes after the Dialog is shown and few insertions are made. The same error message is output :
HW kbd: Failed to set (null) as keyboard focus
Unable to get short BSD proc info for 513: No such process
Unable to get proc info for 513: Undefined error: 0
I search for informations about this issue but nothing interesting with Codename One.
I don't know what to do with this error, I tried some things like using invokeAndBlock() or changing build hints like ios.keyboardOpen (just because there is "keyboard" in it) but nothing worked.
Thanks for the help.

WPF using and accessing an ObjectContext from the BackgroundWorker thread

I have a code like the following (I have stripped some code for readability)
private void RicercaArticoloStripped(object sender, DoWorkEventArgs e)
{
try
{
using (var context = new ControlloSchedeLocalEntities())
{
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text);
if (prodotti.Count() > 0)
{
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
{
textBlockDescrizioneArticolo.Text = prodotti.FirstOrDefault().WADESC;
}));
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error:\n\n" + ex.Message + "\r\nStack: " + ex.ToString());
}
}
private void textBoxCodiceArticolo_KeyUpStripped(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(RicercaArticoloStripped);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RicercaArticoloWorkerCompleted);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
object[] parameters = new object[] { textBoxCodiceArticolo.Text, textBlockDescrizioneArticolo.Text };
worker.RunWorkerAsync(parameters);
}
}
So, as for my understanding of BackgroundWorker, when I instantiate the:
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text);
I am doing it FROM the working thread, not the UI thread.
But I get an exception on the line immediately below, when I try to access the value:
if (prodotti.Count() > 0)
I get the (in)famous error:
"The calling thread cannot access this object because a different thread owns it"
Why?
As you already said you must use Dispatcher.BeginInvoke/Invoke to perform operations from the control's owner thread or you will get "The calling thread cannot access this object because a different thread owns it" exception. Thats why you got this exception;
And here is why you got this exception on the line below (when prodotti.Count() was called):
When you create prodotti variable it's just a IEnumerable<T> object. So he actually calculates only when you call for prodotti.Count() method and thats why you got exception on this line.
IEnumerable actually is generator, that means that he will produce new set of objects every time he used.
To test this you can calculate prodotti as shown bellow:
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text).ToList();
In this case you will get exception immediately because .ToList() forces all calculations.
Check this article for generators and enumerators: http://www.codeproject.com/Articles/155462/IEnumerable-Lazy-and-Dangerous
Updated:
really, when you use IEnumerable with reference types you can get the same objects as previously. Read this answer for more: https://stackoverflow.com/a/14361094/1467309
The property Text of TextBox gets the value of the DependencyProperty Text, this can only be done from the UI-thread. You are accessing textBoxCodiceArticolo.Text from your Worker thread.

VB.NET Webbrowser System.UnauthorizedAccessException in Loop

I've had this code working for at least a year and today it threw an exception that i haven't been able to figure out why its happening. Its a Forms.WebBrowser that hits a generic site first and then a secondary site.
'first site
wbr.ScriptErrorsSuppressed = False
wbr.Navigate("http://www.bing.com/?rb=0")
Do
Application.DoEvents()
Loop Until wbr.ReadyState = WebBrowserReadyState.Complete
'second site
wbr.ScriptErrorsSuppressed = True
Dim start As DateTime = DateTime.Now
Dim loopTimeout As TimeSpan = TimeSpan.FromSeconds(timeout)
wbr.Navigate("http://www.FlightAware.com")
Do
Application.DoEvents()
'loop timer
If DateTime.Now.Subtract(start) > loopTimeout Then
'stop browser
wbr.Stop()
'throw exception
Dim eExpTme As Exception = New Exception("A loop timeout occurred in the web request.")
Throw eExpTme
End If
Loop Until wbr.ReadyState = WebBrowserReadyState.Complete
The error happens on the second site access and it shows that it errors on the very last line with
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Windows.Forms.UnsafeNativeMethods.IHTMLLocation.GetHref()
at System.Windows.Forms.WebBrowser.get_Document()
at System.Windows.Forms.WebBrowser.get_ReadyState()
I just don't get why its errorring on the second site and not the first and what exactly that error message means. I've looked at some help forums but nothing concrete that i can use to troubleshoot.
AGP
The web site has a frame on ad.doubleclick.net, by default cross-domain frame access is disabled for the internet zone, so you get a security exception.
Catch the exception and move on. There isn't much you need to care about in the frame, doubleclick is an ad service.
You can implement IInternetSecurityManager and let IE to believe ad.doubleclick.net and FlightAware.com are the same web site, but this can cause security problem if you extend the trust to arbitrary web sites.
Here is a little hack in C# which you can convert in Vb.net:
public class CrossFrameIE
{
// Returns null in case of failure.
public static IHTMLDocument2 GetDocumentFromWindow(IHTMLWindow2 htmlWindow)
{
if (htmlWindow == null)
{
return null;
}
// First try the usual way to get the document.
try
{
IHTMLDocument2 doc = htmlWindow.document;
return doc;
}
catch (COMException comEx)
{
// I think COMException won't be ever fired but just to be sure ...
if (comEx.ErrorCode != E_ACCESSDENIED)
{
return null;
}
}
catch (System.UnauthorizedAccessException)
{
}
catch
{
// Any other error.
return null;
}
// At this point the error was E_ACCESSDENIED because the frame contains a document from another domain.
// IE tries to prevent a cross frame scripting security issue.
try
{
// Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider.
IServiceProvider sp = (IServiceProvider)htmlWindow;
// Use IServiceProvider.QueryService to get IWebBrowser2 object.
Object brws = null;
sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws);
// Get the document from IWebBrowser2.
IWebBrowser2 browser = (IWebBrowser2)(brws);
return (IHTMLDocument2)browser.Document;
}
catch
{
}
return null;
}
private const int E_ACCESSDENIED = unchecked((int)0x80070005L);
private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
}
// This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface!
[ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
}

Silverlight cant find page error

I have started a a new project (to refactor some code), and just can't work out why I keep getting "Can't find page /Index" error. The code works fine until I use an add method (on any collection type). So I don't think there is a problem with the navigation, but an issue with my IndexViewModel class.
public partial class Index : Page
{
private IndexViewModel _vm;
public Index()
{
InitializeComponent();
_vm = new IndexViewModel();
...
public class IndexViewModel //: ViewModelBase
{
public SortableCollectionView Rows {get;set;}
public IndexViewModel()
{
// generate some dummy data
Random rand = new Random();
for (int i = 0; i < 200; i++)
{
Row row = new Row();
row["stuff"] = s_names[rand.Next(s_names.Length)];
**Rows.Add(row);**
}
}
Looks like you never new up your Rows variable.
Rows = new SortableCollectionView();
To get to the actual error you can use this trick copied from my answer on another question:
To see what the issue is you need to make one change to your MainPage.xaml.cs:
// If an error occurs during navigation, show an error window
private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
Exception ex = e.Exception;
while (ex.InnerException != null)
{
ex = ex.InnerException;
}
e.Handled = true;
ChildWindow errorWin = new ErrorWindow(ex);
errorWin.Show();
}
Once you've made that change when you start the application you should see the exception instead of the page where the exception occurred.
You need
Rows = new SortableCollectionView();
somewhere in your code.

Resources