From f053f2bec1fbff08e6d6c2cdcd8055936a638150 Mon Sep 17 00:00:00 2001 From: Usman Shafiq Date: Mon, 4 Dec 2023 02:52:34 -0500 Subject: [PATCH] Build as Self Contained and Selfhost CefSharp SubProcess (#693) * Added self contained parameter to builds * Remove dotnet install from installer * Fixed missing SubProcessExe * Self hot browser subprocess --------- Co-authored-by: Natsumi --- .github/workflows/github_actions.yml | 2 +- Dotnet/Cef/CefService.cs | 5 +-- Dotnet/Cef/SubProcess.cs | 54 ++++++++++++++++++++++++++++ Dotnet/Program.cs | 1 + Installer/installer.nsi | 16 --------- build-all.ps1 | 2 +- build-dotnet.cmd | 2 +- 7 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 Dotnet/Cef/SubProcess.cs diff --git a/.github/workflows/github_actions.yml b/.github/workflows/github_actions.yml index 1d6c0af36..41465fb3b 100644 --- a/.github/workflows/github_actions.yml +++ b/.github/workflows/github_actions.yml @@ -34,7 +34,7 @@ jobs: run: cd ${{ github.workspace }}/html && npm run production && cd ${{ github.workspace }} - name: Build .NET Application - run: dotnet build -p:Configuration=Release -p:Platform=x64 -p:EnableWindowsTargeting=true + run: dotnet build -p:Configuration=Release -p:Platform=x64 -p:EnableWindowsTargeting=true --self-contained - name: Copy Web UI run: cp -r ${{ github.workspace }}/html/dist ${{ github.workspace }}/bin/x64/Release/html diff --git a/Dotnet/Cef/CefService.cs b/Dotnet/Cef/CefService.cs index 0643c9b1a..f7dc100e4 100644 --- a/Dotnet/Cef/CefService.cs +++ b/Dotnet/Cef/CefService.cs @@ -26,7 +26,8 @@ internal void Init() WindowlessRenderingEnabled = true, PersistSessionCookies = true, PersistUserPreferences = true, - UserAgent = Program.Version + UserAgent = Program.Version, + BrowserSubprocessPath = Environment.ProcessPath }; cefSettings.RegisterScheme(new CefCustomScheme @@ -59,7 +60,7 @@ internal void Init() //CefSharpSettings.WcfEnabled = true; // TOOD: REMOVE THIS LINE YO (needed for synchronous configRepository) CefSharpSettings.ShutdownOnExit = false; - if (Cef.Initialize(cefSettings) == false) + if (Cef.Initialize(cefSettings, false) == false) { throw new Exception("Cef.Initialize()"); } diff --git a/Dotnet/Cef/SubProcess.cs b/Dotnet/Cef/SubProcess.cs new file mode 100644 index 000000000..516f1713f --- /dev/null +++ b/Dotnet/Cef/SubProcess.cs @@ -0,0 +1,54 @@ +using CefSharp.Internals; +using System; +using System.IO; + +namespace VRCX; + +public class BrowserSubprocess +{ + /// + /// This function should be called from the application entry point function (typically Program.Main) + /// to execute a secondary process e.g. gpu, renderer, utility + /// This overload is specifically used for .Net Core. For hosting your own BrowserSubProcess + /// it's preferable to use the Main method provided by this class. + /// - Pass in command line args + /// + /// command line args + /// + /// If called for the browser process (identified by no "type" command-line value) it will return immediately + /// with a value of -1. If called for a recognized secondary process it will block until the process should exit + /// and then return the process exit code. + /// + public static void Start() + { + var args = Environment.GetCommandLineArgs(); + var type = CommandLineArgsParser.GetArgumentValue(args, CefSharpArguments.SubProcessTypeArgument); + + if (string.IsNullOrEmpty(type)) + { + // If --type param missing from command line CEF/Chromium assums + // this is the main process (as all subprocesses must have a type param). + return; + } + + var browserSubprocessDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CefSharp.BrowserSubprocess.Core.dll"); + if (!File.Exists(browserSubprocessDllPath)) + { + browserSubprocessDllPath = Path.Combine(Path.GetDirectoryName(typeof(CefSharp.Core.BrowserSettings).Assembly.Location), "CefSharp.BrowserSubprocess.Core.dll"); + } + var browserSubprocessDll = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(browserSubprocessDllPath); + var browserSubprocessExecutableType = browserSubprocessDll.GetType("CefSharp.BrowserSubprocess.BrowserSubprocessExecutable"); + + var browserSubprocessExecutable = Activator.CreateInstance(browserSubprocessExecutableType); + + var mainMethod = browserSubprocessExecutableType.GetMethod("MainSelfHost", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); + var argCount = mainMethod.GetParameters(); + + var methodArgs = new object[] { args }; + + var exitCode = mainMethod.Invoke(null, methodArgs); + + Environment.Exit((int)exitCode); + } +} + diff --git a/Dotnet/Program.cs b/Dotnet/Program.cs index d4fc0f016..755cb8d03 100644 --- a/Dotnet/Program.cs +++ b/Dotnet/Program.cs @@ -126,6 +126,7 @@ private static void GetVersion() private static void Run() { + BrowserSubprocess.Start(); Update.Check(); StartupArgs.ArgsCheck(); GetVersion(); diff --git a/Installer/installer.nsi b/Installer/installer.nsi index 9e677a60b..783a90be2 100644 --- a/Installer/installer.nsi +++ b/Installer/installer.nsi @@ -118,20 +118,6 @@ Function .onInit done: FunctionEnd -Function CheckAndInstallDotNet - nsExec::ExecToStack /OEM 'cmd /c dir "%windir%\system32" | dotnet --list-runtimes | find /c /i "Microsoft.NETCore.App 8"' - Pop $0 - Pop $1 - StrCpy $2 $1 1 - StrCmp $2 "1" 0 version_not_found - goto version_found - version_not_found: - inetc::get "https://aka.ms/dotnet/8.0/windowsdesktop-runtime-win-x64.exe" $TEMP\dotnet-runtime-win-x64.exe - ExecWait "$TEMP\dotnet-runtime-win-x64.exe /install /quiet /norestart" - Delete "$TEMP\dotnet-runtime-win-x64.exe" - version_found: -FunctionEnd - Function createDesktopShortcut CreateShortcut "$DESKTOP\VRCX.lnk" "$INSTDIR\VRCX.exe" FunctionEnd @@ -164,8 +150,6 @@ Section "Install" SecInstall Delete "$TEMP\vcredist_x64.exe" VSRedistInstalled: - Call CheckAndInstallDotNet - SetOutPath "$INSTDIR" File /r /x *.log /x *.pdb "..\bin\x64\Release\*.*" diff --git a/build-all.ps1 b/build-all.ps1 index 6f1b75a94..74faa038f 100644 --- a/build-all.ps1 +++ b/build-all.ps1 @@ -9,7 +9,7 @@ $ZipName = "VRCX_" + $Date + ".zip" $SetupName = "VRCX_" + $Date + "_Setup.exe" Write-Host "Building .Net..." -ForegroundColor Green -msbuild VRCX.sln -p:Configuration=Release -p:Platform=x64 -p:RestorePackagesConfig=true -t:"Restore;Clean;Build" -m +dotnet build VRCX.sln -p:Configuration=Release -p:Platform=x64 -p:RestorePackagesConfig=true -t:"Restore;Clean;Build" -m --self-contained Write-Host "Building Node.js..." -ForegroundColor Green cd "html" diff --git a/build-dotnet.cmd b/build-dotnet.cmd index 0c733c6ae..1df9e60bd 100644 --- a/build-dotnet.cmd +++ b/build-dotnet.cmd @@ -1,4 +1,4 @@ @echo off -dotnet build VRCX.sln -p:Configuration=Release -p:Platform=x64 -p:RestorePackagesConfig=true -t:"Restore;Clean;Build" -m +dotnet build VRCX.sln -p:Configuration=Release -p:Platform=x64 -p:RestorePackagesConfig=true -t:"Restore;Clean;Build" -m --self-contained mklink /J "%~dp0\bin\x64\Release\html" "%~dp0\html\dist" pause