From c01ef407afca1bea6024aa2985e91d0c5f6af294 Mon Sep 17 00:00:00 2001 From: Todd Schavey Date: Sun, 2 Jan 2022 22:46:53 -0500 Subject: [PATCH] fix #647 add to ElectronNET.API Process member interfaces for various fields --- src/ElectronNET.API/BridgeConnector.cs | 83 ++++++++++- src/ElectronNET.API/Entities/Versions.cs | 18 +++ src/ElectronNET.API/Process.cs | 179 +++++++++++++++-------- src/ElectronNET.Host/api/process.js | 50 ++++++- src/ElectronNET.Host/api/process.js.map | 2 +- src/ElectronNET.Host/api/process.ts | 58 +++++++- 6 files changed, 319 insertions(+), 71 deletions(-) create mode 100644 src/ElectronNET.API/Entities/Versions.cs diff --git a/src/ElectronNET.API/BridgeConnector.cs b/src/ElectronNET.API/BridgeConnector.cs index 23319e5..a12b130 100644 --- a/src/ElectronNET.API/BridgeConnector.cs +++ b/src/ElectronNET.API/BridgeConnector.cs @@ -1,4 +1,9 @@ -namespace ElectronNET.API +using System; +using Newtonsoft.Json.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace ElectronNET.API { internal static class BridgeConnector { @@ -28,6 +33,82 @@ return _socket; } + } + + public static async Task GetValueOverSocketAsync(string eventString, string eventCompletedString) + { + CancellationToken cancellationToken = new(); + cancellationToken.ThrowIfCancellationRequested(); + + var taskCompletionSource = new TaskCompletionSource(); + using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) + { + BridgeConnector.Socket.On(eventCompletedString, (value) => + { + BridgeConnector.Socket.Off(eventCompletedString); + + if (value == null) + { + Console.WriteLine($"ERROR: BridgeConnector (event: '{eventString}') returned null. Socket loop hang."); + taskCompletionSource.SetCanceled(); + return; + } + + try + { + taskCompletionSource.SetResult( new JValue(value).ToObject() ); + } + catch (Exception e) + { + Console.WriteLine($"ERROR: BridgeConnector (event: '{eventString}') exception: {e.Message}. Socket loop hung."); + } + }); + + BridgeConnector.Socket.Emit(eventString); + + return await taskCompletionSource.Task.ConfigureAwait(false); + } } + + public static async Task GetObjectOverSocketAsync(string eventString, string eventCompletedString) + { + CancellationToken cancellationToken = new(); + cancellationToken.ThrowIfCancellationRequested(); + + var taskCompletionSource = new TaskCompletionSource(); + using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) + { + BridgeConnector.Socket.On(eventCompletedString, (value) => + { + BridgeConnector.Socket.Off(eventCompletedString); + taskCompletionSource.SetResult( ((JObject)value).ToObject() ); + }); + + BridgeConnector.Socket.Emit(eventString); + + return await taskCompletionSource.Task.ConfigureAwait(false); + } + } + + public static async Task GetArrayOverSocketAsync(string eventString, string eventCompletedString) + { + CancellationToken cancellationToken = new(); + cancellationToken.ThrowIfCancellationRequested(); + + var taskCompletionSource = new TaskCompletionSource(); + using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) + { + BridgeConnector.Socket.On(eventCompletedString, (value) => + { + BridgeConnector.Socket.Off(eventCompletedString); + taskCompletionSource.SetResult( ((JArray)value).ToObject() ); + }); + + BridgeConnector.Socket.Emit(eventString); + + return await taskCompletionSource.Task.ConfigureAwait(false); + } + } + } } \ No newline at end of file diff --git a/src/ElectronNET.API/Entities/Versions.cs b/src/ElectronNET.API/Entities/Versions.cs new file mode 100644 index 0000000..254a62c --- /dev/null +++ b/src/ElectronNET.API/Entities/Versions.cs @@ -0,0 +1,18 @@ +namespace ElectronNET.API +{ + /// + /// + /// + public class Versions + { + /// + /// Gets or sets a value representing Chrome's version string. + /// + public string Chrome { get; set; } + + /// + /// Gets or sets a value representing Electron's version string. + /// + public bool Electron { get; set; } + } +} \ No newline at end of file diff --git a/src/ElectronNET.API/Process.cs b/src/ElectronNET.API/Process.cs index 887eda3..0976d20 100644 --- a/src/ElectronNET.API/Process.cs +++ b/src/ElectronNET.API/Process.cs @@ -37,92 +37,145 @@ namespace ElectronNET.API private static readonly object _syncRoot = new(); /// - /// The process.execPath property returns the absolute pathname of the executable that started the Node.js process. Symbolic links, if any, are resolved. - /// - /// - /// - /// var path = await Electron.Process.ExecPathAsync; - /// - /// + /// The process.execPath property returns the absolute pathname of the executable that + /// started the Node.js process. Symbolic links, if any, are resolved. + /// public Task ExecPathAsync { get { - CancellationToken cancellationToken = new(); - cancellationToken.ThrowIfCancellationRequested(); - - var taskCompletionSource = new TaskCompletionSource(); - using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) - { - BridgeConnector.Socket.On("process-execPathCompleted", (text) => - { - BridgeConnector.Socket.Off("process-execPathCompleted"); - taskCompletionSource.SetResult((string) text); - }); - - BridgeConnector.Socket.Emit("process-execPath"); - - return taskCompletionSource.Task; - } + return BridgeConnector.GetValueOverSocketAsync( + "process-execPath", "process-execPath-Completed"); } } /// - /// TBD + /// The process.argv property returns an array containing the command-line arguments passed + /// when the Node.js process was launched. The first element will be process.execPath. See + /// process.argv0 if access to the original value of argv[0] is needed. The second element + /// will be the path to the JavaScript file being executed. The remaining elements will be + /// any additional command-line arguments /// - /// public Task ArgvAsync { get { - CancellationToken cancellationToken = new(); - cancellationToken.ThrowIfCancellationRequested(); - - var taskCompletionSource = new TaskCompletionSource(); - using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) - { - BridgeConnector.Socket.On("process-argvCompleted", (value) => - { - BridgeConnector.Socket.Off("process-argvCompleted"); - taskCompletionSource.SetResult( ((JArray)value).ToObject() ); - }); - - BridgeConnector.Socket.Emit("process-argv"); - - return taskCompletionSource.Task; - } + return BridgeConnector.GetArrayOverSocketAsync( + "process-argv", "process-argv-Completed"); } } /// - /// The process.execPath property returns the absolute pathname of the executable that started the Node.js process. Symbolic links, if any, are resolved. + /// The process.execPath property returns the absolute pathname of the executable that + /// started the Node.js process. Symbolic links, if any, are resolved. /// - /// - /// - /// var path = await Electron.Process.ExecPathAsync; - /// - /// public Task TypeAsync { get { - CancellationToken cancellationToken = new(); - cancellationToken.ThrowIfCancellationRequested(); - - var taskCompletionSource = new TaskCompletionSource(); - using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) - { - BridgeConnector.Socket.On("process-typeCompleted", (text) => - { - BridgeConnector.Socket.Off("process-typeCompleted"); - taskCompletionSource.SetResult((string) text); - }); - - BridgeConnector.Socket.Emit("process-type"); - - return taskCompletionSource.Task; - } + return BridgeConnector.GetValueOverSocketAsync( + "process-type", "process-type-Completed"); } } + + + /// + /// + /// + public Task VersionsAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-versions", "process-versions-Completed"); + } + } + + + /// + /// + /// + public Task DefaultAppAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-defaultApp", "process-defaultApp-Completed"); + } + } + + /// + /// + /// + public Task IsMainFrameAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-isMainFrame", "process-isMainFrame-Completed"); + } + } + + /// + /// + /// + public Task ResourcesPathAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-resourcesPath", "process-resourcesPath-Completed"); + } + } + + /// + /// + /// + public Task UpTimeAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-uptime", "process-uptime-Completed"); + } + } + + /// + /// + /// + public Task PidAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-pid", "process-pid-Completed"); + } + } + + + /// + /// + /// + public Task ArchAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-arch", "process-arch-Completed"); + } + } + + /// + /// + /// + public Task PlatformAsync + { + get + { + return BridgeConnector.GetValueOverSocketAsync( + "process-platform", "process-platform-Completed"); + } + } + } } diff --git a/src/ElectronNET.Host/api/process.js b/src/ElectronNET.Host/api/process.js index 00c929f..36c08b4 100644 --- a/src/ElectronNET.Host/api/process.js +++ b/src/ElectronNET.Host/api/process.js @@ -4,15 +4,59 @@ module.exports = (socket) => { electronSocket = socket; socket.on('process-execPath', () => { const value = process.execPath; - electronSocket.emit('process-execPathCompleted', value); + electronSocket.emit('process-execPath-Completed', value); }); socket.on('process-argv', () => { const value = process.argv; - electronSocket.emit('process-argvCompleted', value); + electronSocket.emit('process-argv-Completed', value); }); socket.on('process-type', () => { const value = process.type; - electronSocket.emit('process-typeCompleted', value); + electronSocket.emit('process-type-Completed', value); + }); + socket.on('process-versions', () => { + const value = process.versions; + electronSocket.emit('process-versions-Completed', value); + }); + socket.on('process-defaultApp', () => { + if (process.defaultApp === undefined) { + electronSocket.emit('process-defaultApp-Completed', false); + return; + } + electronSocket.emit('process-defaultApp-Completed', process.defaultApp); + }); + socket.on('process-isMainFrame', () => { + if (process.isMainFrame === undefined) { + electronSocket.emit('process-isMainFrame-Completed', false); + return; + } + electronSocket.emit('process-isMainFrame-Completed', process.isMainFrame); + }); + socket.on('process-resourcesPath', () => { + const value = process.resourcesPath; + electronSocket.emit('process-resourcesPath-Completed', value); + }); + socket.on('process-uptime', () => { + let value = process.uptime(); + if (value === undefined) { + value = -1; + } + electronSocket.emit('process-uptime-Completed', value); + }); + socket.on('process-pid', () => { + if (process.pid === undefined) { + electronSocket.emit('process-pid-Completed', -1); + return; + } + electronSocket.emit('process-pid-Completed', process.pid); + }); + socket.on('process-arch', () => { + const value = process.arch; + electronSocket.emit('process-arch-Completed', value); + }); + socket.on('process-platform', () => { + const value = process.platform; + electronSocket.emit('process-platform-Completed', value); }); }; //# sourceMappingURL=process.js.map \ No newline at end of file diff --git a/src/ElectronNET.Host/api/process.js.map b/src/ElectronNET.Host/api/process.js.map index 1e69e30..096946c 100644 --- a/src/ElectronNET.Host/api/process.js.map +++ b/src/ElectronNET.Host/api/process.js.map @@ -1 +1 @@ -{"version":3,"file":"process.js","sourceRoot":"","sources":["process.ts"],"names":[],"mappings":";AACA,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAc,EAAE,EAAE;IACxB,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC/B,cAAc,CAAC,IAAI,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;QAC3B,cAAc,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;QAC3B,cAAc,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"process.js","sourceRoot":"","sources":["process.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/ElectronNET.Host/api/process.ts b/src/ElectronNET.Host/api/process.ts index 97c0569..ad04dbf 100644 --- a/src/ElectronNET.Host/api/process.ts +++ b/src/ElectronNET.Host/api/process.ts @@ -6,16 +6,68 @@ export = (socket: Socket) => { socket.on('process-execPath', () => { const value = process.execPath; - electronSocket.emit('process-execPathCompleted', value); + electronSocket.emit('process-execPath-Completed', value); }); socket.on('process-argv', () => { const value = process.argv; - electronSocket.emit('process-argvCompleted', value); + electronSocket.emit('process-argv-Completed', value); }); socket.on('process-type', () => { const value = process.type; - electronSocket.emit('process-typeCompleted', value); + electronSocket.emit('process-type-Completed', value); }); + + socket.on('process-versions', () => { + const value = process.versions; + electronSocket.emit('process-versions-Completed', value); + }); + + socket.on('process-defaultApp', () => { + if (process.defaultApp === undefined) { + electronSocket.emit('process-defaultApp-Completed', false); + return; + } + electronSocket.emit('process-defaultApp-Completed', process.defaultApp); + }); + + socket.on('process-isMainFrame', () => { + if (process.isMainFrame === undefined) { + electronSocket.emit('process-isMainFrame-Completed', false); + return; + } + electronSocket.emit('process-isMainFrame-Completed', process.isMainFrame); + }); + + socket.on('process-resourcesPath', () => { + const value = process.resourcesPath; + electronSocket.emit('process-resourcesPath-Completed', value); + }); + + socket.on('process-uptime', () => { + let value = process.uptime(); + if (value === undefined) { + value = -1; + } + electronSocket.emit('process-uptime-Completed', value); + }); + + socket.on('process-pid', () => { + if (process.pid === undefined) { + electronSocket.emit('process-pid-Completed', -1); + return; + } + electronSocket.emit('process-pid-Completed', process.pid); + }); + + socket.on('process-arch', () => { + const value = process.arch; + electronSocket.emit('process-arch-Completed', value); + }); + + socket.on('process-platform', () => { + const value = process.platform; + electronSocket.emit('process-platform-Completed', value); + }) };