Closed ray007 closed 9 years ago
Did you set up your own project using the CefSharp.Wpf or CefSharp.WinForms Nuget with your project set to either x86
or x64
as covered in the FAQ point 8? That's the recommended approach as it takes care of copying not only CefSharp - but also CEF binaries etc. to your development bin/
folder.
I suspect you are missing some CEF related files. Compare your bin/
folder to the one in e.g. CefSharp.MinimalExample
. Lastly there is also some trouble-shooting wiki pages...
@jornh This type of issue seems to be one of our most frequent, once this is resolved perhaps we need to look at some better documentation?
@amaitland yep agree. I'm thinking maybe a less word heavy (but longer) README.md with a tutorial style with code snippets in and frequent "more here on this topic" exit.
Though this particular issue is not exactly a beginners problem but a converted CefSharp 1 user who already got off the ground - so probably more a "troubleshooting binaries" location entry. Well enough hi-jacking of this issue lets get back to your issue at hand @ray007 :smile:
@jornh yes, all projects in the solution are marked for x86
. The content of the bin
folder also seems to be fine, the "small" program, which is just a window wrapping the web-view works fine.
But we have a second program, which show one or more of the views in tabs. It does so by using the DLLs and other resources straight from the bin
directory (or installation directory when not in debug mode) of the "small" program. And here I've run into the problem with starting the render process.
Hope I've described my problem clearly enough.
@ray007 Both your app and the BrowserSubProcess
need access to libcef.dll
and it's related files.
Can you install the nuget
package into both projects to start with? Then work backwards from there.
@amaitland I don't really have control over the second program. The plan was to provide a DLL which does all the work required for the view so the second program doesn't have to care about the details. All of which worked fine until to upgrade to CefSharp3...
I've tried to change the current directory to the one containing the DLL and CefSharp.BrowserSubprocess.exe before calling Cef.Initialize(), but it didn't change anything.
I'll try to talk to the developer of the second program to get his help, but he's sitting in another country...
Are they separate executables or is one a library being referenced by the other?
I still don't quite have a picture of how your app hangs together (missing the fine detail).
Anyways, I'm sure once you resolve the dependency issue things will be fine.
@ray007 is the second program in the same directory with the CEF files (libcef.dll
, etc.), or is it in another directory? A screenshot or text-tree of the directory structure would be helpful.
If the second program is in another directory, does it work if you manually copy the CEF files into the directory before running the program?
There are 2 executables, one is just a thin wrapper around the DLL providing the view and can be found in the same directory as libcef.dll
.
The second program is installed in a different location and just loads the DLL provided in the directory of the first program:
C:\Program Files (x86)\OurCompany\
- Program1
- Program2
Pogram1 contains all cef-resources, Program2 just tries to access them via Program1.dll.
You can specify the BrowserSubprocessPath
in the settings. You may still have problems as basically CEF
is unable to resolve it's dependencies.
https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/CefExample.cs#L29
@amaitland I did specify the full path for BrowserSubprocessPath
, but unfortunately that's not enough. Same with changing the current directory, though I'm not sure that's not changed again by Program2 later...
@ray007 Did manually copying the files resolve the problem?
You could potentially add the directory to your path e.g.
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Process) + ";C:\Program Files (x86)\OurCompany\Program1";
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);
@amaitland Unfortunately neither copying the resources to the Program2 directory nor adding the Program1 directory to the Path
solved the problem.
But I'll check again the copying to make sure I didn't miss a file.
Maybe see what Process Monitor
has to say about what's happening at a low level?
https://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
I've now looked at what's happening with Process Monitor
:
It seems the full path for BrowserSubprocessPath
in the browser settings is ignored, the program is looking for Cefsharp.BrowserSubprocess.exe
in all directories in the path.
It seems neither changing the current directory nor modifying the Path
environment variable helps here.
Copying Cefsharp.BrowserSubprocess.*
to the directory of Program2 seems to at least start 1 process with --type=gpu-process
, but it of course fails looking for other DLLs later on.
Btw: should I be worried about Cef.IsInitialized
already being true before I call Cef.Initialize()
?
Btw: should I be worried about Cef.IsInitialized already being true before I call Cef.Initialize()?
Settings are only initialized once, so it's likely causing your problems. Cef.Initialize()
should happen before you create an instance of the browser.
https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Core/Cef.h#L152
Ah, I think we're getting closer to finding the problem.
While I only have one place in my code where I call Cef.Initialize()
and checking there Cef.IsInitialized
is already true, I've just found that Cef.Initialize()
is also called from the contructor ChromiumWebBrowser()
. Since the ChromiumWebBrowser is instantiated from XAML, Cef.Initialize()
gets called from there before I do with my own settings.
Do you plan do make this work or do I need to remove the <cefSharp:ChromiumWebBrowser...>
tag from XAML? Or just add an earlier call to Initialize()
with my parameters, I'll keep trying...
Making sure to call Cef.Initialize()
earlier seemed to help a bit, at least the messages in the debug.log
file have changed:
[0129/152115:VERBOSE1:pref_proxy_config_tracker_impl.cc(148)] 17BAB960: set chrome proxy config service to 17BAB690
[0129/152115:VERBOSE1:pref_proxy_config_tracker_impl.cc(277)] 17BAB960: Done pushing proxy to UpdateProxyConfig
[0129/152115:VERBOSE1:child_thread.cc(239)] Mojo is disabled on child
Still no working web view in Program2...
After re-reading all the comments, I think a better description of this issue is:
"How do I run my program .exe
from a different directory to where the CefSharp files (libcef.dll
, etc.) are?"
Is there anything to indicate that CEF supports this scenario of having its library files in a different directory to the exe? If it isn't, there is not much CefSharp can do.
Maybe someone else knows if this is meant to work or not, but I personally think that given the trouble that you can have even while the files are in the same directory, we should not support this scenario.
I think the easiest solution is to copy the CefSharp files to the directory of Program2.
Maybe someone else knows if this is meant to work or not, but I personally think that given the trouble that you can have even while the files are in the same directory, we should not support this scenario.
I've tried in the past and never succeeded in getting things working properly :frowning:
That's bad. While Program1 here is a standalone program, most of its functionality is exported as DLL and used in Program2 as Addin if found. Which also enables updating the Program1 part without redeploying Program2. All of which worked fine with CefSharp1.
Off to some more debugging then...
There are quite a few downsides to interfacing with unmanaged code, lack of control over how dependencies are loaded is one.
I'd probably embed the cef libs in the DLL making for one rather large self contained module. Then on load unpack the required parts into the bin directory, #483 may have a useful link.
Stay with CefSharp 1 if it better suites your requirements.
Unfortunately staying with CefSharp1 also isn't really an option. Our program loads an XML file from the net and is starting to crash with really big xml files...
What I don't understand is there nowhere being an error visible, when things clearly do go wrong somewhere. I assume the render process should be started by the CefSharp.BrowserSubprocess when a ChomiumWebBrowser
is instantiated? Is there a logfile for the BrowserSubprocess somewhere?
My coworker tried to use my view and CefSharp without the use of the plugin infrastructure and told me things failed then too. I'd be grateful for any other hints on how to find this problem...
debug.log
is the only output that Cef
produces.
Without a sample that reproduces the problem I don't think there is much more we can do.
(I use CefSharp
in a dll that's used by a couple of projects and everything works fine with copying the files into the bin
directory, so I'm quite confident that what your doing is possible).
Info update:
What I've found is that the IsBrowserInitialized
property never goes to true
for the ChromiumWebBrowser
in Program2 and the IsBrowserInitializedChanged
event is also not fired.
Any ideas to that one?
The source is the best documentation. Start at https://github.com/cefsharp/CefSharp/blob/master/CefSharp.WinForms/ChromiumWebBrowser.cs#L171, make sure that's firing and step into from there.
Found it: When starting up there aren't any dimension set on my ViewControl which contains the CromiumWebBrowser. While the browser component in CefSharp1 did initialize itself without valid dimensions on the control, the new one from CefSharp3 doesn't. I can work with that, but I think the old behavior was better.
I can work with that, but I think the old behavior was better.
Moot point I believe, CEF
now requires dimensions to initialize properly.
Re. https://github.com/cefsharp/CefSharp/issues/767#issuecomment-71579485
@jornh This type of issue seems to be one of our most frequent, once this is resolved perhaps we need to look at some better documentation?
So I guess this ended up in another quite in-frequent place? Not so FAQ-able after all /me thinks
Still :smile: for you @ray007 having found the needle in the haystack.
So I guess this ended up in another quite in-frequent place? Not so FAQ-able after all /me thinks
True. It's probably worth changing the title? Just incase someone else has a similar problem?
I think a more accurate title is deserved.
I also think it would be useful to add a new issue label like "cef1-to-cef3-upgrade-problem". I recall some other cef1 upgrade issues, and it would good for future upgraders to have a list of issues to check against. What do you reckon?
What do you reckon?
Excellent idea!
Hmm, if it's CEF where the behavior changed, maybe this should be reported upstream?
I could be totally mistaken but I think you'll find that for performance reasons when the size is zero it deliberately stops rendering (saves resources).
It's best to init the browser when you wish for it to render content. (Previously you did have to init in the form/control constructor, this is no longer the case).
Happy if you wish to update the documentation, e.g Add an item to the FAQ.
I've recently converted our project to use CefSharp3 instead of the old CefSharp1. First tests looked promising, but while the "small" standalone program has no problems, integration into another larger program failed so far. Looking at the Taskmanager I'm missing a
CefSharp.BrowserSubprocess.exe --type=render...
anddebug.log
gets a new line like[0126/172817:ERROR:child_process_launcher.cc(344)] Failed to launch child process
The one difference I'm aware of is the second program being launched from a different location. Since I've configured CefSettings to include the full path to the Browser Subprocess executable, that shouldn't matter. But it doesn't change the fact that the call to
Cef.Initialize(settings)
fails. No idea whyCef.IsInitialized
is already true before i try that call the first time.Any hints what's going wrong here or how I could find out?