diff --git a/src/ElectronNET.Samples.ElectronHostHook/Controllers/HomeController.cs b/src/ElectronNET.Samples.ElectronHostHook/Controllers/HomeController.cs new file mode 100644 index 00000000..10c10596 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/Controllers/HomeController.cs @@ -0,0 +1,21 @@ +using ElectronNET.API; +using Microsoft.AspNetCore.Mvc; + +namespace ElectronNET.Samples.ElectronHostHook.Controllers +{ + public class HomeController : Controller + { + public async Task Index() + { + string message = "Electron not active"; + if (HybridSupport.IsElectronActive) + { + // Call the HostHook defined in ElectronHostHook/index.ts + var result = await Electron.HostHook.CallAsync("ping", "Hello from C#"); + message = $"Sent 'Hello from C#', Received: '{result}'"; + } + + return View("Index", message); + } + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/.gitignore b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/.gitignore new file mode 100644 index 00000000..984dc924 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/.gitignore @@ -0,0 +1,3 @@ +node_modules +*.js +*.js.map diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/connector.ts b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/connector.ts new file mode 100644 index 00000000..295ba95f --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/connector.ts @@ -0,0 +1,21 @@ +import { Socket } from "socket.io"; + +export class Connector { + constructor(private socket: Socket, public app: any) { + } + + on(key: string, javaScriptCode: Function): void { + this.socket.on(key, (...args: any[]) => { + const id: string = args.pop(); + try { + javaScriptCode(...args, (data) => { + if (data) { + this.socket.emit(`${key}Complete${id}`, data); + } + }); + } catch (error) { + this.socket.emit(`${key}Error${id}`, `Host Hook Exception`, error); + } + }); + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/index.ts b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/index.ts new file mode 100644 index 00000000..54b69c97 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/index.ts @@ -0,0 +1,16 @@ +import { Connector } from "./connector"; +import { Socket } from "socket.io"; + +export class HookService extends Connector { + constructor(socket: Socket, public app: any) { + super(socket, app); + } + + onHostReady(): void { + // execute your own JavaScript Host logic here + this.on("ping", (msg, done) => { + console.log("Received ping from C#:", msg); + done("pong: " + msg); + }); + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/package.json b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/package.json new file mode 100644 index 00000000..069cbac2 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/package.json @@ -0,0 +1,12 @@ +{ + "name": "electron-host-hook", + "version": "1.0.0", + "description": "Connector for Electron.NET projects.", + "main": "index.js", + "dependencies": { + "socket.io": "^4.8.1" + }, + "devDependencies": { + "typescript": "^5.9.3" + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/tsconfig.json b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/tsconfig.json new file mode 100644 index 00000000..db8ccccd --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronHostHook/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2019", + "sourceMap": true, + "skipLibCheck": true + }, + "exclude": ["node_modules"] +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/ElectronNET.Samples.ElectronHostHook.csproj b/src/ElectronNET.Samples.ElectronHostHook/ElectronNET.Samples.ElectronHostHook.csproj new file mode 100644 index 00000000..70eb4366 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/ElectronNET.Samples.ElectronHostHook.csproj @@ -0,0 +1,36 @@ + + + true + + + + + + net8.0 + OutOfProcess + AspNetCoreModule + false + commonjs + true + ElectronHostHook/tsconfig.json + true + true + + + + + + + + + + + + + + + + + + + diff --git a/src/ElectronNET.Samples.ElectronHostHook/Program.cs b/src/ElectronNET.Samples.ElectronHostHook/Program.cs new file mode 100644 index 00000000..ee8fa812 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/Program.cs @@ -0,0 +1,31 @@ +using ElectronNET.API; + +namespace ElectronNET.Samples.ElectronHostHook +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + builder.WebHost.UseElectron(args, async () => + { + var window = await Electron.WindowManager.CreateWindowAsync(); + }); + + builder.Services.AddElectron(); + builder.Services.AddControllersWithViews(); + + var app = builder.Build(); + + app.UseStaticFiles(); + app.UseRouting(); + + app.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + + app.Run(); + } + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/Properties/launchSettings.json b/src/ElectronNET.Samples.ElectronHostHook/Properties/launchSettings.json new file mode 100644 index 00000000..d4c4b1eb --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "ElectronNET.Samples.ElectronHostHook": { + "commandName": "Project", + "launchBrowser": false, + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/ElectronNET.Samples.ElectronHostHook/Views/Home/Index.cshtml b/src/ElectronNET.Samples.ElectronHostHook/Views/Home/Index.cshtml new file mode 100644 index 00000000..f0f3be97 --- /dev/null +++ b/src/ElectronNET.Samples.ElectronHostHook/Views/Home/Index.cshtml @@ -0,0 +1,25 @@ +@model string +@{ + Layout = null; +} + + + + + + + ElectronHostHook Sample + + + +

ElectronHostHook Sample

+

This sample demonstrates bidirectional communication between C# and the Electron Host process.

+ +
+ Result: @Model +
+ + diff --git a/src/ElectronNET.sln b/src/ElectronNET.sln index 6cadc125..ef64ab18 100644 --- a/src/ElectronNET.sln +++ b/src/ElectronNET.sln @@ -62,6 +62,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ElectronNET.IntegrationTest EndProject Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "ElectronNET.Host", "ElectronNET.Host\ElectronNET.Host.esproj", "{1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectronNET.Samples.ElectronHostHook", "ElectronNET.Samples.ElectronHostHook\ElectronNET.Samples.ElectronHostHook.csproj", "{B8D65F3A-7E54-4632-9F1C-46679237B312}" + ProjectSection(ProjectDependencies) = postProject + {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6} = {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6} + {8860606D-6847-F22A-5AED-DF4E0984DD24} = {8860606D-6847-F22A-5AED-DF4E0984DD24} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -105,6 +111,10 @@ Global {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6}.Release|Any CPU.Build.0 = Release|Any CPU {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6}.Release|Any CPU.Deploy.0 = Release|Any CPU + {B8D65F3A-7E54-4632-9F1C-46679237B312}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8D65F3A-7E54-4632-9F1C-46679237B312}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8D65F3A-7E54-4632-9F1C-46679237B312}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8D65F3A-7E54-4632-9F1C-46679237B312}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -120,6 +130,7 @@ Global {06CAADC7-DE5B-47B4-AB2A-E9501459A2D1} = {D36CDFFD-3438-42E4-A7FF-88BA19AC4964} {AE877E48-6B44-63C2-8EA0-DB58D096B553} = {75129C45-FC6F-41B0-A485-07F4A7E031ED} {1C5FD66E-A1C6-C436-DF7C-3ECE4FEDDFE6} = {1BB6F634-2831-4496-83A6-BC6761DCEC8D} + {B8D65F3A-7E54-4632-9F1C-46679237B312} = {EDCBFC49-2AEE-4BAF-9368-4409298C52FC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {81A62E71-9E04-4EFE-AD5C-23165375F8EF}