diff --git a/CefSharp.BrowserSubprocess/CefRenderProcess.h b/CefSharp.BrowserSubprocess/CefRenderProcess.h index 28f906243a..83d4daa896 100644 --- a/CefSharp.BrowserSubprocess/CefRenderProcess.h +++ b/CefSharp.BrowserSubprocess/CefRenderProcess.h @@ -2,11 +2,14 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#pragma once + #include "include/cef_app.h" +#include "SubprocessCefApp.h" int ExecuteCefRenderProcess(HINSTANCE hInstance) { CefMainArgs main_args(hInstance); - CefRefPtr app; - return CefExecuteProcess(main_args, app); + CefRefPtr subprocessCefAppPtr = SubprocessCefApp::GetInstance(); + return CefExecuteProcess(main_args, (CefRefPtr) subprocessCefAppPtr); } diff --git a/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj index 5f80b73f32..c91153df55 100644 --- a/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj +++ b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj @@ -91,6 +91,7 @@ + @@ -105,6 +106,8 @@ + + diff --git a/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj.filters b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj.filters index 854b5bb01c..5e757f570f 100644 --- a/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj.filters +++ b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.vcxproj.filters @@ -24,10 +24,19 @@ Header Files + + Header Files + + + Header Files + Source Files + + Source Files + \ No newline at end of file diff --git a/CefSharp.BrowserSubprocess/JavascriptProxy.h b/CefSharp.BrowserSubprocess/JavascriptProxy.h index 644c558390..d5bde0b6c7 100644 --- a/CefSharp.BrowserSubprocess/JavascriptProxy.h +++ b/CefSharp.BrowserSubprocess/JavascriptProxy.h @@ -13,6 +13,8 @@ namespace CefSharp { private ref class JavascriptProxy : IJavascriptProxy { + SubprocessCefApp* _subprocessCefApp; + public: // TODO: Don't hardwire the address like this, since it makes it impossible to run multiple apps that use // CefSharp simultaneously... @@ -20,8 +22,25 @@ namespace CefSharp literal String^ ServiceName = "JavaScriptProxy"; static String^ Address = BaseAddress + "/" + ServiceName; - virtual Object^ EvaluateScript(String^ script, double timeout) + JavascriptProxy() + { + _subprocessCefApp = SubprocessCefApp::GetInstance(); + } + + virtual Object^ EvaluateScript(int browserId, int frameId, String^ script, double timeout) { + auto browser = _subprocessCefApp->GetBrowserById(browserId); + auto frame = browser->GetFrame(frameId); + auto v8Context = frame->GetV8Context(); + + if (v8Context.get() && v8Context->Enter()) + { + CefRefPtr result; + CefRefPtr exception; + + v8Context->Eval("10 + 20", result, exception); + } + return "gurka"; } }; diff --git a/CefSharp.BrowserSubprocess/JavascriptProxyService.h b/CefSharp.BrowserSubprocess/JavascriptProxyService.h index c7e7748d8a..af2cb4cb78 100644 --- a/CefSharp.BrowserSubprocess/JavascriptProxyService.h +++ b/CefSharp.BrowserSubprocess/JavascriptProxyService.h @@ -10,22 +10,26 @@ using namespace CefSharp::Internals::JavascriptBinding; using namespace CefSharp::BrowserSubprocess; using namespace System; using namespace System::ServiceModel; +using namespace System::ServiceModel::Description; using namespace System::Threading; -static void ThreadEntryPoint(); +static void JavascriptProxyServiceEntryPoint(); +static void AddDebugBehavior(ServiceHost^ host); void CreateJavascriptProxyServiceHost() { - auto thread = gcnew Thread(gcnew ThreadStart(ThreadEntryPoint)); + auto thread = gcnew Thread(gcnew ThreadStart(JavascriptProxyServiceEntryPoint)); thread->Start(); } -void ThreadEntryPoint() +void JavascriptProxyServiceEntryPoint() { auto uris = gcnew array(1); uris[0] = gcnew Uri(JavascriptProxy::BaseAddress); auto host = gcnew ServiceHost(JavascriptProxy::typeid, uris); + AddDebugBehavior(host); + host->AddServiceEndpoint( IJavascriptProxy::typeid, gcnew NetNamedPipeBinding(), @@ -34,3 +38,19 @@ void ThreadEntryPoint() host->Open(); } + +void AddDebugBehavior(ServiceHost^ host) +{ + auto serviceDebugBehavior = host->Description->Behaviors->Find(); + + if (serviceDebugBehavior == nullptr) + { + serviceDebugBehavior = gcnew ServiceDebugBehavior(); + serviceDebugBehavior->IncludeExceptionDetailInFaults = true; + host->Description->Behaviors->Add(serviceDebugBehavior); + } + else + { + serviceDebugBehavior->IncludeExceptionDetailInFaults = true; + } +} diff --git a/CefSharp.BrowserSubprocess/Program.cpp b/CefSharp.BrowserSubprocess/Program.cpp index dbfb42a6b8..fad923c2ca 100644 --- a/CefSharp.BrowserSubprocess/Program.cpp +++ b/CefSharp.BrowserSubprocess/Program.cpp @@ -2,6 +2,7 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. +#include "Program.h" #include "CefRenderProcess.h" #include "JavascriptProxyService.h" diff --git a/CefSharp.BrowserSubprocess/Program.h b/CefSharp.BrowserSubprocess/Program.h new file mode 100644 index 0000000000..96374f6731 --- /dev/null +++ b/CefSharp.BrowserSubprocess/Program.h @@ -0,0 +1,5 @@ +// Copyright © 2013 The CefSharp Project. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +#define DECL __declspec(dllexport) diff --git a/CefSharp.BrowserSubprocess/SubprocessCefApp.cpp b/CefSharp.BrowserSubprocess/SubprocessCefApp.cpp new file mode 100644 index 0000000000..4015d6d019 --- /dev/null +++ b/CefSharp.BrowserSubprocess/SubprocessCefApp.cpp @@ -0,0 +1,10 @@ +// Copyright © 2013 The CefSharp Project. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +#pragma once + +#include "Program.h" +#include "SubprocessCefApp.h" + +SubprocessCefApp* SubprocessCefApp::_instance = nullptr; diff --git a/CefSharp.BrowserSubprocess/SubprocessCefApp.h b/CefSharp.BrowserSubprocess/SubprocessCefApp.h new file mode 100644 index 0000000000..b938ee79fc --- /dev/null +++ b/CefSharp.BrowserSubprocess/SubprocessCefApp.h @@ -0,0 +1,59 @@ +// Copyright © 2013 The CefSharp Project. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +#pragma once + +#include +#include "include/cef_app.h" + +private class SubprocessCefApp : public CefApp, + public CefRenderProcessHandler +{ + static SubprocessCefApp* _instance; + std::list> _browsers; + +public: + + static SubprocessCefApp* GetInstance() + { + if (_instance == nullptr) + { + _instance = new SubprocessCefApp(); + } + + return _instance; + } + + virtual DECL CefRefPtr GetRenderProcessHandler() OVERRIDE + { + return this; + } + + virtual DECL void OnBrowserCreated(CefRefPtr browser) OVERRIDE + { + _browsers.push_back(browser); + } + + virtual DECL void OnBrowserDestroyed(CefRefPtr browser) OVERRIDE + { + _browsers.remove(browser); + } + + virtual DECL CefRefPtr GetBrowserById(int browser_id) + { + // FIXME: Doesn't seem to work. Our list contains a browser w/ ID == 0, and the parameter we get is 1. How come? + // We could experiment with OnContextCreated() to see if it would work better... + for (auto browser : _browsers) + { + if (browser->GetIdentifier() == browser_id) + { + return browser; + } + } + + return nullptr; + } + + IMPLEMENT_REFCOUNTING(SubprocessCefApp); +};