Setup Electron
ADD
HiddenWallet/HiddenWallet.GUI/index.html
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>HiddenWallet - nopara73</title>
+ <script type="text/javascript" src="node_modules/angular/angular.min.js"></script>
+ <script type="text/javascript" src="app/app.js"></script>
+</head>
+<body>
+ <div class="container" ng-controller="WalletCtrl as ctrl">
+ <p style="color: red" ng-show="ctrl.ErrorMessage">{{ctrl.ErrorMessage}}</p>
+ <p>{{ ctrl.Wallet }}</p>
+ </div>
+</body>
+</html>
\ No newline at end of file

ADD
HiddenWallet/HiddenWallet.GUI/main.js
+const electron = require('electron');
+// Module to control application life.
+const app = electron.app;
+// Module to create native browser window.
+const BrowserWindow = electron.BrowserWindow;
+
+const path = require('path');
+const url = require('url');
+
+// Keep a global reference of the window object, if you don't, the window will
+// be closed automatically when the JavaScript object is garbage collected.
+let mainWindow;
+
+function createWindow() {
+ // Create the browser window.
+ mainWindow = new BrowserWindow({ width: 800, height: 600 });
+
+ // and load the index.html of the app.
+ mainWindow.loadURL(url.format({
+ pathname: path.join(__dirname, 'index.html'),
+ protocol: 'file:',
+ slashes: true
+ }));
+
+ // Open the DevTools.
+ mainWindow.webContents.openDevTools();
+
+ // Emitted when the window is closed.
+ mainWindow.on('closed', function () {
+ // Dereference the window object, usually you would store windows
+ // in an array if your app supports multi windows, this is the time
+ // when you should delete the corresponding element.
+ mainWindow = null;
+ });
+}
+
+// This method will be called when Electron has finished
+// initialization and is ready to create browser windows.
+// Some APIs can only be used after this event occurs.
+app.on('ready', startApi);
+
+// Quit when all windows are closed.
+app.on('window-all-closed', function () {
+ // On OS X it is common for applications and their menu bar
+ // to stay active until the user quits explicitly with Cmd + Q
+ if (process.platform !== 'darwin') {
+ app.quit();
+ }
+});
+
+app.on('activate', function () {
+ // On OS X it's common to re-create a window in the app when the
+ // dock icon is clicked and there are no other windows open.
+ if (mainWindow === null) {
+ createWindow();
+ }
+});
+// In this file you can include the rest of your app's specific main process
+// code. You can also put them in separate files and require them here.
+
+const os = require('os');
+var apiProcess = null;
+
+function startApi() {
+ var proc = require('child_process').spawn;
+ // run server
+ var apipath = path.join(__dirname, '..\\HiddenWallet.API\\bin\\dist\\win\\HiddenWallet.API.exe');
+ apiProcess = proc(apipath);
+
+ apiProcess.stdout.on('data', (data) => {
+ writeLog(`stdout: ${data}`);
+ if (mainWindow == null) {
+ createWindow();
+ }
+ });
+}
+
+//Kill process when electron exits
+process.on('exit', function () {
+ writeLog('exit');
+ apiProcess.kill();
+});
+
+function writeLog(msg) {
+ console.log(msg);
+}
\ No newline at end of file

ADD
HiddenWallet/HiddenWallet.GUI/package.json
+{
+ "name": "hidden-wallet.gui",
+ "version": "0.4.0",
+ "description": "HiddenWallet.GUI",
+ "main": "main.js",
+ "author": {
+ "name": "nopara73"
+ },
+ "devDependencies": {
+ "electron": "^1.6.5"
+ },
+ "dependencies": {
+ "angular": "^1.6.4"
+ },
+ "scripts": {
+ "start": "electron ."
+ }
+}

MODIFY
HiddenWallet/HiddenWallet.sln
HiddenWallet/HiddenWallet.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiddenWallet.API", "HiddenWallet.API\HiddenWallet.API.csproj", "{150C4E15-F6AD-4620-9198-D236227A90A6}"
EndProject
+Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "HiddenWallet.GUI", "HiddenWallet.GUI\HiddenWallet.GUI.njsproj", "{AA83AE28-4FD1-4064-B256-634091A8D738}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{150C4E15-F6AD-4620-9198-D236227A90A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{150C4E15-F6AD-4620-9198-D236227A90A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{150C4E15-F6AD-4620-9198-D236227A90A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA83AE28-4FD1-4064-B256-634091A8D738}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA83AE28-4FD1-4064-B256-634091A8D738}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA83AE28-4FD1-4064-B256-634091A8D738}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA83AE28-4FD1-4064-B256-634091A8D738}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Setup Electron