mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-02-12 21:25:06 +00:00
Merge branch 'dev/hosthooks'
This commit is contained in:
@@ -60,7 +60,13 @@
|
||||
/// </summary>
|
||||
public static Clipboard Clipboard { get { return Clipboard.Instance; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to execute native JavaScript/TypeScript code from the host process.
|
||||
///
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// ElectronHostHook directory:
|
||||
/// <c>electronize add HostHook</c>
|
||||
/// </summary>
|
||||
public static HostHook HostHook { get { return HostHook.Instance; } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,18 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows you to execute native JavaScript/TypeScript code from the host process.
|
||||
///
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// ElectronHostHook directory:
|
||||
/// <c>electronize add HostHook</c>
|
||||
/// </summary>
|
||||
public sealed class HostHook
|
||||
{
|
||||
private static HostHook _electronHostHook;
|
||||
private static object _syncRoot = new object();
|
||||
string oneCallguid = Guid.NewGuid().ToString();
|
||||
|
||||
internal HostHook() { }
|
||||
|
||||
@@ -32,18 +40,43 @@ namespace ElectronNET.API
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
public void Call(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments);
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + oneCallguid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + oneCallguid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments, oneCallguid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Results from the executed host code.</typeparam>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
/// <returns></returns>
|
||||
public Task<T> CallAsync<T>(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Complete" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
BridgeConnector.Socket.Off(socketEventName + "Complete" + guid);
|
||||
T data;
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
@@ -11,7 +8,6 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "main.js");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "package.json");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "package-lock.json");
|
||||
|
||||
string hostApiFolder = Path.Combine(tempPath, "api");
|
||||
if (Directory.Exists(hostApiFolder) == false)
|
||||
|
||||
67
ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs
Normal file
67
ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
public static class DirectoryCopy
|
||||
{
|
||||
public static void Do(string sourceDirName, string destDirName, bool copySubDirs, List<string> ignoredSubDirs)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourceDirName);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
// If the destination directory doesn't exist, create it.
|
||||
if (!Directory.Exists(destDirName))
|
||||
{
|
||||
Directory.CreateDirectory(destDirName);
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryInfo targetDir = new DirectoryInfo(destDirName);
|
||||
|
||||
foreach (FileInfo fileDel in targetDir.EnumerateFiles())
|
||||
{
|
||||
fileDel.Delete();
|
||||
}
|
||||
foreach (DirectoryInfo dirDel in targetDir.EnumerateDirectories())
|
||||
{
|
||||
dirDel.Delete(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Get the files in the directory and copy them to the new location.
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string temppath = Path.Combine(destDirName, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
// If copying subdirectories, copy them and their contents to new location.
|
||||
if (copySubDirs)
|
||||
{
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
if (ignoredSubDirs.Contains(subdir.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string temppath = Path.Combine(destDirName, subdir.Name);
|
||||
Do(subdir.FullName, temppath, copySubDirs, ignoredSubDirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
139
ElectronNET.CLI/Commands/AddCommand.cs
Normal file
139
ElectronNET.CLI/Commands/AddCommand.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace ElectronNET.CLI.Commands
|
||||
{
|
||||
public class AddCommand : ICommand
|
||||
{
|
||||
public const string COMMAND_NAME = "add";
|
||||
public const string COMMAND_DESCRIPTION = "The add command needs to be invoked via 'add hosthook'. This creates a special folder for your custom npm package installation.";
|
||||
public const string COMMAND_ARGUMENTS = "hosthook";
|
||||
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
|
||||
|
||||
|
||||
private string[] _args;
|
||||
|
||||
public AddCommand(string[] args)
|
||||
{
|
||||
_args = args;
|
||||
}
|
||||
|
||||
private static string ElectronHostHookFolderName = "ElectronHostHook";
|
||||
|
||||
public Task<bool> ExecuteAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
if(_args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Specify 'hosthook' to add custom npm packages.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_args[0].ToLowerInvariant() != "hosthook")
|
||||
{
|
||||
Console.WriteLine("Specify 'hosthook' to add custom npm packages.");
|
||||
return false;
|
||||
}
|
||||
|
||||
string aspCoreProjectPath = "";
|
||||
|
||||
// Maybe ToDo: Adding the possiblity to specify a path (like we did in the InitCommand, but this would require a better command args parser)
|
||||
aspCoreProjectPath = Directory.GetCurrentDirectory();
|
||||
|
||||
var currentDirectory = aspCoreProjectPath;
|
||||
|
||||
var targetFilePath = Path.Combine(currentDirectory, ElectronHostHookFolderName);
|
||||
|
||||
if(Directory.Exists(targetFilePath))
|
||||
{
|
||||
Console.WriteLine("ElectronHostHook directory already in place. If you want to start over, delete the folder and invoke this command again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLine("Adding the ElectronHostHook folder to your project...");
|
||||
|
||||
Directory.CreateDirectory(targetFilePath);
|
||||
|
||||
// Deploy related files
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "index.ts", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "connector.ts", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "package.json", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "tsconfig.json", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, ".gitignore", "ElectronHostHook.");
|
||||
|
||||
// npm for typescript compiler etc.
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", targetFilePath);
|
||||
|
||||
// run typescript compiler
|
||||
string tscPath = Path.Combine(targetFilePath, "node_modules", ".bin");
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"tsc -p ../../", tscPath);
|
||||
|
||||
// search .csproj
|
||||
Console.WriteLine($"Search your .csproj to add configure CopyToPublishDirectory to 'Never'");
|
||||
var projectFile = Directory.EnumerateFiles(currentDirectory, "*.csproj", SearchOption.TopDirectoryOnly).FirstOrDefault();
|
||||
|
||||
Console.WriteLine($"Found your .csproj: {projectFile} - check for existing CopyToPublishDirectory setting or update it.");
|
||||
|
||||
if (!EditCsProj(projectFile)) return false;
|
||||
|
||||
Console.WriteLine($"Everything done - happy electronizing with your custom npm packages!");
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// ToDo: Cleanup this copy/past code.
|
||||
private static bool EditCsProj(string projectFile)
|
||||
{
|
||||
using (var stream = File.Open(projectFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
|
||||
{
|
||||
var xmlDocument = XDocument.Load(stream);
|
||||
|
||||
var projectElement = xmlDocument.Descendants("Project").FirstOrDefault();
|
||||
if (projectElement == null || projectElement.Attribute("Sdk")?.Value != "Microsoft.NET.Sdk.Web")
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Project file is not a compatible type of 'Microsoft.NET.Sdk.Web'. Your project: {projectElement?.Attribute("Sdk")?.Value}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string itemGroupXmlString = "<ItemGroup>" +
|
||||
"<Content Update=\"ElectronHostHook\\**\\*.*\">" +
|
||||
"<CopyToPublishDirectory>Never</CopyToPublishDirectory>" +
|
||||
"</Content>" +
|
||||
"</ItemGroup>";
|
||||
|
||||
var newItemGroupForConfig = XElement.Parse(itemGroupXmlString);
|
||||
xmlDocument.Root.Add(newItemGroupForConfig);
|
||||
|
||||
stream.SetLength(0);
|
||||
stream.Position = 0;
|
||||
|
||||
var xws = new XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = true,
|
||||
Indent = true
|
||||
};
|
||||
using (XmlWriter xw = XmlWriter.Create(stream, xws))
|
||||
{
|
||||
xmlDocument.Save(xw);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Console.WriteLine($"Publish setting added in csproj!");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.CLI.Commands.Actions;
|
||||
|
||||
@@ -16,7 +14,7 @@ namespace ElectronNET.CLI.Commands
|
||||
public static string COMMAND_ARGUMENTS = "Needed: '/target' with params 'win/osx/linux' to build for a typical app or use 'custom' and specify .NET Core build config & electron build config" + Environment.NewLine +
|
||||
" for custom target, check .NET Core RID Catalog and Electron build target/" + Environment.NewLine +
|
||||
" e.g. '/target win' or '/target custom \"win7-x86;win32\"'" + Environment.NewLine +
|
||||
"Optional: '/dotnet-configuration' with the desired .NET Core build config e.g. release or debug. Default = Release" + Environment.NewLine +
|
||||
"Optional: '/dotnet-configuration' with the desired .NET Core build config e.g. release or debug. Default = Release" + Environment.NewLine +
|
||||
"Optional: '/electron-arch' to specify the resulting electron processor architecture (e.g. ia86 for x86 builds). Be aware to use the '/target custom' param as well!" + Environment.NewLine +
|
||||
"Optional: '/electron-params' specify any other valid parameter, which will be routed to the electron-packager." + Environment.NewLine +
|
||||
"Full example for a 32bit debug build with electron prune: build /target custom win7-x86;win32 /dotnet-configuration Debug /electron-arch ia32 /electron-params \"--prune=true \"";
|
||||
@@ -83,33 +81,40 @@ namespace ElectronNET.CLI.Commands
|
||||
}
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install --production", tempPath);
|
||||
|
||||
if (Directory.Exists(checkForNodeModulesDirPath) == false)
|
||||
Console.WriteLine("Start npm install electron-packager...");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
Console.WriteLine("node_modules missing in: " + checkForNodeModulesDirPath);
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
|
||||
Console.WriteLine("Start npm install electron-packager...");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
// Works proper on Windows...
|
||||
ProcessHelper.CmdExecute("npm install electron-packager --global", tempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: find another solution or document it proper
|
||||
// GH Issue https://github.com/electron-userland/electron-prebuilt/issues/48
|
||||
Console.WriteLine("Electron Packager - make sure you invoke 'sudo npm install electron-packager --global' at " + tempPath + " manually. Sry.");
|
||||
}
|
||||
// Works proper on Windows...
|
||||
ProcessHelper.CmdExecute("npm install electron-packager --global", tempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Skip npm install, because node_modules directory exists in: " + checkForNodeModulesDirPath);
|
||||
// ToDo: find another solution or document it proper
|
||||
// GH Issue https://github.com/electron-userland/electron-prebuilt/issues/48
|
||||
Console.WriteLine("Electron Packager - make sure you invoke 'sudo npm install electron-packager --global' at " + tempPath + " manually. Sry.");
|
||||
}
|
||||
|
||||
Console.WriteLine("ElectronHostHook handling started...");
|
||||
|
||||
string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
|
||||
|
||||
if (Directory.Exists(electronhosthookDir))
|
||||
{
|
||||
string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
|
||||
DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List<string>() { "node_modules" });
|
||||
|
||||
Console.WriteLine("Start npm install for hosthooks...");
|
||||
ProcessHelper.CmdExecute("npm install --production", hosthookDir);
|
||||
|
||||
string tscPath = Path.Combine(tempPath, "node_modules", ".bin");
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"tsc -p ../../ElectronHostHook --sourceMap false", tscPath);
|
||||
}
|
||||
|
||||
Console.WriteLine("Build Electron Desktop Application...");
|
||||
|
||||
@@ -61,22 +61,33 @@ namespace ElectronNET.CLI.Commands
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
|
||||
var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
if (Directory.Exists(checkForNodeModulesDirPath) == false)
|
||||
{
|
||||
Console.WriteLine("node_modules missing in: " + checkForNodeModulesDirPath);
|
||||
Console.WriteLine("node_modules missing in: " + nodeModulesDirPath);
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
|
||||
Console.WriteLine("ElectronHostHook handling started...");
|
||||
|
||||
string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
|
||||
|
||||
if (Directory.Exists(electronhosthookDir))
|
||||
{
|
||||
Console.WriteLine("Skip npm install, because node_modules directory exists in: " + checkForNodeModulesDirPath);
|
||||
string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
|
||||
DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List<string>() { "node_modules" });
|
||||
|
||||
Console.WriteLine("Start npm install for hosthooks...");
|
||||
ProcessHelper.CmdExecute("npm install", hosthookDir);
|
||||
|
||||
string tscPath = Path.Combine(tempPath, "node_modules", ".bin");
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"tsc -p ../../ElectronHostHook", tscPath);
|
||||
}
|
||||
|
||||
string path = Path.Combine(tempPath, "node_modules", ".bin");
|
||||
|
||||
|
||||
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWindows)
|
||||
{
|
||||
@@ -92,5 +103,7 @@ namespace ElectronNET.CLI.Commands
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ This package contains the dotnet tooling to electronize your application.</Descr
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\package-lock.json" Link="ElectronHost\package-lock.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\package.json" Link="ElectronHost\package.json" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -55,6 +54,15 @@ This package contains the dotnet tooling to electronize your application.</Descr
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\ipc.js" Link="ElectronHost\api\ipc.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\index.ts" Link="ElectronHost\ElectronHostHook\index.ts" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\connector.ts" Link="ElectronHost\ElectronHostHook\connector.ts" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\tsconfig.json" Link="ElectronHost\ElectronHostHook\tsconfig.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\package.json" Link="ElectronHost\ElectronHostHook\package.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\.gitignore" Link="ElectronHost\ElectronHostHook\.gitignore" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\app.js" Link="ElectronHost\api\app.js" />
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace ElectronNET.CLI
|
||||
case InitCommand.COMMAND_NAME:
|
||||
command = new InitCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
case AddCommand.COMMAND_NAME:
|
||||
command = new AddCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
case VersionCommand.COMMAND_NAME:
|
||||
command = new VersionCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
@@ -83,15 +86,20 @@ namespace ElectronNET.CLI
|
||||
Console.WriteLine($"\t{StartElectronCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {StartElectronCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to build the Electron Application:");
|
||||
Console.WriteLine("Command to build the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{BuildCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {BuildCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to init the Electron Application:");
|
||||
Console.WriteLine("Command to init the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{InitCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {InitCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Command to add a custom npm packages to the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{AddCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {AddCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to see the current ElectronNET version number:");
|
||||
Console.WriteLine("\t");
|
||||
@@ -116,6 +124,9 @@ namespace ElectronNET.CLI
|
||||
case InitCommand.COMMAND_NAME:
|
||||
PrintUsage(InitCommand.COMMAND_NAME, InitCommand.COMMAND_DESCRIPTION, InitCommand.CommandOptions, InitCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
case AddCommand.COMMAND_NAME:
|
||||
PrintUsage(AddCommand.COMMAND_NAME, AddCommand.COMMAND_DESCRIPTION, AddCommand.CommandOptions, AddCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
case VersionCommand.COMMAND_NAME:
|
||||
PrintUsage(VersionCommand.COMMAND_NAME, VersionCommand.COMMAND_DESCRIPTION, VersionCommand.CommandOptions, VersionCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
|
||||
91
ElectronNET.Host/ElectronHostHook/.gitignore
vendored
Normal file
91
ElectronNET.Host/ElectronHostHook/.gitignore
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
# Created by https://www.gitignore.io/api/node
|
||||
# Edit at https://www.gitignore.io/?templates=node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# End of https://www.gitignore.io/api/node
|
||||
27
ElectronNET.Host/ElectronHostHook/connector.js
Normal file
27
ElectronNET.Host/ElectronHostHook/connector.js
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Connector {
|
||||
constructor(socket,
|
||||
// @ts-ignore
|
||||
app) {
|
||||
this.socket = socket;
|
||||
this.app = app;
|
||||
}
|
||||
on(key, javaScriptCode) {
|
||||
this.socket.on(key, (...args) => {
|
||||
const id = 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.Connector = Connector;
|
||||
//# sourceMappingURL=connector.js.map
|
||||
1
ElectronNET.Host/ElectronHostHook/connector.js.map
Normal file
1
ElectronNET.Host/ElectronHostHook/connector.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"connector.js","sourceRoot":"","sources":["connector.ts"],"names":[],"mappings":";;AAAA,MAAa,SAAS;IAClB,YAAoB,MAAuB;IACvC,aAAa;IACN,GAAiB;QAFR,WAAM,GAAN,MAAM,CAAiB;QAEhC,QAAG,GAAH,GAAG,CAAc;IAAI,CAAC;IAEjC,EAAE,CAAC,GAAW,EAAE,cAAwB;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACnC,MAAM,EAAE,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;YAE9B,IAAI;gBACA,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC7B,IAAI,IAAI,EAAE;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;qBACjD;gBACL,CAAC,CAAC,CAAC;aACN;YAAC,OAAO,KAAK,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC;aACtE;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AApBD,8BAoBC"}
|
||||
21
ElectronNET.Host/ElectronHostHook/connector.ts
Normal file
21
ElectronNET.Host/ElectronHostHook/connector.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export class Connector {
|
||||
constructor(private socket: SocketIO.Socket,
|
||||
// @ts-ignore
|
||||
public app: Electron.App) { }
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
14
ElectronNET.Host/ElectronHostHook/index.js
Normal file
14
ElectronNET.Host/ElectronHostHook/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const connector_1 = require("./connector");
|
||||
class HookService extends connector_1.Connector {
|
||||
constructor(socket, app) {
|
||||
super(socket, app);
|
||||
this.app = app;
|
||||
}
|
||||
onHostReady() {
|
||||
// execute your own JavaScript Host logic here
|
||||
}
|
||||
}
|
||||
exports.HookService = HookService;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
ElectronNET.Host/ElectronHostHook/index.js.map
Normal file
1
ElectronNET.Host/ElectronHostHook/index.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;AAEA,2CAAwC;AAExC,MAAa,WAAY,SAAQ,qBAAS;IACtC,YAAY,MAAuB,EAAS,GAAiB;QACzD,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QADqB,QAAG,GAAH,GAAG,CAAc;IAE7D,CAAC;IAED,WAAW;QACP,8CAA8C;IAClD,CAAC;CACJ;AARD,kCAQC"}
|
||||
14
ElectronNET.Host/ElectronHostHook/index.ts
Normal file
14
ElectronNET.Host/ElectronHostHook/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// @ts-ignore
|
||||
import * as Electron from "electron";
|
||||
import { Connector } from "./connector";
|
||||
|
||||
export class HookService extends Connector {
|
||||
constructor(socket: SocketIO.Socket, public app: Electron.App) {
|
||||
super(socket, app);
|
||||
}
|
||||
|
||||
onHostReady(): void {
|
||||
// execute your own JavaScript Host logic here
|
||||
}
|
||||
}
|
||||
|
||||
20
ElectronNET.Host/ElectronHostHook/package.json
Normal file
20
ElectronNET.Host/ElectronHostHook/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "electron-host-hook",
|
||||
"version": "1.0.0",
|
||||
"description": "Connector for Electron.NET projects.",
|
||||
"repository": {
|
||||
"url": "https://github.com/ElectronNET/Electron.NET"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Gregor Biswanger",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/socket.io": "^2.1.2",
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
11
ElectronNET.Host/ElectronHostHook/tsconfig.json
Normal file
11
ElectronNET.Host/ElectronHostHook/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"target": "es2015"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
const { app } = require('electron');
|
||||
const { BrowserWindow, dialog, shell } = require('electron');
|
||||
const fs = require('fs');
|
||||
const { BrowserWindow } = require('electron');
|
||||
const path = require('path');
|
||||
const process = require('child_process').spawn;
|
||||
const portscanner = require('portscanner');
|
||||
@@ -106,9 +105,10 @@ function startSocketApiBridge(port) {
|
||||
}
|
||||
|
||||
try {
|
||||
const hostHookScriptFilePath = path.join(__dirname, 'bin', 'ElectronHostHook', 'index.js');
|
||||
const { HookService } = require(hostHookScriptFilePath);
|
||||
if (hostHook === undefined) {
|
||||
const hostHookScriptFilePath = path.join(__dirname, 'ElectronHostHook', 'index.js');
|
||||
|
||||
if (isModuleAvailable(hostHookScriptFilePath) && hostHook === undefined) {
|
||||
const { HookService } = require(hostHookScriptFilePath);
|
||||
hostHook = new HookService(socket, app);
|
||||
hostHook.onHostReady();
|
||||
}
|
||||
@@ -118,6 +118,14 @@ function startSocketApiBridge(port) {
|
||||
});
|
||||
}
|
||||
|
||||
function isModuleAvailable(name) {
|
||||
try {
|
||||
require.resolve(name);
|
||||
return true;
|
||||
} catch (e) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
function startAspCoreBackend(electronPort) {
|
||||
|
||||
// hostname needs to be localhost, otherwise Windows Firewall will be triggered.
|
||||
|
||||
1733
ElectronNET.Host/package-lock.json
generated
1733
ElectronNET.Host/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
||||
{
|
||||
"name": "electron.net.host",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"description": "Electron-Host for Electron.NET.",
|
||||
"repository": {
|
||||
"url": "https://github.com/ElectronNET/Electron.NET"
|
||||
},
|
||||
"main": "main.js",
|
||||
"author": "Gregor Biswanger",
|
||||
"license": "ISC",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "tsc -p ."
|
||||
},
|
||||
|
||||
@@ -23,10 +23,6 @@ namespace ElectronNET.WebApp.Controllers
|
||||
|
||||
string[] files = await Electron.Dialog.ShowOpenDialogAsync(mainWindow, options);
|
||||
Electron.IpcMain.Send(mainWindow, "select-directory-reply", files);
|
||||
|
||||
var result = await Electron.HostHook.CallAsync<string>("create-excel", files);
|
||||
|
||||
await Electron.Dialog.ShowMessageBoxAsync(result);
|
||||
});
|
||||
|
||||
Electron.IpcMain.On("error-dialog", (args) =>
|
||||
|
||||
34
ElectronNET.WebApp/Controllers/HostHookController.cs
Normal file
34
ElectronNET.WebApp/Controllers/HostHookController.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using ElectronNET.API;
|
||||
using ElectronNET.API.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Linq;
|
||||
|
||||
namespace ElectronNET.WebApp.Controllers
|
||||
{
|
||||
public class HostHookController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
if (HybridSupport.IsElectronActive)
|
||||
{
|
||||
Electron.IpcMain.On("start-hoosthook", async (args) =>
|
||||
{
|
||||
var mainWindow = Electron.WindowManager.BrowserWindows.First();
|
||||
var options = new OpenDialogOptions
|
||||
{
|
||||
Properties = new OpenDialogProperty[]
|
||||
{
|
||||
OpenDialogProperty.openDirectory
|
||||
}
|
||||
};
|
||||
var folderPath = await Electron.Dialog.ShowOpenDialogAsync(mainWindow, options);
|
||||
|
||||
var resultFromTypeScript = await Electron.HostHook.CallAsync<string>("create-excel-file", folderPath);
|
||||
Electron.IpcMain.Send(mainWindow, "excel-file-created", resultFromTypeScript);
|
||||
});
|
||||
}
|
||||
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,7 @@ namespace ElectronNET.WebApp.Controllers
|
||||
|
||||
Electron.IpcMain.On("new-window", async (args) =>
|
||||
{
|
||||
|
||||
await Electron.WindowManager.CreateWindowAsync(viewPath);
|
||||
|
||||
});
|
||||
|
||||
Electron.IpcMain.On("manage-window", async (args) =>
|
||||
|
||||
92
ElectronNET.WebApp/ElectronHostHook/.gitignore
vendored
92
ElectronNET.WebApp/ElectronHostHook/.gitignore
vendored
@@ -1 +1,91 @@
|
||||
node_modules
|
||||
|
||||
# Created by https://www.gitignore.io/api/node
|
||||
# Edit at https://www.gitignore.io/?templates=node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# End of https://www.gitignore.io/api/node
|
||||
@@ -1,16 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Connector {
|
||||
constructor(socket, app) {
|
||||
constructor(socket,
|
||||
// @ts-ignore
|
||||
app) {
|
||||
this.socket = socket;
|
||||
this.app = app;
|
||||
}
|
||||
on(key, javaScriptCode) {
|
||||
this.socket.on(key, (...args) => {
|
||||
const id = args.pop();
|
||||
javaScriptCode(args, (data) => {
|
||||
this.socket.emit(`${key}Complete${id}`, data);
|
||||
});
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"connector.js","sourceRoot":"","sources":["connector.ts"],"names":[],"mappings":";;AAAA,MAAa,SAAS;IAClB,YAAoB,MAAuB,EAAS,GAAiB;QAAjD,WAAM,GAAN,MAAM,CAAiB;QAAS,QAAG,GAAH,GAAG,CAAc;IAAI,CAAC;IAE1E,EAAE,CAAC,GAAW,EAAE,cAAwB;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACnC,MAAM,EAAE,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;YAE9B,cAAc,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AAZD,8BAYC"}
|
||||
{"version":3,"file":"connector.js","sourceRoot":"","sources":["connector.ts"],"names":[],"mappings":";;AAAA,MAAa,SAAS;IAClB,YAAoB,MAAuB;IACvC,aAAa;IACN,GAAiB;QAFR,WAAM,GAAN,MAAM,CAAiB;QAEhC,QAAG,GAAH,GAAG,CAAc;IAAI,CAAC;IAEjC,EAAE,CAAC,GAAW,EAAE,cAAwB;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACnC,MAAM,EAAE,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;YAE9B,IAAI;gBACA,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC7B,IAAI,IAAI,EAAE;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;qBACjD;gBACL,CAAC,CAAC,CAAC;aACN;YAAC,OAAO,KAAK,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC;aACtE;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AApBD,8BAoBC"}
|
||||
@@ -1,13 +1,21 @@
|
||||
export class Connector {
|
||||
constructor(private socket: SocketIO.Socket, public app: Electron.App) { }
|
||||
constructor(private socket: SocketIO.Socket,
|
||||
// @ts-ignore
|
||||
public app: Electron.App) { }
|
||||
|
||||
on(key: string, javaScriptCode: Function): void {
|
||||
this.socket.on(key, (...args: any[]) => {
|
||||
const id: string = args.pop();
|
||||
|
||||
javaScriptCode(args, (data) => {
|
||||
this.socket.emit(`${key}Complete${id}`, data);
|
||||
});
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ class ExcelCreator {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const workbook = new Excel.Workbook();
|
||||
const worksheet = workbook.addWorksheet("My Sheet");
|
||||
// worksheet.columns = [
|
||||
// { header: "Id", key: "id", width: 10 },
|
||||
// { header: "Name", key: "name", width: 32 },
|
||||
// { header: "D.O.B.", key: "DOB", width: 10, outlineLevel: 1 }
|
||||
// ];
|
||||
worksheet.addRow({ id: 1, name: "John Doe", dob: new Date(1970, 1, 1) });
|
||||
worksheet.addRow({ id: 2, name: "Jane Doe", dob: new Date(1965, 1, 7) });
|
||||
yield workbook.xlsx.writeFile(path + "sample.xlsx");
|
||||
worksheet.columns = [
|
||||
{ header: "Id", key: "id", width: 10 },
|
||||
{ header: "Name", key: "name", width: 32 },
|
||||
{ header: "Birthday", key: "birthday", width: 10, outlineLevel: 1 }
|
||||
];
|
||||
worksheet.addRow({ id: 1, name: "John Doe", birthday: new Date(1970, 1, 1) });
|
||||
worksheet.addRow({ id: 2, name: "Jane Doe", birthday: new Date(1965, 1, 7) });
|
||||
yield workbook.xlsx.writeFile(path + "\\sample.xlsx");
|
||||
return "finish";
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"excelCreator.js","sourceRoot":"","sources":["excelCreator.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,iCAAiC;AAGjC,MAAa,YAAY;IACf,MAAM,CAAC,IAAY;;YACrB,MAAM,QAAQ,GAAa,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAChD,MAAM,SAAS,GAAc,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAC/D,wBAAwB;YACxB,8CAA8C;YAC9C,kDAAkD;YAClD,mEAAmE;YACnE,KAAK;YACL,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACzE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAEzE,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,aAAa,CAAC,CAAC;YAEpD,OAAO,QAAQ,CAAC;QACpB,CAAC;KAAA;CACJ;AAhBD,oCAgBC"}
|
||||
{"version":3,"file":"excelCreator.js","sourceRoot":"","sources":["excelCreator.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,iCAAiC;AAGjC,MAAa,YAAY;IACf,MAAM,CAAC,IAAY;;YACrB,MAAM,QAAQ,GAAa,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAChD,MAAM,SAAS,GAAc,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAC/D,SAAS,CAAC,OAAO,GAAG;gBAChB,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;gBACtC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;gBAC1C,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE;aACtE,CAAC;YACF,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9E,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAE9E,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,eAAe,CAAC,CAAC;YAEtD,OAAO,QAAQ,CAAC;QACpB,CAAC;KAAA;CACJ;AAhBD,oCAgBC"}
|
||||
@@ -5,16 +5,16 @@ export class ExcelCreator {
|
||||
async create(path: string): Promise<string> {
|
||||
const workbook: Workbook = new Excel.Workbook();
|
||||
const worksheet: Worksheet = workbook.addWorksheet("My Sheet");
|
||||
// worksheet.columns = [
|
||||
// { header: "Id", key: "id", width: 10 },
|
||||
// { header: "Name", key: "name", width: 32 },
|
||||
// { header: "D.O.B.", key: "DOB", width: 10, outlineLevel: 1 }
|
||||
// ];
|
||||
worksheet.addRow({ id: 1, name: "John Doe", dob: new Date(1970, 1, 1) });
|
||||
worksheet.addRow({ id: 2, name: "Jane Doe", dob: new Date(1965, 1, 7) });
|
||||
worksheet.columns = [
|
||||
{ header: "Id", key: "id", width: 10 },
|
||||
{ header: "Name", key: "name", width: 32 },
|
||||
{ header: "Birthday", key: "birthday", width: 10, outlineLevel: 1 }
|
||||
];
|
||||
worksheet.addRow({ id: 1, name: "John Doe", birthday: new Date(1970, 1, 1) });
|
||||
worksheet.addRow({ id: 2, name: "Jane Doe", birthday: new Date(1965, 1, 7) });
|
||||
|
||||
await workbook.xlsx.writeFile(path + "sample.xlsx");
|
||||
await workbook.xlsx.writeFile(path + "\\sample.xlsx");
|
||||
|
||||
return "finish";
|
||||
return "Excel file created!";
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;AACA,2CAAwC;AACxC,iDAA8C;AAE9C,MAAa,WAAY,SAAQ,qBAAS;IACtC,YAAY,MAAuB,EAAS,GAAiB;QACzD,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QADqB,QAAG,GAAH,GAAG,CAAc;IAE7D,CAAC;IAED,WAAW;QACP,8CAA8C;QAE9C,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,CAAO,IAAI,EAAE,IAAI,EAAE,EAAE;YACzC,MAAM,YAAY,GAAiB,IAAI,2BAAY,EAAE,CAAC;YACtD,MAAM,MAAM,GAAW,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,CAAC;QACjB,CAAC,CAAA,CAAC,CAAC;IACP,CAAC;CACJ;AAfD,kCAeC"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,2CAAwC;AACxC,iDAA8C;AAE9C,MAAa,WAAY,SAAQ,qBAAS;IACtC,YAAY,MAAuB,EAAS,GAAiB;QACzD,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QADqB,QAAG,GAAH,GAAG,CAAc;IAE7D,CAAC;IAED,WAAW;QACP,8CAA8C;QAE9C,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,CAAO,IAAI,EAAE,IAAI,EAAE,EAAE;YACzC,MAAM,YAAY,GAAiB,IAAI,2BAAY,EAAE,CAAC;YACtD,MAAM,MAAM,GAAW,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,CAAC;QACjB,CAAC,CAAA,CAAC,CAAC;IACP,CAAC;CACJ;AAfD,kCAeC"}
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-ignore
|
||||
import * as Electron from "electron";
|
||||
import { Connector } from "./connector";
|
||||
import { ExcelCreator } from "./excelCreator";
|
||||
@@ -9,8 +10,7 @@ export class HookService extends Connector {
|
||||
|
||||
onHostReady(): void {
|
||||
// execute your own JavaScript Host logic here
|
||||
|
||||
this.on("create-excel", async (path, done) => {
|
||||
this.on("create-excel-file", async (path, done) => {
|
||||
const excelCreator: ExcelCreator = new ExcelCreator();
|
||||
const result: string = await excelCreator.create(path);
|
||||
|
||||
|
||||
1711
ElectronNET.WebApp/ElectronHostHook/package-lock.json
generated
1711
ElectronNET.WebApp/ElectronHostHook/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,22 @@
|
||||
{
|
||||
"name": "electron-host-hook",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"description": "Connector for Electron.NET projects.",
|
||||
"repository": {
|
||||
"url": "https://github.com/ElectronNET/Electron.NET"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"author": "Gregor Biswanger",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/electron": "^1.6.10",
|
||||
"@types/exceljs": "^0.5.2",
|
||||
"@types/socket.io": "^2.1.2"
|
||||
"@types/socket.io": "^2.1.2",
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"exceljs": "^1.6.3"
|
||||
"exceljs": "^1.10.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
|
||||
@@ -11,22 +10,6 @@
|
||||
<ItemGroup>
|
||||
<Content Remove="Views\Windows\HandleErrorCrashes.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="ElectronHostHook\connector.ts" />
|
||||
<None Remove="ElectronHostHook\excelCreator.ts" />
|
||||
<None Remove="ElectronHostHook\index.ts" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="ElectronHostHook\connector.ts">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="ElectronHostHook\excelCreator.ts">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="ElectronHostHook\index.ts">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Assets\" />
|
||||
<Folder Include="wwwroot\assets\" />
|
||||
@@ -35,9 +18,6 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
@@ -57,4 +37,9 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="ElectronHostHook\**\*.*">
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -22,6 +22,7 @@
|
||||
<link rel="import" href="dialogs">
|
||||
<link rel="import" href="tray">
|
||||
<link rel="import" href="ipc">
|
||||
<link rel="import" href="hosthook">
|
||||
<link rel="import" href="appsysinformation">
|
||||
<link rel="import" href="clipboard">
|
||||
<link rel="import" href="pdf">
|
||||
@@ -69,6 +70,7 @@
|
||||
Communication
|
||||
</h5>
|
||||
<button type="button" id="button-ipc" data-section="ipc" class="nav-button">Communicate between the <em>two processes</em></button>
|
||||
<button type="button" id="button-hosthook" data-section="hosthook" class="nav-button">Execute your own <em>TypeScript code</em></button>
|
||||
</div>
|
||||
|
||||
<div class="nav-item u-category-system">
|
||||
|
||||
95
ElectronNET.WebApp/Views/HostHook/Index.cshtml
Normal file
95
ElectronNET.WebApp/Views/HostHook/Index.cshtml
Normal file
@@ -0,0 +1,95 @@
|
||||
<template class="task-template">
|
||||
<section id="hosthook-section" class="section js-section u-category-communication">
|
||||
<header class="communication">
|
||||
<div class="section-wrapper">
|
||||
<h1>
|
||||
<svg class="section-icon"><use xlink:href="assets/img/icons.svg#icon-communication"></use></svg>
|
||||
Execute your own TypeScript code
|
||||
</h1>
|
||||
<h3>The <code>HostHook</code> API allows you to execute your own JavaScript/TypeScript code on the host process.</h3>
|
||||
|
||||
<p>Create first an ElectronHostHook directory via the Electron.NET CLI, with the following command: <code>electronize add hosthook</code>.</p>
|
||||
<p>In this directory you can install any NPM packages and embed your own JavaScript/TypeScript code. It is also possible to respond to events from the host process.</p>
|
||||
<p>You find the sample source code in <code>Controllers\HostHookController.cs</code> and in the <code>ElectronHostHook</code> folder.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="demo">
|
||||
<div class="demo-wrapper">
|
||||
<button id="async-msg-demo-toggle" class="js-container-target demo-toggle-button">
|
||||
Execute TypeScript code
|
||||
<div class="demo-meta u-avoid-clicks">Supports: Win, macOS, Linux <span class="demo-meta-divider">|</span> Process: Main</div>
|
||||
</button>
|
||||
<div class="demo-box">
|
||||
<div class="demo-controls">
|
||||
<button class="demo-button" id="start-hoosthook-button">Create Excel-File</button>
|
||||
<span class="demo-response" id="hoosthook-reply"></span>
|
||||
</div>
|
||||
<p>Use <code>Electron.HostHook.CallAsync</code> to execute asynchronously your own JavaScript/TypeScript code, that expect a result value.</p>
|
||||
|
||||
<p>This example execute the TypeScript code, that listening on "create-excel". The TypeScript code use a NPM Package names exceljs, to create a Excel file and reply a success message.</p>
|
||||
|
||||
<h5>Main Process (C#)</h5>
|
||||
<pre><code class="csharp">
|
||||
Electron.IpcMain.On("start-hoosthook", async (args) =>
|
||||
{
|
||||
var mainWindow = Electron.WindowManager.BrowserWindows.First();
|
||||
var options = new OpenDialogOptions
|
||||
{
|
||||
Properties = new OpenDialogProperty[]
|
||||
{
|
||||
OpenDialogProperty.openDirectory
|
||||
}
|
||||
};
|
||||
var folderPath = await Electron.Dialog.ShowOpenDialogAsync(mainWindow, options);
|
||||
|
||||
var resultFromTypeScript = await Electron.HostHook.CallAsync<string>("create-excel-file", folderPath);
|
||||
Electron.IpcMain.Send(mainWindow, "excel-file-created", resultFromTypeScript);
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
<h5>index.ts from ElectronHostHook-Folder (TypeScript)</h5>
|
||||
<pre>
|
||||
<code class="typescript">
|
||||
import * as Electron from "electron";
|
||||
import { Connector } from "./connector";
|
||||
import { ExcelCreator } from "./excelCreator";
|
||||
|
||||
export class HookService extends Connector {
|
||||
constructor(socket: SocketIO.Socket, public app: Electron.App) {
|
||||
super(socket, app);
|
||||
}
|
||||
|
||||
onHostReady(): void {
|
||||
// execute your own JavaScript Host logic here
|
||||
this.on("create-excel", async (path, done) => {
|
||||
const excelCreator: ExcelCreator = new ExcelCreator();
|
||||
const result: string = await excelCreator.create(path);
|
||||
|
||||
done(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
const { ipcRenderer } = require("electron");
|
||||
|
||||
document.getElementById("start-hoosthook-button").addEventListener("click", () => {
|
||||
ipcRenderer.send("start-hoosthook");
|
||||
});
|
||||
|
||||
ipcRenderer.on('excel-file-created', (event, arg) => {
|
||||
const message = `Asynchronous message reply: ${arg}`;
|
||||
document.getElementById('hoosthook-reply').innerHTML = message;
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user