From e8cf336bf3f2871c400cd01ee090fa42df97adf8 Mon Sep 17 00:00:00 2001 From: amaitland Date: Sat, 18 Jul 2020 13:30:54 +1000 Subject: [PATCH] Net Core - Support for compiling with .Net Core 3.1 - Make Wpf/WinForms/OffScreen projects target AnyCPU Only the VC++ projects are platform specific now. - Remove BrowserSubProcess project reference Not needed as we now have a standalone exe - Add OffScreen example - Add WPF Example project - Fix some compile errors for main solution - Add BrowserSubProcess executable - JavascriptObjectRepository remove isAsync param Rather than throw exception remove the option - BrowserSubprocess Exclude the WCF specific code from the netCore project - Add some ifdef/ifndef to exclude the WCF specific implementation - Move WCF implementation into separate namespace --- .../BindObjectAsyncHandler.h | 4 + .../BrowserSubprocessExecutable.h | 1 - .../CefAppUnmanagedWrapper.cpp | 8 ++ .../CefBrowserWrapper.h | 5 +- ...arp.BrowserSubprocess.Core.netcore.vcxproj | 16 +--- .../JavascriptMethodHandler.h | 2 + .../JavascriptMethodWrapper.h | 3 +- .../JavascriptPropertyWrapper.h | 4 +- .../JavascriptRootObjectWrapper.cpp | 4 +- .../JavascriptRootObjectWrapper.h | 18 ++++ .../WcfBrowserSubprocessExecutable.h | 2 - .../WcfEnabledSubProcess.cpp | 2 - .../WcfEnabledSubProcess.h | 2 - .../CefSharp.BrowserSubprocess.netcore.csproj | 49 ++++++++++ CefSharp.BrowserSubprocess/Program.netcore.cs | 37 ++++++++ .../Properties/launchSettings.json | 8 ++ CefSharp.Core/ManagedCefBrowserAdapter.h | 1 + CefSharp.Example/CefExample.cs | 21 ++--- .../CefSharp.Example.netcore.csproj | 1 - .../CefSharp.OffScreen.Example.netcore.csproj | 46 +++++++++ CefSharp.OffScreen.Example/Program.cs | 8 +- .../CefSharp.OffScreen.netcore.csproj | 1 - .../BrowserTabUserControl.cs | 10 +- .../CefSharp.WinForms.Example.netcore.csproj | 90 +++++++++--------- CefSharp.WinForms.Example/Program.cs | 12 --- .../CefSharp.WinForms.netcore.csproj | 1 - .../CefSharp.Wpf.Example.netcore.csproj | 48 ++++++++++ .../JavascriptCallbackMainWindow.xaml.cs | 5 + .../Views/BrowserTabView.xaml.cs | 20 ++++ CefSharp.Wpf/CefSharp.Wpf.netcore.csproj | 1 - CefSharp/CefSharp.csproj | 14 +-- CefSharp/CefSharp.netcore.csproj | 3 + CefSharp/IJavascriptObjectRepository.cs | 6 ++ .../Internals/JavascriptObjectRepository.cs | 17 ++-- .../{ => Wcf}/BrowserProcessResponse.cs | 2 +- .../{ => Wcf}/BrowserProcessService.cs | 4 +- .../{ => Wcf}/BrowserProcessServiceHost.cs | 4 +- .../Internals/{ => Wcf}/IBrowserProcess.cs | 13 +-- .../JavascriptCallbackEndpointBehavior.cs | 4 +- .../{ => Wcf}/JavascriptCallbackSurrogate.cs | 4 +- .../WcfExtensions.cs} | 6 +- CefSharp3.netcore.sln | 94 ++++++++++++------- 42 files changed, 420 insertions(+), 181 deletions(-) create mode 100644 CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.netcore.csproj create mode 100644 CefSharp.BrowserSubprocess/Program.netcore.cs create mode 100644 CefSharp.BrowserSubprocess/Properties/launchSettings.json create mode 100644 CefSharp.OffScreen.Example/CefSharp.OffScreen.Example.netcore.csproj create mode 100644 CefSharp.Wpf.Example/CefSharp.Wpf.Example.netcore.csproj rename CefSharp/Internals/{ => Wcf}/BrowserProcessResponse.cs (96%) rename CefSharp/Internals/{ => Wcf}/BrowserProcessService.cs (97%) rename CefSharp/Internals/{ => Wcf}/BrowserProcessServiceHost.cs (98%) rename CefSharp/Internals/{ => Wcf}/IBrowserProcess.cs (87%) rename CefSharp/Internals/{ => Wcf}/JavascriptCallbackEndpointBehavior.cs (96%) rename CefSharp/Internals/{ => Wcf}/JavascriptCallbackSurrogate.cs (97%) rename CefSharp/Internals/{WCFExtensions.cs => Wcf/WcfExtensions.cs} (95%) diff --git a/CefSharp.BrowserSubprocess.Core/BindObjectAsyncHandler.h b/CefSharp.BrowserSubprocess.Core/BindObjectAsyncHandler.h index 91c0af2516..5cc1434d3e 100644 --- a/CefSharp.BrowserSubprocess.Core/BindObjectAsyncHandler.h +++ b/CefSharp.BrowserSubprocess.Core/BindObjectAsyncHandler.h @@ -147,7 +147,11 @@ namespace CefSharp JavascriptRootObjectWrapper^ rootObject; if (!rootObjectWrappers->TryGetValue(frame->GetIdentifier(), rootObject)) { +#ifdef NETCOREAPP + rootObject = gcnew JavascriptRootObjectWrapper(browser->GetIdentifier()); +#else rootObject = gcnew JavascriptRootObjectWrapper(browser->GetIdentifier(), _browserWrapper->BrowserProcess); +#endif rootObjectWrappers->TryAdd(frame->GetIdentifier(), rootObject); } diff --git a/CefSharp.BrowserSubprocess.Core/BrowserSubprocessExecutable.h b/CefSharp.BrowserSubprocess.Core/BrowserSubprocessExecutable.h index 5812dc20d8..874184c9c4 100644 --- a/CefSharp.BrowserSubprocess.Core/BrowserSubprocessExecutable.h +++ b/CefSharp.BrowserSubprocess.Core/BrowserSubprocessExecutable.h @@ -7,7 +7,6 @@ #include "Stdafx.h" #include "SubProcess.h" -#include "WcfEnabledSubProcess.h" using namespace System; using namespace CefSharp::Internals; diff --git a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp index 7fd5d8784d..26982d2569 100644 --- a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp +++ b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp @@ -292,7 +292,11 @@ namespace CefSharp JavascriptRootObjectWrapper^ rootObject; if (!rootObjectWrappers->TryGetValue(frameId, rootObject)) { +#ifdef NETCOREAPP + rootObject = gcnew JavascriptRootObjectWrapper(browserId); +#else rootObject = gcnew JavascriptRootObjectWrapper(browserId, browserWrapper->BrowserProcess); +#endif rootObjectWrappers->TryAdd(frameId, rootObject); } @@ -394,7 +398,11 @@ namespace CefSharp //as without javascript there is no need for a context. if (rootObjectWrapper == nullptr) { +#ifdef NETCOREAPP + rootObjectWrapper = gcnew JavascriptRootObjectWrapper(browser->GetIdentifier()); +#else rootObjectWrapper = gcnew JavascriptRootObjectWrapper(browser->GetIdentifier(), browserWrapper->BrowserProcess); +#endif browserWrapper->JavascriptRootObjectWrappers->TryAdd(frameId, rootObjectWrapper); } diff --git a/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h b/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h index b0041e5376..9e90a601d9 100644 --- a/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h @@ -12,7 +12,9 @@ #include "JavascriptRootObjectWrapper.h" using namespace CefSharp::Internals::Async; +#ifndef NETCOREAPP using namespace System::ServiceModel; +#endif using namespace System::Threading; using namespace System::Threading::Tasks; @@ -65,9 +67,8 @@ namespace CefSharp #ifndef NETCOREAPP // This allows us to create the WCF proxies back to our parent process. property ChannelFactory^ ChannelFactory; -#endif - // The WCF proxy to the parent process. property IBrowserProcess^ BrowserProcess; +#endif }; } diff --git a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj index 52d820d947..cbdd9c87dc 100644 --- a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj +++ b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj @@ -169,6 +169,7 @@ + @@ -176,24 +177,16 @@ - - - - - - - - @@ -209,15 +202,10 @@ + - - - - - - Create diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptMethodHandler.h b/CefSharp.BrowserSubprocess.Core/JavascriptMethodHandler.h index c7202c4a4e..45935a5f35 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptMethodHandler.h +++ b/CefSharp.BrowserSubprocess.Core/JavascriptMethodHandler.h @@ -7,6 +7,8 @@ #include "include/cef_v8.h" #include "JavascriptCallbackRegistry.h" +using namespace CefSharp::Internals::Wcf; + namespace CefSharp { private class JavascriptMethodHandler : public CefV8Handler diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptMethodWrapper.h b/CefSharp.BrowserSubprocess.Core/JavascriptMethodWrapper.h index 296e493481..780684e7e1 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptMethodWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/JavascriptMethodWrapper.h @@ -10,6 +10,7 @@ #include "JavascriptMethodHandler.h" using namespace System::Runtime::Serialization; +using namespace CefSharp::Internals::Wcf; namespace CefSharp { @@ -44,4 +45,4 @@ namespace CefSharp void Bind(JavascriptMethod^ javascriptMethod, const CefRefPtr& v8Value); BrowserProcessResponse^ Execute(array^ parameters); }; -} \ No newline at end of file +} diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptPropertyWrapper.h b/CefSharp.BrowserSubprocess.Core/JavascriptPropertyWrapper.h index 4235a1a92d..a531ecfcda 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptPropertyWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/JavascriptPropertyWrapper.h @@ -8,6 +8,8 @@ #include "include/cef_v8.h" #include "JavascriptCallbackRegistry.h" +using namespace CefSharp::Internals::Wcf; + namespace CefSharp { private ref class JavascriptPropertyWrapper @@ -37,4 +39,4 @@ namespace CefSharp void Bind(JavascriptProperty^ javascriptProperty, const CefRefPtr& v8Value, JavascriptCallbackRegistry^ callbackRegistry); }; -} \ No newline at end of file +} diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.cpp b/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.cpp index c31e619ece..f82874c82b 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.cpp +++ b/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.cpp @@ -27,6 +27,7 @@ namespace CefSharp _wrappedAsyncObjects->Add(wrapperObject); } +#ifndef NETCOREAPP else { if (_browserProcess == nullptr) @@ -41,6 +42,7 @@ namespace CefSharp _wrappedObjects->Add(wrapperObject); } +#endif } } } @@ -66,4 +68,4 @@ namespace CefSharp } return result; } -} \ No newline at end of file +} diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.h b/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.h index fdc3fd6a9e..0a141de838 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/JavascriptRootObjectWrapper.h @@ -6,7 +6,9 @@ #include "include/cef_v8.h" #include "JavascriptCallbackRegistry.h" +#ifndef NETCOREAPP #include "JavascriptObjectWrapper.h" +#endif #include "Async/JavascriptAsyncObjectWrapper.h" using namespace System::Runtime::Serialization; @@ -14,6 +16,9 @@ using namespace System::Linq; using namespace System::Collections::Generic; using namespace CefSharp::Internals::Async; +#ifndef NETCOREAPP +using namespace CefSharp::Internals::Wcf; +#endif namespace CefSharp { @@ -28,10 +33,14 @@ namespace CefSharp //Is static so ids are unique to this process https://github.com/cefsharp/CefSharp/issues/2792 static int64 _lastCallback; +#ifndef NETCOREAPP initonly List^ _wrappedObjects; +#endif initonly List^ _wrappedAsyncObjects; initonly Dictionary^ _methodCallbacks; +#ifndef NETCOREAPP IBrowserProcess^ _browserProcess; +#endif // The entire set of possible JavaScript functions to // call directly into. JavascriptCallbackRegistry^ _callbackRegistry; @@ -45,10 +54,16 @@ namespace CefSharp } public: +#ifdef NETCOREAPP + JavascriptRootObjectWrapper(int browserId) +#else JavascriptRootObjectWrapper(int browserId, IBrowserProcess^ browserProcess) +#endif { +#ifndef NETCOREAPP _browserProcess = browserProcess; _wrappedObjects = gcnew List(); +#endif _wrappedAsyncObjects = gcnew List(); _callbackRegistry = gcnew JavascriptCallbackRegistry(browserId); _methodCallbacks = gcnew Dictionary(); @@ -62,12 +77,15 @@ namespace CefSharp _callbackRegistry = nullptr; } +#ifndef NETCOREAPP for each (JavascriptObjectWrapper^ var in _wrappedObjects) { delete var; } _wrappedObjects->Clear(); +#endif + for each (JavascriptAsyncObjectWrapper^ var in _wrappedAsyncObjects) { delete var; diff --git a/CefSharp.BrowserSubprocess.Core/WcfBrowserSubprocessExecutable.h b/CefSharp.BrowserSubprocess.Core/WcfBrowserSubprocessExecutable.h index 47a4044b77..761e5344f1 100644 --- a/CefSharp.BrowserSubprocess.Core/WcfBrowserSubprocessExecutable.h +++ b/CefSharp.BrowserSubprocess.Core/WcfBrowserSubprocessExecutable.h @@ -10,7 +10,6 @@ #include "WcfEnabledSubProcess.h" #include "BrowserSubprocessExecutable.h" -#ifndef NETCOREAPP using namespace System; using namespace CefSharp::Internals; @@ -45,4 +44,3 @@ namespace CefSharp }; } } -#endif diff --git a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp index aef716ac90..ced1f83c3b 100644 --- a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp +++ b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp @@ -7,7 +7,6 @@ #include "Stdafx.h" #include "WcfEnabledSubProcess.h" -#ifndef NETCOREAPP using namespace System::ServiceModel; namespace CefSharp @@ -102,4 +101,3 @@ namespace CefSharp } } } -#endif diff --git a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h index 7d58937d0a..ffd3ea46f7 100644 --- a/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h +++ b/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.h @@ -2,7 +2,6 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#ifndef NETCOREAPP #pragma once #include "Stdafx.h" @@ -37,4 +36,3 @@ namespace CefSharp }; } } -#endif diff --git a/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.netcore.csproj b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.netcore.csproj new file mode 100644 index 0000000000..f66fceabf6 --- /dev/null +++ b/CefSharp.BrowserSubprocess/CefSharp.BrowserSubprocess.netcore.csproj @@ -0,0 +1,49 @@ + + + + + obj.netcore\ + bin.netcore\ + + + + + + + WinExe + netcoreapp3.1 + CefSharp.BrowserSubprocess + CefSharp.BrowserSubprocess + $(BaseOutputPath)$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + false + true + ..\CefSharp.snk + MinimumRecommendedRules.ruleset + app.manifest + CefSharp.BrowserSubprocess.Program + + + + 2 + + + + + + + + + + + + + + + + + + + + + diff --git a/CefSharp.BrowserSubprocess/Program.netcore.cs b/CefSharp.BrowserSubprocess/Program.netcore.cs new file mode 100644 index 0000000000..e021a07258 --- /dev/null +++ b/CefSharp.BrowserSubprocess/Program.netcore.cs @@ -0,0 +1,37 @@ +// Copyright © 2020 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using System.Diagnostics; +using CefSharp.RenderProcess; + +namespace CefSharp.BrowserSubprocess +{ + /// + /// When implementing your own BrowserSubprocess + /// - For .Net Core use (No WCF Support) + /// - Include an app.manifest with the dpi/compatability sections, this is required (this project contains the relevant). + /// - If you are targeting x86/Win32 then you should set /LargeAddressAware (https://docs.microsoft.com/en-us/cpp/build/reference/largeaddressaware?view=vs-2017) + /// + public class Program + { + public static int Main(string[] args) + { + Debug.WriteLine("BrowserSubprocess starting up with command line: " + string.Join("\n", args)); + + SubProcess.EnableHighDPISupport(); + + //Add your own custom implementation of IRenderProcessHandler here + IRenderProcessHandler handler = null; + + //The BrowserSubprocessExecutable provides BrowserSubProcess functionality + //specific to CefSharp there is no WCF support used for the sync JSB feature. + var browserProcessExe = new BrowserSubprocessExecutable(); + var result = browserProcessExe.Main(args, handler); + + Debug.WriteLine("BrowserSubprocess shutting down."); + + return result; + } + } +} diff --git a/CefSharp.BrowserSubprocess/Properties/launchSettings.json b/CefSharp.BrowserSubprocess/Properties/launchSettings.json new file mode 100644 index 0000000000..cdf806c5be --- /dev/null +++ b/CefSharp.BrowserSubprocess/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "CefSharp.BrowserSubprocess.netcore": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/CefSharp.Core/ManagedCefBrowserAdapter.h b/CefSharp.Core/ManagedCefBrowserAdapter.h index c75d94698d..b5ceb4a85c 100644 --- a/CefSharp.Core/ManagedCefBrowserAdapter.h +++ b/CefSharp.Core/ManagedCefBrowserAdapter.h @@ -21,6 +21,7 @@ using namespace System::Diagnostics; #ifndef NETCOREAPP using namespace System::ServiceModel; +using namespace CefSharp::Internals::Wcf; #endif using namespace System::Threading; using namespace System::Threading::Tasks; diff --git a/CefSharp.Example/CefExample.cs b/CefSharp.Example/CefExample.cs index f2864f7427..1c415de682 100644 --- a/CefSharp.Example/CefExample.cs +++ b/CefSharp.Example/CefExample.cs @@ -159,18 +159,16 @@ public static void Init(CefSettingsBase settings, IBrowserProcessHandler browser //settings.LogSeverity = LogSeverity.Verbose; -#if !NETCOREAPP if (DebuggingSubProcess) { + +#if NETCOREAPP + settings.BrowserSubprocessPath = Path.GetFullPath("..\\..\\..\\..\\..\\CefSharp.BrowserSubprocess\\bin.netcore\\Debug\\netcoreapp3.1\\CefSharp.BrowserSubprocess.exe"); +#else var architecture = Environment.Is64BitProcess ? "x64" : "x86"; settings.BrowserSubprocessPath = Path.GetFullPath("..\\..\\..\\..\\CefSharp.BrowserSubprocess\\bin\\" + architecture + "\\Debug\\CefSharp.BrowserSubprocess.exe"); - } -#else - // We use our Applications exe as the BrowserSubProcess, multiple copies - // will be spawned. - var exePath = Process.GetCurrentProcess().MainModule.FileName; - settings.BrowserSubprocessPath = exePath; #endif + } settings.RegisterScheme(new CefCustomScheme { @@ -241,14 +239,7 @@ public static void Init(CefSettingsBase settings, IBrowserProcessHandler browser //see https://github.com/cefsharp/CefSharp/wiki/General-Usage#proxy-resolution //CefSharpSettings.Proxy = new ProxyOptions(ip: "127.0.0.1", port: "8080", username: "cefsharp", password: "123"); - bool performDependencyCheck = -#if !NETCOREAPP - !DebuggingSubProcess; -#else - // For .NET Core, don't perform a dependency check, to allow publishing single-file - // executables. - false; -#endif + bool performDependencyCheck = !DebuggingSubProcess; if (!Cef.Initialize(settings, performDependencyCheck: performDependencyCheck, browserProcessHandler: browserProcessHandler)) { diff --git a/CefSharp.Example/CefSharp.Example.netcore.csproj b/CefSharp.Example/CefSharp.Example.netcore.csproj index f93b5d8ea2..006c92d59b 100644 --- a/CefSharp.Example/CefSharp.Example.netcore.csproj +++ b/CefSharp.Example/CefSharp.Example.netcore.csproj @@ -16,7 +16,6 @@ true false AllRules.ruleset - x86;x64 diff --git a/CefSharp.OffScreen.Example/CefSharp.OffScreen.Example.netcore.csproj b/CefSharp.OffScreen.Example/CefSharp.OffScreen.Example.netcore.csproj new file mode 100644 index 0000000000..192d0c0c80 --- /dev/null +++ b/CefSharp.OffScreen.Example/CefSharp.OffScreen.Example.netcore.csproj @@ -0,0 +1,46 @@ + + + + + obj.netcore\ + bin.netcore\ + + + + + + Exe + netcoreapp3.1 + CefSharp.OffScreen.Example + CefSharp.OffScreen.Example + false + app.manifest + MinimumRecommendedRules.ruleset + x86;x64 + CefSharp.OffScreen.Example.Program + + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + + \ No newline at end of file diff --git a/CefSharp.OffScreen.Example/Program.cs b/CefSharp.OffScreen.Example/Program.cs index b44952f44d..8311176326 100644 --- a/CefSharp.OffScreen.Example/Program.cs +++ b/CefSharp.OffScreen.Example/Program.cs @@ -167,10 +167,14 @@ private static void DisplayBitmap(Task task) // Dispose it to avoid keeping the memory alive. Especially important in 32-bit applications. bitmap.Dispose(); - Console.WriteLine("Screenshot saved. Launching your default image viewer..."); + Console.WriteLine("Screenshot saved. Launching your default image viewer..."); // Tell Windows to launch the saved image. - Process.Start(screenshotPath); + Process.Start(new ProcessStartInfo(screenshotPath) + { + // UseShellExecute is false by default on .NET Core. + UseShellExecute = true + }); Console.WriteLine("Image viewer launched. Press any key to exit."); } diff --git a/CefSharp.OffScreen/CefSharp.OffScreen.netcore.csproj b/CefSharp.OffScreen/CefSharp.OffScreen.netcore.csproj index 0a06c224bf..93a87ccd8b 100644 --- a/CefSharp.OffScreen/CefSharp.OffScreen.netcore.csproj +++ b/CefSharp.OffScreen/CefSharp.OffScreen.netcore.csproj @@ -19,7 +19,6 @@ true ..\CefSharp.snk MinimumRecommendedRules.ruleset - x86;x64 diff --git a/CefSharp.WinForms.Example/BrowserTabUserControl.cs b/CefSharp.WinForms.Example/BrowserTabUserControl.cs index abe4e94aea..629b09da36 100644 --- a/CefSharp.WinForms.Example/BrowserTabUserControl.cs +++ b/CefSharp.WinForms.Example/BrowserTabUserControl.cs @@ -65,10 +65,12 @@ public BrowserTabUserControl(Action openNewTab, string url, bool m browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged; browser.LoadError += OnLoadError; -#if !NETCOREAPP +#if NETCOREAPP + browser.JavascriptObjectRepository.Register("boundAsync", new AsyncBoundObject(), options: BindingOptions.DefaultBinder); +#else browser.JavascriptObjectRepository.Register("bound", new BoundObject(), isAsync: false, options: BindingOptions.DefaultBinder); -#endif browser.JavascriptObjectRepository.Register("boundAsync", new AsyncBoundObject(), isAsync: true, options: BindingOptions.DefaultBinder); +#endif //If you call CefSharp.BindObjectAsync in javascript and pass in the name of an object which is not yet //bound, then ResolveObject will be called, you can then register it @@ -77,7 +79,11 @@ public BrowserTabUserControl(Action openNewTab, string url, bool m var repo = e.ObjectRepository; if (e.ObjectName == "boundAsync2") { +#if NETCOREAPP + repo.Register("boundAsync2", new AsyncBoundObject(), options: BindingOptions.DefaultBinder); +#else repo.Register("boundAsync2", new AsyncBoundObject(), isAsync: true, options: BindingOptions.DefaultBinder); +#endif } }; diff --git a/CefSharp.WinForms.Example/CefSharp.WinForms.Example.netcore.csproj b/CefSharp.WinForms.Example/CefSharp.WinForms.Example.netcore.csproj index 660c377db2..df170c1e13 100644 --- a/CefSharp.WinForms.Example/CefSharp.WinForms.Example.netcore.csproj +++ b/CefSharp.WinForms.Example/CefSharp.WinForms.Example.netcore.csproj @@ -1,53 +1,53 @@ - - - obj.netcore\ - bin.netcore\ - + + obj.netcore\ + bin.netcore\ + - + - - WinExe - netcoreapp3.1 - CefSharp.WinForms.Example - CefSharp.WinForms.Example - true - false - app.manifest - MinimumRecommendedRules.ruleset - x86;x64 - + + WinExe + netcoreapp3.1 + CefSharp.WinForms.Example + CefSharp.WinForms.Example + true + false + app.manifest + MinimumRecommendedRules.ruleset + x86;x64 + - - - - - - - + + + + + + - - - True - True - Resources.resx - - - - - PreserveNewest - - - - - - - - - - - + + + True + True + Resources.resx + + + + + PreserveNewest + + + + + + + + + + + + \ No newline at end of file diff --git a/CefSharp.WinForms.Example/Program.cs b/CefSharp.WinForms.Example/Program.cs index 284d30b15f..209cd82b06 100644 --- a/CefSharp.WinForms.Example/Program.cs +++ b/CefSharp.WinForms.Example/Program.cs @@ -50,18 +50,6 @@ public static int Main(string[] args) } else { -#if NETCOREAPP - //We are using our current exe as the BrowserSubProcess - //Multiple instances will be spawned to handle all the - //Chromium proceses, render, gpu, network, plugin, etc. - var subProcessExe = new CefSharp.BrowserSubprocess.BrowserSubprocessExecutable(); - var result = subProcessExe.Main(args); - if (result > 0) - { - return result; - } -#endif - #if DEBUG if (!System.Diagnostics.Debugger.IsAttached) { diff --git a/CefSharp.WinForms/CefSharp.WinForms.netcore.csproj b/CefSharp.WinForms/CefSharp.WinForms.netcore.csproj index a816a723ba..6e2e1a9fdd 100644 --- a/CefSharp.WinForms/CefSharp.WinForms.netcore.csproj +++ b/CefSharp.WinForms/CefSharp.WinForms.netcore.csproj @@ -19,7 +19,6 @@ true ..\CefSharp.snk MinimumRecommendedRules.ruleset - x86;x64 diff --git a/CefSharp.Wpf.Example/CefSharp.Wpf.Example.netcore.csproj b/CefSharp.Wpf.Example/CefSharp.Wpf.Example.netcore.csproj new file mode 100644 index 0000000000..e428e2eb6f --- /dev/null +++ b/CefSharp.Wpf.Example/CefSharp.Wpf.Example.netcore.csproj @@ -0,0 +1,48 @@ + + + + + obj.netcore\ + bin.netcore\ + + + + + + WinExe + netcoreapp3.1 + CefSharp.Wpf.Example + CefSharp.Wpf.Example + true + false + app.manifest + MinimumRecommendedRules.ruleset + x86;x64 + CefSharp.Wpf.Example.Program + + + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + + \ No newline at end of file diff --git a/CefSharp.Wpf.Example/JavascriptCallbackMainWindow.xaml.cs b/CefSharp.Wpf.Example/JavascriptCallbackMainWindow.xaml.cs index 25a4f3512e..7e243bbe29 100644 --- a/CefSharp.Wpf.Example/JavascriptCallbackMainWindow.xaml.cs +++ b/CefSharp.Wpf.Example/JavascriptCallbackMainWindow.xaml.cs @@ -19,8 +19,13 @@ public JavascriptCallbackMainWindow() boundObjectOne = new JavascriptCallbackBoundObject(BrowserOne); boundObjectTwo = new JavascriptCallbackBoundObject(BrowserTwo); +#if NETCOREAPP + BrowserOne.JavascriptObjectRepository.Register("boundObject", boundObjectOne); + BrowserTwo.JavascriptObjectRepository.Register("boundObject", boundObjectTwo); +#else BrowserOne.JavascriptObjectRepository.Register("boundObject", boundObjectOne, false); BrowserTwo.JavascriptObjectRepository.Register("boundObject", boundObjectTwo, false); +#endif } private void ExecuteCallbackImmediatelyClick(object sender, RoutedEventArgs e) diff --git a/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs b/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs index dc6d103826..049a5a64eb 100644 --- a/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs +++ b/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs @@ -50,7 +50,9 @@ public BrowserTabView() //To use the ResolveObject below and bind an object with isAsync:false we must set CefSharpSettings.WcfEnabled = true before //the browser is initialized. +#if !NETCOREAPP CefSharpSettings.WcfEnabled = true; +#endif //If you call CefSharp.BindObjectAsync in javascript and pass in the name of an object which is not yet //bound, then ResolveObject will be called, you can then register it @@ -61,6 +63,23 @@ public BrowserTabView() //When JavascriptObjectRepository.Settings.LegacyBindingEnabled = true //This event will be raised with ObjectName == Legacy so you can bind your //legacy objects +#if NETCOREAPP + if (e.ObjectName == "Legacy") + { + repo.Register("boundAsync", new AsyncBoundObject(), options: bindingOptions); + } + else + { + if (e.ObjectName == "boundAsync") + { + repo.Register("boundAsync", new AsyncBoundObject(), options: bindingOptions); + } + else if (e.ObjectName == "boundAsync2") + { + repo.Register("boundAsync2", new AsyncBoundObject(), options: bindingOptions); + } + } +#else if (e.ObjectName == "Legacy") { repo.Register("bound", new BoundObject(), isAsync: false, options: BindingOptions.DefaultBinder); @@ -81,6 +100,7 @@ public BrowserTabView() repo.Register("boundAsync2", new AsyncBoundObject(), isAsync: true, options: bindingOptions); } } +#endif }; browser.JavascriptObjectRepository.ObjectBoundInJavascript += (sender, e) => diff --git a/CefSharp.Wpf/CefSharp.Wpf.netcore.csproj b/CefSharp.Wpf/CefSharp.Wpf.netcore.csproj index 89422325b1..9a605a24ff 100644 --- a/CefSharp.Wpf/CefSharp.Wpf.netcore.csproj +++ b/CefSharp.Wpf/CefSharp.Wpf.netcore.csproj @@ -19,7 +19,6 @@ true ..\CefSharp.snk MinimumRecommendedRules.ruleset - x86;x64 diff --git a/CefSharp/CefSharp.csproj b/CefSharp/CefSharp.csproj index 15fe4bc2f2..b8056d0b89 100644 --- a/CefSharp/CefSharp.csproj +++ b/CefSharp/CefSharp.csproj @@ -283,8 +283,8 @@ - - + + @@ -292,15 +292,15 @@ - + - - - + + + @@ -310,7 +310,7 @@ - + diff --git a/CefSharp/CefSharp.netcore.csproj b/CefSharp/CefSharp.netcore.csproj index 9ba8ffae66..61c4669f06 100644 --- a/CefSharp/CefSharp.netcore.csproj +++ b/CefSharp/CefSharp.netcore.csproj @@ -22,8 +22,11 @@ + + + diff --git a/CefSharp/IJavascriptObjectRepository.cs b/CefSharp/IJavascriptObjectRepository.cs index c7b2f1b3f6..b8e9628c11 100644 --- a/CefSharp/IJavascriptObjectRepository.cs +++ b/CefSharp/IJavascriptObjectRepository.cs @@ -30,6 +30,7 @@ public interface IJavascriptObjectRepository : IDisposable /// /// object name /// the object that will be bound in javascript +#if !NETCOREAPP /// /// if true the object will be registered for async communication, /// only methods will be exposed and when called from javascript will return a Promise to be awaited. @@ -37,9 +38,14 @@ public interface IJavascriptObjectRepository : IDisposable /// If false then methods and properties will be registered, this method relies on a WCF service to communicate. /// If you are targeting .Net Core then you can only use isAsync = true as Microsoft has chosen not to support WCF. /// +#endif /// binding options, by default method/property names are camelCased, you can control this /// and other advanced options though this class. +#if NETCOREAPP + void Register(string name, object objectToBind, BindingOptions options = null); +#else void Register(string name, object objectToBind, bool isAsync, BindingOptions options = null); +#endif /// /// UnRegister all the currently bound objects from the repository. If you unregister an object that is currently /// bound in JavaScript then the method/property calls will fail. diff --git a/CefSharp/Internals/JavascriptObjectRepository.cs b/CefSharp/Internals/JavascriptObjectRepository.cs index b38fc115f9..5011c103d0 100644 --- a/CefSharp/Internals/JavascriptObjectRepository.cs +++ b/CefSharp/Internals/JavascriptObjectRepository.cs @@ -153,7 +153,11 @@ private JavascriptObject CreateJavascriptObject(bool rootObject, IJavascriptName return result; } +#if NETCOREAPP + public void Register(string name, object value, BindingOptions options) +#else public void Register(string name, object value, bool isAsync, BindingOptions options) +#endif { if (name == null) { @@ -165,9 +169,12 @@ public void Register(string name, object value, bool isAsync, BindingOptions opt throw new ArgumentNullException("value"); } -#if !NETCOREAPP + //Enable WCF if not already enabled - can only be done before the browser has been initliazed //if done after the subprocess won't be WCF enabled it we'll have to throw an exception +#if NETCOREAPP + var isAsync = true; +#else if (!IsBrowserInitialized && !isAsync) { CefSharpSettings.WcfEnabled = true; @@ -177,13 +184,7 @@ public void Register(string name, object value, bool isAsync, BindingOptions opt { throw new InvalidOperationException(@"To enable synchronous JS bindings set WcfEnabled true in CefSharpSettings before you create your ChromiumWebBrowser instances."); - } -#else - // WCF is not available on .NET Core. - if (!isAsync) - { - throw new NotSupportedException("Synchronous JS bindings are not supported."); - } + } #endif //Validation name is unique diff --git a/CefSharp/Internals/BrowserProcessResponse.cs b/CefSharp/Internals/Wcf/BrowserProcessResponse.cs similarity index 96% rename from CefSharp/Internals/BrowserProcessResponse.cs rename to CefSharp/Internals/Wcf/BrowserProcessResponse.cs index 00fc5dc9e3..bfba86c21c 100644 --- a/CefSharp/Internals/BrowserProcessResponse.cs +++ b/CefSharp/Internals/Wcf/BrowserProcessResponse.cs @@ -4,7 +4,7 @@ using System.Runtime.Serialization; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { [DataContract] [KnownType(typeof(bool[]))] diff --git a/CefSharp/Internals/BrowserProcessService.cs b/CefSharp/Internals/Wcf/BrowserProcessService.cs similarity index 97% rename from CefSharp/Internals/BrowserProcessService.cs rename to CefSharp/Internals/Wcf/BrowserProcessService.cs index 6b342949c0..b17cf2bf19 100644 --- a/CefSharp/Internals/BrowserProcessService.cs +++ b/CefSharp/Internals/Wcf/BrowserProcessService.cs @@ -2,10 +2,9 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#if !NETCOREAPP using System.ServiceModel; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)] internal class BrowserProcessService : IBrowserProcess @@ -49,4 +48,3 @@ public BrowserProcessResponse SetProperty(long objectId, string name, object val } } } -#endif diff --git a/CefSharp/Internals/BrowserProcessServiceHost.cs b/CefSharp/Internals/Wcf/BrowserProcessServiceHost.cs similarity index 98% rename from CefSharp/Internals/BrowserProcessServiceHost.cs rename to CefSharp/Internals/Wcf/BrowserProcessServiceHost.cs index 38b7e35c5a..bb5ba5c858 100644 --- a/CefSharp/Internals/BrowserProcessServiceHost.cs +++ b/CefSharp/Internals/Wcf/BrowserProcessServiceHost.cs @@ -2,14 +2,13 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#if !NETCOREAPP using System; using System.Net.Security; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { public class BrowserProcessServiceHost : ServiceHost { @@ -68,4 +67,3 @@ public static CustomBinding CreateBinding() } } } -#endif diff --git a/CefSharp/Internals/IBrowserProcess.cs b/CefSharp/Internals/Wcf/IBrowserProcess.cs similarity index 87% rename from CefSharp/Internals/IBrowserProcess.cs rename to CefSharp/Internals/Wcf/IBrowserProcess.cs index fed3a30bc8..e5aa8c19ab 100644 --- a/CefSharp/Internals/IBrowserProcess.cs +++ b/CefSharp/Internals/Wcf/IBrowserProcess.cs @@ -3,13 +3,10 @@ // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System.Collections.Generic; -#if !NETCOREAPP using System.ServiceModel; -#endif -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { -#if !NETCOREAPP [ServiceContract(SessionMode = SessionMode.Required)] [ServiceKnownType(typeof(object[]))] [ServiceKnownType(typeof(Dictionary))] @@ -17,22 +14,16 @@ namespace CefSharp.Internals [ServiceKnownType(typeof(JavascriptMethod))] [ServiceKnownType(typeof(JavascriptProperty))] [ServiceKnownType(typeof(JavascriptCallback))] -#endif + public interface IBrowserProcess { -#if !NETCOREAPP [OperationContract] -#endif BrowserProcessResponse CallMethod(long objectId, string name, object[] parameters); -#if !NETCOREAPP [OperationContract] -#endif BrowserProcessResponse GetProperty(long objectId, string name); -#if !NETCOREAPP [OperationContract] -#endif BrowserProcessResponse SetProperty(long objectId, string name, object value); } } diff --git a/CefSharp/Internals/JavascriptCallbackEndpointBehavior.cs b/CefSharp/Internals/Wcf/JavascriptCallbackEndpointBehavior.cs similarity index 96% rename from CefSharp/Internals/JavascriptCallbackEndpointBehavior.cs rename to CefSharp/Internals/Wcf/JavascriptCallbackEndpointBehavior.cs index 1c50a56efe..7456de79e6 100644 --- a/CefSharp/Internals/JavascriptCallbackEndpointBehavior.cs +++ b/CefSharp/Internals/Wcf/JavascriptCallbackEndpointBehavior.cs @@ -2,14 +2,13 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#if !NETCOREAPP using System.Collections.Generic; using System.Linq; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { internal sealed class JavascriptCallbackEndpointBehavior : IEndpointBehavior { @@ -47,4 +46,3 @@ public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRu } } } -#endif diff --git a/CefSharp/Internals/JavascriptCallbackSurrogate.cs b/CefSharp/Internals/Wcf/JavascriptCallbackSurrogate.cs similarity index 97% rename from CefSharp/Internals/JavascriptCallbackSurrogate.cs rename to CefSharp/Internals/Wcf/JavascriptCallbackSurrogate.cs index 7a7c8a6432..b5ec239395 100644 --- a/CefSharp/Internals/JavascriptCallbackSurrogate.cs +++ b/CefSharp/Internals/Wcf/JavascriptCallbackSurrogate.cs @@ -2,14 +2,13 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#if !NETCOREAPP using System; using System.CodeDom; using System.Collections.ObjectModel; using System.Reflection; using System.Runtime.Serialization; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { internal sealed class JavascriptCallbackSurrogate : IDataContractSurrogate { @@ -71,4 +70,3 @@ public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclarati } } } -#endif diff --git a/CefSharp/Internals/WCFExtensions.cs b/CefSharp/Internals/Wcf/WcfExtensions.cs similarity index 95% rename from CefSharp/Internals/WCFExtensions.cs rename to CefSharp/Internals/Wcf/WcfExtensions.cs index addeccc330..8eebcf95ce 100644 --- a/CefSharp/Internals/WCFExtensions.cs +++ b/CefSharp/Internals/Wcf/WcfExtensions.cs @@ -2,13 +2,12 @@ // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -#if !NETCOREAPP using System; using System.ServiceModel.Description; -namespace CefSharp.Internals +namespace CefSharp.Internals.Wcf { - internal static class WCFExtensions + internal static class WcfExtensions { public static void ApplyOperationBehavior(this ServiceDescription description, Func behaviorFactory, @@ -53,4 +52,3 @@ public static void ApplyServiceBehavior(this ServiceDescription description, } } } -#endif diff --git a/CefSharp3.netcore.sln b/CefSharp3.netcore.sln index 9d53ff7e4a..14eca615f7 100644 --- a/CefSharp3.netcore.sln +++ b/CefSharp3.netcore.sln @@ -45,6 +45,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CefSharp.Example.netcore", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CefSharp.WinForms.Example.netcore", "CefSharp.WinForms.Example\CefSharp.WinForms.Example.netcore.csproj", "{64E47346-0BB1-4DF7-B135-12D70E1F2F32}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CefSharp.BrowserSubprocess.netcore", "CefSharp.BrowserSubprocess\CefSharp.BrowserSubprocess.netcore.csproj", "{FBFBD752-467C-444F-93E4-80D6242E8513}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CefSharp.Wpf.Example.netcore", "CefSharp.Wpf.Example\CefSharp.Wpf.Example.netcore.csproj", "{E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CefSharp.OffScreen.Example.netcore", "CefSharp.OffScreen.Example\CefSharp.OffScreen.Example.netcore.csproj", "{A430C9D4-0952-44A2-989A-23C476B7A1F0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -77,38 +83,38 @@ Global {6C4BB501-2F8E-48AC-9AB5-8CFB2D74185C}.Release|x64.Build.0 = Release|x64 {6C4BB501-2F8E-48AC-9AB5-8CFB2D74185C}.Release|x86.ActiveCfg = Release|Win32 {6C4BB501-2F8E-48AC-9AB5-8CFB2D74185C}.Release|x86.Build.0 = Release|Win32 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x64.ActiveCfg = Debug|x64 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x64.Build.0 = Debug|x64 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x86.ActiveCfg = Debug|x86 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x86.Build.0 = Debug|x86 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x64.ActiveCfg = Release|x64 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x64.Build.0 = Release|x64 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x86.ActiveCfg = Release|x86 - {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x86.Build.0 = Release|x86 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x64.ActiveCfg = Debug|x64 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x64.Build.0 = Debug|x64 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x86.ActiveCfg = Debug|x86 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x86.Build.0 = Debug|x86 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x64.ActiveCfg = Release|x64 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x64.Build.0 = Release|x64 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x86.ActiveCfg = Release|x86 - {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x86.Build.0 = Release|x86 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x64.ActiveCfg = Debug|x64 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x64.Build.0 = Debug|x64 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x86.ActiveCfg = Debug|x86 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x86.Build.0 = Debug|x86 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x64.ActiveCfg = Release|x64 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x64.Build.0 = Release|x64 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x86.ActiveCfg = Release|x86 - {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x86.Build.0 = Release|x86 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x64.ActiveCfg = Debug|x64 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x64.Build.0 = Debug|x64 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x86.ActiveCfg = Debug|x86 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x86.Build.0 = Debug|x86 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x64.ActiveCfg = Release|x64 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x64.Build.0 = Release|x64 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x86.ActiveCfg = Release|x86 - {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x86.Build.0 = Release|x86 + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x64.ActiveCfg = Debug|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x64.Build.0 = Debug|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x86.ActiveCfg = Debug|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Debug|x86.Build.0 = Debug|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x64.ActiveCfg = Release|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x64.Build.0 = Release|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x86.ActiveCfg = Release|Any CPU + {B91EB129-F892-402C-AF08-F3E1D5B80B09}.Release|x86.Build.0 = Release|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x64.ActiveCfg = Debug|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x64.Build.0 = Debug|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x86.ActiveCfg = Debug|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Debug|x86.Build.0 = Debug|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x64.ActiveCfg = Release|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x64.Build.0 = Release|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x86.ActiveCfg = Release|Any CPU + {99A1985B-2C79-4DE5-A0AD-0513647B9737}.Release|x86.Build.0 = Release|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x64.ActiveCfg = Debug|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x64.Build.0 = Debug|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x86.ActiveCfg = Debug|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Debug|x86.Build.0 = Debug|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x64.ActiveCfg = Release|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x64.Build.0 = Release|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x86.ActiveCfg = Release|Any CPU + {6680485E-7A5A-4661-86EB-F7B7B6AE4ADE}.Release|x86.Build.0 = Release|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x64.ActiveCfg = Debug|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x64.Build.0 = Debug|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x86.ActiveCfg = Debug|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Debug|x86.Build.0 = Debug|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x64.ActiveCfg = Release|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x64.Build.0 = Release|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x86.ActiveCfg = Release|Any CPU + {89540209-0C6D-4387-BE8A-7593B8D7784A}.Release|x86.Build.0 = Release|Any CPU {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Debug|x64.ActiveCfg = Debug|x64 {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Debug|x64.Build.0 = Debug|x64 {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Debug|x86.ActiveCfg = Debug|x86 @@ -117,6 +123,30 @@ Global {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Release|x64.Build.0 = Release|x64 {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Release|x86.ActiveCfg = Release|x86 {64E47346-0BB1-4DF7-B135-12D70E1F2F32}.Release|x86.Build.0 = Release|x86 + {FBFBD752-467C-444F-93E4-80D6242E8513}.Debug|x64.ActiveCfg = Debug|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Debug|x64.Build.0 = Debug|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Debug|x86.ActiveCfg = Debug|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Debug|x86.Build.0 = Debug|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Release|x64.ActiveCfg = Release|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Release|x64.Build.0 = Release|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Release|x86.ActiveCfg = Release|Any CPU + {FBFBD752-467C-444F-93E4-80D6242E8513}.Release|x86.Build.0 = Release|Any CPU + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Debug|x64.ActiveCfg = Debug|x64 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Debug|x64.Build.0 = Debug|x64 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Debug|x86.ActiveCfg = Debug|x86 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Debug|x86.Build.0 = Debug|x86 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Release|x64.ActiveCfg = Release|x64 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Release|x64.Build.0 = Release|x64 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Release|x86.ActiveCfg = Release|x86 + {E73A3B0C-457E-4065-BCE9-A10CAA8F4F2A}.Release|x86.Build.0 = Release|x86 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Debug|x64.ActiveCfg = Debug|x64 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Debug|x64.Build.0 = Debug|x64 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Debug|x86.ActiveCfg = Debug|x86 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Debug|x86.Build.0 = Debug|x86 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Release|x64.ActiveCfg = Release|x64 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Release|x64.Build.0 = Release|x64 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Release|x86.ActiveCfg = Release|x86 + {A430C9D4-0952-44A2-989A-23C476B7A1F0}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE