Skip to content

Commit

Permalink
NEW: Added support for version v97.1.61. Please refer to the README.m…
Browse files Browse the repository at this point in the history
…d file for breaking changes.

FIX: CefSharp v84 would not be recognized
  • Loading branch information
cwollenhaupt committed Feb 1, 2022
1 parent 2ff4344 commit 0c35125
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 17 deletions.
2 changes: 1 addition & 1 deletion C#/fpCefSharp/fpCefSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CefSharp.WinForms" Version="92.0.260" />
<PackageReference Include="CefSharp.WinForms" Version="97.1.61" />
</ItemGroup>

<ItemGroup>
Expand Down
120 changes: 104 additions & 16 deletions FoxPro/cefsharpbrowser.prg
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ Define Class CefSharpBrowser as Custom
*--------------------------------------------------------------------------------------
oConfig = null

*--------------------------------------------------------------------------------------
* Make sure we only load CefSharp releases that are supported by the runtimes installed
* on the local machine.
*--------------------------------------------------------------------------------------
lCheckRuntime = .T.

*--------------------------------------------------------------------------------------
* Internal properties. Ensures that BindToHost is never called more than once per
* instance. We avoid repeated calls by maintaining a .NET Bridge instance that is
Expand All @@ -39,8 +45,18 @@ Define Class CefSharpBrowser as Custom
*========================================================================================
* Returns the cefSharp folder with the highest supported and installed version of
* cefSharp. We always return a path, even when it doesn't exist.
*
* The first time we call GetCefSharpPath we must pass a host, so that we can execute
* code in the AppDomain of the browser control. Calling BindToHost takes care of this.
*========================================================================================
Function GetCefSharpPath
Function GetCefSharpPath (toHost)

*--------------------------------------------------------------------------------------
* Assertions
*--------------------------------------------------------------------------------------
#IF __DEBUGLEVEL >= __DEBUG_REGULAR
Assert Vartype (m.toHost) $ T_OBJECT + T_OPTIONAL
#ENDIF

*--------------------------------------------------------------------------------------
* specify the program folder.
Expand All @@ -52,28 +68,42 @@ Function GetCefSharpPath
lcRoot = JustPath(_VFP.ServerName)
ENDIF
lcRoot = Addbs (m.lcRoot)


*--------------------------------------------------------------------------------------
* CefSharp v93 requires at least the VC++ 2019 runtime. We determine what runtimes
* are installed: vc2015, vc2019.
*--------------------------------------------------------------------------------------
* These are all supported versions of the CefSharp browser.
Local lcRuntime
lcRuntime = This.GetInstalledVcRuntime (m.toHost)

*--------------------------------------------------------------------------------------
Local laSupportedVersion[5]
laSupportedVersion[1] = "cef-bin-v65"
laSupportedVersion[2] = "cef-bin-v75.1.142"
laSupportedVersion[3] = "cef-bin-v79.1.360"
laSupportedVersion[4] = "cef-bin-v84.4.10"
laSupportedVersion[4] = "cef-bin-v91.1.230"
laSupportedVersion[5] = "cef-bin-v92.0.260"
* These are all supported versions of the CefSharp browser and the supported VC++
* runtimes.
*--------------------------------------------------------------------------------------
Local laSupportedVersion[7]
laSupportedVersion[1] = "cef-bin-v65 vc2015/vc2019"
laSupportedVersion[2] = "cef-bin-v75.1.142 vc2015/vc2019"
laSupportedVersion[3] = "cef-bin-v79.1.360 vc2015/vc2019"
laSupportedVersion[4] = "cef-bin-v84.4.10 vc2015/vc2019"
laSupportedVersion[5] = "cef-bin-v91.1.230 vc2015/vc2019"
laSupportedVersion[6] = "cef-bin-v92.0.260 vc2015/vc2019"
laSupportedVersion[7] = "cef-bin-v97.1.61 vc2019"

*--------------------------------------------------------------------------------------
* CefSharp is located in a sub folder. We are looking for the highest available
* version. If we can't find a version, we return the the path of the oldest supported
* version.
* version. We limit our search to those versions of CefSharp supported by the
* VC runtime that is installed on the machine.
*--------------------------------------------------------------------------------------
Local lcPath, lnVersion
Local lcPath, lnVersion, lcSupported
For lnVersion = Alen (laSupportedVersion, ALEN_LINES) to 1 step -1
lcPath = m.lcRoot + laSupportedVersion[m.lnVersion]
If Directory (m.lcPath, 1)
Exit
lcPath = m.lcRoot + GetWordNum (laSupportedVersion[m.lnVersion], 1)
lcSupported = GetWordNum (laSupportedVersion[m.lnVersion], 2)
If m.lcRuntime $ m.lcSupported ;
or not This.lCheckRuntime
If Directory (m.lcPath, 1)
Exit
EndIf
EndIf
EndFor

Expand All @@ -86,7 +116,65 @@ Function GetCefSharpPath
#ENDIF

Return m.lcPath

*========================================================================================
* Returns the installed VC++ runtime (vc2015, vc2019). To remain backward compatible
* with previous releases of cefSharpBrowser we return vc2015 whenever we can't find any
* later runtime without actually checking if the runtime is installed.
*========================================================================================
Procedure GetInstalledVcRuntime (toHost)

*--------------------------------------------------------------------------------------
* Assertions
*--------------------------------------------------------------------------------------
#IF __DEBUGLEVEL >= __DEBUG_REGULAR
Assert Vartype (m.toHost) $ T_OBJECT + T_OPTIONAL
#ENDIF

*--------------------------------------------------------------------------------------
* VC2015, VC2017, VC2019 and VC2022 share the same runtime library. That is, the
* library is backward compatible with the latest installed one being the one that is
* used. VcRedist.exe updates the registry to indicate which version is installed
* on the machine.
*
* We pass NULL instead of a default value to GetValue, because GetValue returns NULL
* if the key doesn't exist (ie. the runtime is not installed at all). GetValue only
* returns the default value if the key exists, but the value doesn't.
*--------------------------------------------------------------------------------------
Local lcVersion, loBridge
loBridge = This.DotNet (m.toHost)
lcVersion = loBridge.InvokeStaticMethod ( ;
"Microsoft.Win32.Registry", "GetValue" ;
,"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DevDiv\VC\Servicing\14.0\RuntimeMinimum" ;
,"Version" ;
,null ;
)
lcVersion = Nvl (m.lcVersion, "00.00.00")

*--------------------------------------------------------------------------------------
* Parse major and minor version
*--------------------------------------------------------------------------------------
Local lcMajor, lcMinor
lcMajor = GetWordNum (m.lcVersion, 1, ".")
lcMinor = GetWordNum (m.lcVersion, 2, ".")

*--------------------------------------------------------------------------------------
* Currently we only distinguish between vc2015 and vc2019. For newer runtimes such as
* VC 2022 we still return vc2019 until a future version of CefSharp actually requires
* this as a minimum version.
*--------------------------------------------------------------------------------------
Local lcVersion
Do case
Case Val (m.lcMajor) > 14
lcVersion = "vc2019"
Case Val (m.lcMajor) = 14 and Val (m.lcMinor) >= 20
lcVersion = "vc2019" && 14.20 is VC 2019 with multiple release up to 14.29.
Otherwise
lcVersion = "vc2015"
EndCase

Return m.lcVersion

*========================================================================================
* Returns .T. if the cefSharp browser is available. This is the case when the application
* folder contains a cef-bin-vNNN subfolder. NN is the version that is used.
Expand Down Expand Up @@ -166,7 +254,7 @@ Procedure BindToHost (toHost, tcAddress, toConfig)
* Load assemblies.
*--------------------------------------------------------------------------------------
Local lcPath, llOK
lcPath = Addbs (This.GetCefSharpPath ())
lcPath = Addbs (This.GetCefSharpPath (m.toHost))
loBridge.LoadAssembly (m.lcPath + "CefSharp.dll")
loBridge.LoadAssembly (m.lcPath + "CefSharp.Core.dll")
loBridge.LoadAssembly (m.lcPath + "CefSharp.WinForms.dll")
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ fpCefSharp relies on the following projects:
- [CefSharp](https://github.com/cefsharp/CefSharp)
- [wwDotNetBridge](https://github.com/RickStrahl/wwDotnetBridge)
- [fpDotNet](https://github.com/cwollenhaupt/fpDotNet)

### Breaking Changes
Visual C++ 2019 is used to build CefSharp in version v93 any beyond due to a change originating at Google. Clients must install the latest VC++ runtime to use any version later than v92.0.260. Microsoft provides the latest runtime for x86 systems [here](https://aka.ms/vs/17/release/vc_redist.x86.exe).

fpCefSharp verifies which VC++ runtime is installed on a client. Without an appropriate runtime only CefSharp versions up to v92.0.260 are considered. You can disable this behavior by setting the lCheckRuntime property to .F. If you support clients with and without VC++ 2019 runtimes, you must deploy the current version of fpCefSharp as well as the cef-bin folder for version v92.0.260 or any previous one. Not running the latest version of CefSharp is a security risk and might make your application vulnerable to web browser exploits.

If you subclassed fpCefSharp and overrode the GetCefSharpPath to change how fpCefSharp locates CefSharp, then please be advised that the method now receives a toHost parameter. You are free to ignore the value, but your subclass must have a corresponding LParameters statement to receive the value.

0 comments on commit 0c35125

Please sign in to comment.