From f6d17406cd8d19a2af8095421a199edc6ed1a181 Mon Sep 17 00:00:00 2001 From: Florian Rappl Date: Tue, 4 Apr 2023 14:31:25 +0200 Subject: [PATCH] Cleanup and improvements --- .../Commands/Actions/DirectoryCopy.cs | 30 ++++--- .../Actions/GetTargetPlatformInformation.cs | 7 +- src/ElectronNET.CLI/Commands/AddCommand.cs | 27 ++++--- src/ElectronNET.CLI/Commands/BuildCommand.cs | 79 ++++++++----------- src/ElectronNET.CLI/Commands/CommandOption.cs | 3 + src/ElectronNET.CLI/Commands/InitCommand.cs | 71 +++++++++-------- .../Commands/StartElectronCommand.cs | 66 ++++++---------- src/ElectronNET.CLI/ElectronNET.CLI.csproj | 5 +- src/ElectronNET.CLI/ProcessHelper.cs | 26 ++++++ src/ElectronNET.Host/src/build-helper.ts | 7 +- src/ElectronNET.Host/src/main.ts | 22 +++++- src/ElectronNET.Host/tsconfig.json | 20 +++-- src/ElectronNET.HostHook/.gitignore | 1 - .../{src/connector.ts => index.ts} | 14 ++-- src/ElectronNET.HostHook/package.json | 4 +- src/ElectronNET.HostHook/src/index.ts | 13 --- src/ElectronNET.HostHook/tsconfig.json | 18 ++--- 17 files changed, 214 insertions(+), 199 deletions(-) rename src/ElectronNET.HostHook/{src/connector.ts => index.ts} (60%) delete mode 100644 src/ElectronNET.HostHook/src/index.ts diff --git a/src/ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs b/src/ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs index 39ded69..622646b 100644 --- a/src/ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs +++ b/src/ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs @@ -8,16 +8,15 @@ namespace ElectronNET.CLI.Commands.Actions public static void Do(string sourceDirName, string destDirName, bool copySubDirs, List ignoredSubDirs) { // Get the subdirectories for the specified directory. - DirectoryInfo dir = new DirectoryInfo(sourceDirName); + var dir = new DirectoryInfo(sourceDirName); if (!dir.Exists) { - throw new DirectoryNotFoundException( - "Source directory does not exist or could not be found: " - + sourceDirName); + throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName); } - DirectoryInfo[] dirs = dir.GetDirectories(); + var dirs = dir.GetDirectories(); + // If the destination directory doesn't exist, create it. if (!Directory.Exists(destDirName)) { @@ -25,40 +24,39 @@ namespace ElectronNET.CLI.Commands.Actions } else { - DirectoryInfo targetDir = new DirectoryInfo(destDirName); + var targetDir = new DirectoryInfo(destDirName); - foreach (FileInfo fileDel in targetDir.EnumerateFiles()) + foreach (var fileDel in targetDir.EnumerateFiles()) { fileDel.Delete(); } - foreach (DirectoryInfo dirDel in targetDir.EnumerateDirectories()) + + foreach (var 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) + var files = dir.GetFiles(); + + foreach (var file in files) { - string temppath = Path.Combine(destDirName, file.Name); + var 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) + foreach (var subdir in dirs) { if (ignoredSubDirs.Contains(subdir.Name)) { continue; } - string temppath = Path.Combine(destDirName, subdir.Name); + var temppath = Path.Combine(destDirName, subdir.Name); Do(subdir.FullName, temppath, copySubDirs, ignoredSubDirs); } } diff --git a/src/ElectronNET.CLI/Commands/Actions/GetTargetPlatformInformation.cs b/src/ElectronNET.CLI/Commands/Actions/GetTargetPlatformInformation.cs index a12d427..66a17a5 100644 --- a/src/ElectronNET.CLI/Commands/Actions/GetTargetPlatformInformation.cs +++ b/src/ElectronNET.CLI/Commands/Actions/GetTargetPlatformInformation.cs @@ -9,13 +9,12 @@ namespace ElectronNET.CLI.Commands.Actions { public string NetCorePublishRid { get; set; } public string ElectronPackerPlatform { get; set; } - } public static GetTargetPlatformInformationResult Do(string desiredPlatform, string specifiedPlatfromFromCustom) { - string netCorePublishRid = string.Empty; - string electronPackerPlatform = string.Empty; + var netCorePublishRid = string.Empty; + var electronPackerPlatform = string.Empty; switch (desiredPlatform) { @@ -60,7 +59,7 @@ namespace ElectronNET.CLI.Commands.Actions break; } - return new GetTargetPlatformInformationResult() + return new GetTargetPlatformInformationResult { ElectronPackerPlatform = electronPackerPlatform, NetCorePublishRid = netCorePublishRid diff --git a/src/ElectronNET.CLI/Commands/AddCommand.cs b/src/ElectronNET.CLI/Commands/AddCommand.cs index 8ef821f..2c4be74 100644 --- a/src/ElectronNET.CLI/Commands/AddCommand.cs +++ b/src/ElectronNET.CLI/Commands/AddCommand.cs @@ -15,7 +15,6 @@ namespace ElectronNET.CLI.Commands public const string COMMAND_ARGUMENTS = "hosthook"; public static IList CommandOptions { get; set; } = new List(); - private string[] _args; public AddCommand(string[] args) @@ -41,15 +40,21 @@ namespace ElectronNET.CLI.Commands // Maybe ToDo: Adding the possiblity to specify a path (like we did in the InitCommand, but this would require a better command args parser) var currentDirectory = Directory.GetCurrentDirectory(); - var hostDistFolder = Path.Combine(currentDirectory, "dist"); + var hostFolder = Path.Combine(currentDirectory, "ElectronHostHook"); - if (!Directory.Exists(hostDistFolder)) + if (!Directory.Exists(hostFolder)) { - Directory.CreateDirectory(hostDistFolder); + Directory.CreateDirectory(hostFolder); } // Deploy related files - EmbeddedFileHelper.DeployEmbeddedFile(hostDistFolder, "host-hook.js", "dist."); + EmbeddedFileHelper.DeployEmbeddedFile(hostFolder, "package.json", "hook."); + EmbeddedFileHelper.DeployEmbeddedFile(hostFolder, "tsconfig.json", "hook."); + EmbeddedFileHelper.DeployEmbeddedFile(hostFolder, ".gitignore", "hook."); + EmbeddedFileHelper.DeployEmbeddedFile(hostFolder, "index.ts", "hook."); + + Console.WriteLine($"Installing the dependencies ..."); + ProcessHelper.CheckNodeModules(hostFolder); // search .csproj or .fsproj (.csproj has higher precedence) Console.WriteLine($"Search your .csproj/.fsproj to add configure CopyToPublishDirectory to 'Never'"); @@ -82,16 +87,15 @@ namespace ElectronNET.CLI.Commands 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}"); + Console.WriteLine($"Project file is not a compatible type of 'Microsoft.NET.Sdk.Web'. Your project: {projectElement?.Attribute("Sdk")?.Value}"); return false; } var itemGroupXmlString = "" + - "" + - "Never" + - "" + - ""; + "" + + "Never" + + "" + + ""; var newItemGroupForConfig = XElement.Parse(itemGroupXmlString); xmlDocument.Root.Add(newItemGroupForConfig); @@ -109,7 +113,6 @@ namespace ElectronNET.CLI.Commands { xmlDocument.Save(xw); } - } Console.WriteLine($"Publish setting added in csproj/fsproj!"); diff --git a/src/ElectronNET.CLI/Commands/BuildCommand.cs b/src/ElectronNET.CLI/Commands/BuildCommand.cs index 2f4f52c..eded479 100644 --- a/src/ElectronNET.CLI/Commands/BuildCommand.cs +++ b/src/ElectronNET.CLI/Commands/BuildCommand.cs @@ -51,15 +51,18 @@ namespace ElectronNET.CLI.Commands { return Task.Run(() => { - Console.WriteLine("Build Electron Application..."); + var parser = new SimpleCommandLineParser(); - SimpleCommandLineParser parser = new SimpleCommandLineParser(); + Console.WriteLine("Build Electron Application..."); parser.Parse(_args); //This version will be shared between the dotnet publish and electron-builder commands - string version = null; + var version = string.Empty; + if (parser.Arguments.ContainsKey(_paramVersion)) + { version = parser.Arguments[_paramVersion][0]; + } if (!parser.Arguments.ContainsKey(_paramTarget)) { @@ -69,23 +72,24 @@ namespace ElectronNET.CLI.Commands } var desiredPlatform = parser.Arguments[_paramTarget][0]; - string specifiedFromCustom = string.Empty; + var specifiedFromCustom = string.Empty; + if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1) { specifiedFromCustom = parser.Arguments[_paramTarget][1]; } - string configuration = "Release"; + var configuration = "Release"; + if (parser.Arguments.ContainsKey(_paramDotNetConfig)) { configuration = parser.Arguments[_paramDotNetConfig][0]; } var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom); - Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}..."); - string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform); + var tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform); if (Directory.Exists(tempPath) == false) { @@ -97,17 +101,13 @@ namespace ElectronNET.CLI.Commands Directory.CreateDirectory(tempPath); } - Console.WriteLine("Executing dotnet publish in this directory: " + tempPath); - string tempBinPath = Path.Combine(tempPath, "bin"); + var tempBinPath = Path.Combine(tempPath, "bin"); + Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration..."); - Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration..."); - var dotNetPublishFlags = GetDotNetPublishFlags(parser); - - var command = - $"dotnet publish -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))} --self-contained"; + var command = $"dotnet publish -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))} --self-contained"; // output the command Console.ForegroundColor = ConsoleColor.Green; @@ -132,33 +132,16 @@ namespace ElectronNET.CLI.Commands File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true); } - var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules"); - - if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson)) - - Console.WriteLine("Start npm install..."); - ProcessHelper.CmdExecute("npm install --production", tempPath); + ProcessHelper.CheckNodeModules(tempPath, parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson)); 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() { "node_modules" }); - - Console.WriteLine("Start npm install for hosthooks..."); - ProcessHelper.CmdExecute("npm install", hosthookDir); - - // ToDo: Not sure if this runs under linux/macos - ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir); - } + ProcessHelper.BundleHostHook(tempPath); Console.WriteLine("Build Electron Desktop Application..."); // Specifying an absolute path supercedes a relative path - string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop"); + var buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop"); + if (parser.Arguments.ContainsKey(_paramAbsoluteOutput)) { buildPath = parser.Arguments[_paramAbsoluteOutput][0]; @@ -170,13 +153,15 @@ namespace ElectronNET.CLI.Commands Console.WriteLine("Executing electron magic in this directory: " + buildPath); - string electronArch = "x64"; + var electronArch = "x64"; + if (parser.Arguments.ContainsKey(_paramElectronArch)) { electronArch = parser.Arguments[_paramElectronArch][0]; } - string electronParams = ""; + var electronParams = string.Empty; + if (parser.Arguments.ContainsKey(_paramElectronParams)) { electronParams = parser.Arguments[_paramElectronParams][0]; @@ -185,7 +170,7 @@ namespace ElectronNET.CLI.Commands // ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :) Console.WriteLine("Create electron-builder configuration file..."); - string manifestFileName = "electron.manifest.json"; + var manifestFileName = "electron.manifest.json"; if (parser.Arguments.ContainsKey(_manifest)) { @@ -194,14 +179,13 @@ namespace ElectronNET.CLI.Commands ProcessHelper.CmdExecute( string.IsNullOrWhiteSpace(version) - ? $"node build-helper.js {manifestFileName}" - : $"node build-helper.js {manifestFileName} {version}", tempPath); + ? $"node dist/build-helper.js {manifestFileName}" + : $"node dist/build-helper.js {manifestFileName} {version}", tempPath); - Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}..."); + Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform} ..."); ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=23.2.0 {electronParams}", tempPath); Console.WriteLine("... done"); - return true; }); } @@ -216,21 +200,28 @@ namespace ElectronNET.CLI.Commands if (parser.Arguments.ContainsKey(_paramVersion)) { - if(parser.Arguments.Keys.All(key => !key.StartsWith("p:Version=") && !key.StartsWith("property:Version="))) + if (parser.Arguments.Keys.All(key => !key.StartsWith("p:Version=") && !key.StartsWith("property:Version="))) + { dotNetPublishFlags.Add("/p:Version", parser.Arguments[_paramVersion][0]); - if(parser.Arguments.Keys.All(key => !key.StartsWith("p:ProductVersion=") && !key.StartsWith("property:ProductVersion="))) + } + + if (parser.Arguments.Keys.All(key => !key.StartsWith("p:ProductVersion=") && !key.StartsWith("property:ProductVersion="))) + { dotNetPublishFlags.Add("/p:ProductVersion", parser.Arguments[_paramVersion][0]); + } } foreach (var parm in parser.Arguments.Keys.Where(key => key.StartsWith("p:") || key.StartsWith("property:"))) { var split = parm.IndexOf('='); + if (split < 0) { continue; } var key = $"/{parm.Substring(0, split)}"; + // normalize the key if (key.StartsWith("/property:")) { diff --git a/src/ElectronNET.CLI/Commands/CommandOption.cs b/src/ElectronNET.CLI/Commands/CommandOption.cs index 675f571..7ff44bd 100644 --- a/src/ElectronNET.CLI/Commands/CommandOption.cs +++ b/src/ElectronNET.CLI/Commands/CommandOption.cs @@ -43,8 +43,11 @@ get { var key = this.Switch; + if (key.StartsWith("--")) + { key = key.Substring(2); + } return key; } diff --git a/src/ElectronNET.CLI/Commands/InitCommand.cs b/src/ElectronNET.CLI/Commands/InitCommand.cs index c253920..ca68592 100644 --- a/src/ElectronNET.CLI/Commands/InitCommand.cs +++ b/src/ElectronNET.CLI/Commands/InitCommand.cs @@ -32,11 +32,12 @@ namespace ElectronNET.CLI.Commands { return Task.Run(() => { - string aspCoreProjectPath = ""; + var aspCoreProjectPath = ""; if (_parser.Arguments.ContainsKey(_aspCoreProjectPath)) { - string projectPath = _parser.Arguments[_aspCoreProjectPath].First(); + var projectPath = _parser.Arguments[_aspCoreProjectPath].First(); + if (Directory.Exists(projectPath)) { aspCoreProjectPath = projectPath; @@ -49,7 +50,7 @@ namespace ElectronNET.CLI.Commands var currentDirectory = aspCoreProjectPath; - if(_parser.Arguments.ContainsKey(_manifest)) + if (_parser.Arguments.ContainsKey(_manifest)) { ConfigName = "electron.manifest." + _parser.Arguments[_manifest].First() + ".json"; Console.WriteLine($"Adding your custom {ConfigName} config file to your project..."); @@ -72,20 +73,26 @@ namespace ElectronNET.CLI.Commands // search .csproj/.fsproj (.csproj has higher precedence) Console.WriteLine($"Search your .csproj/fsproj to add the needed {ConfigName}..."); + var projectFile = Directory.EnumerateFiles(currentDirectory, "*.csproj", SearchOption.TopDirectoryOnly) .Union(Directory.EnumerateFiles(currentDirectory, "*.fsproj", SearchOption.TopDirectoryOnly)) .FirstOrDefault(); // update config file with the name of the csproj/fsproj // ToDo: If the csproj/fsproj name != application name, this will fail - string text = File.ReadAllText(targetFilePath); - text = text.Replace("{{executable}}", Path.GetFileNameWithoutExtension(projectFile)); + var text = File + .ReadAllText(targetFilePath) + .Replace("{{executable}}", Path.GetFileNameWithoutExtension(projectFile)); + File.WriteAllText(targetFilePath, text); var extension = Path.GetExtension(projectFile); Console.WriteLine($"Found your {extension}: {projectFile} - check for existing config or update it."); - if (!EditProjectFile(projectFile)) return false; + if (!EditProjectFile(projectFile)) + { + return false; + } // search launchSettings.json Console.WriteLine($"Search your .launchSettings to add our electron debug profile..."); @@ -112,22 +119,22 @@ namespace ElectronNET.CLI.Commands return; } - string launchSettingText = File.ReadAllText(launchSettingFile); + var launchSettingText = File.ReadAllText(launchSettingFile); if(_parser.Arguments.ContainsKey(_manifest)) { - string manifestName = _parser.Arguments[_manifest].First(); + var manifestName = _parser.Arguments[_manifest].First(); - if(launchSettingText.Contains("start /manifest " + ConfigName) == false) + if (launchSettingText.Contains("start /manifest " + ConfigName) == false) { - StringBuilder debugProfileBuilder = new StringBuilder(); - debugProfileBuilder.AppendLine("profiles\": {"); - debugProfileBuilder.AppendLine(" \"Electron.NET App - " + manifestName + "\": {"); - debugProfileBuilder.AppendLine(" \"commandName\": \"Executable\","); - debugProfileBuilder.AppendLine(" \"executablePath\": \"electronize\","); - debugProfileBuilder.AppendLine(" \"commandLineArgs\": \"start /manifest " + ConfigName + "\","); - debugProfileBuilder.AppendLine(" \"workingDirectory\": \".\""); - debugProfileBuilder.AppendLine(" },"); + var debugProfileBuilder = new StringBuilder() + .AppendLine("profiles\": {") + .AppendLine(" \"Electron.NET App - " + manifestName + "\": {") + .AppendLine(" \"commandName\": \"Executable\",") + .AppendLine(" \"executablePath\": \"electronize\",") + .AppendLine(" \"commandLineArgs\": \"start /manifest " + ConfigName + "\",") + .AppendLine(" \"workingDirectory\": \".\"") + .AppendLine(" },"); launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString()); File.WriteAllText(launchSettingFile, launchSettingText); @@ -141,14 +148,14 @@ namespace ElectronNET.CLI.Commands } else if (launchSettingText.Contains("\"executablePath\": \"electronize\"") == false) { - StringBuilder debugProfileBuilder = new StringBuilder(); - debugProfileBuilder.AppendLine("profiles\": {"); - debugProfileBuilder.AppendLine(" \"Electron.NET App\": {"); - debugProfileBuilder.AppendLine(" \"commandName\": \"Executable\","); - debugProfileBuilder.AppendLine(" \"executablePath\": \"electronize\","); - debugProfileBuilder.AppendLine(" \"commandLineArgs\": \"start\","); - debugProfileBuilder.AppendLine(" \"workingDirectory\": \".\""); - debugProfileBuilder.AppendLine(" },"); + var debugProfileBuilder = new StringBuilder() + .AppendLine("profiles\": {") + .AppendLine(" \"Electron.NET App\": {") + .AppendLine(" \"commandName\": \"Executable\",") + .AppendLine(" \"executablePath\": \"electronize\",") + .AppendLine(" \"commandLineArgs\": \"start\",") + .AppendLine(" \"workingDirectory\": \".\"") + .AppendLine(" },"); launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString()); File.WriteAllText(launchSettingFile, launchSettingText); @@ -166,8 +173,8 @@ namespace ElectronNET.CLI.Commands 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( @@ -183,11 +190,11 @@ namespace ElectronNET.CLI.Commands Console.WriteLine($"{ConfigName} will be added to csproj/fsproj."); - string itemGroupXmlString = "" + - "" + - "PreserveNewest" + - "" + - ""; + var itemGroupXmlString = "" + + "" + + "PreserveNewest" + + "" + + ""; var newItemGroupForConfig = XElement.Parse(itemGroupXmlString); xmlDocument.Root.Add(newItemGroupForConfig); @@ -200,11 +207,11 @@ namespace ElectronNET.CLI.Commands OmitXmlDeclaration = true, Indent = true }; + using (XmlWriter xw = XmlWriter.Create(stream, xws)) { xmlDocument.Save(xw); } - } Console.WriteLine($"{ConfigName} added in csproj/fsproj!"); diff --git a/src/ElectronNET.CLI/Commands/StartElectronCommand.cs b/src/ElectronNET.CLI/Commands/StartElectronCommand.cs index 03382ec..fbe828f 100644 --- a/src/ElectronNET.CLI/Commands/StartElectronCommand.cs +++ b/src/ElectronNET.CLI/Commands/StartElectronCommand.cs @@ -35,16 +35,16 @@ namespace ElectronNET.CLI.Commands { return Task.Run(() => { - Console.WriteLine("Start Electron Desktop Application..."); + var parser = new SimpleCommandLineParser(); + var aspCoreProjectPath = string.Empty; - SimpleCommandLineParser parser = new SimpleCommandLineParser(); + Console.WriteLine("Start Electron Desktop Application ..."); parser.Parse(_args); - string aspCoreProjectPath = ""; - if (parser.Arguments.ContainsKey(_aspCoreProjectPath)) { - string projectPath = parser.Arguments[_aspCoreProjectPath].First(); + var projectPath = parser.Arguments[_aspCoreProjectPath].First(); + if (Directory.Exists(projectPath)) { aspCoreProjectPath = projectPath; @@ -55,16 +55,17 @@ namespace ElectronNET.CLI.Commands aspCoreProjectPath = Directory.GetCurrentDirectory(); } - string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host"); - if (Directory.Exists(tempPath) == false) + var tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host"); + + if (!Directory.Exists(tempPath)) { Directory.CreateDirectory(tempPath); } - string tempBinPath = Path.Combine(tempPath, "bin"); + var tempBinPath = Path.Combine(tempPath, "bin"); var resultCode = 0; + var publishReadyToRun = "/p:PublishReadyToRun="; - string publishReadyToRun = "/p:PublishReadyToRun="; if (parser.Arguments.ContainsKey(_paramPublishReadyToRun)) { publishReadyToRun += parser.Arguments[_paramPublishReadyToRun][0]; @@ -74,7 +75,8 @@ namespace ElectronNET.CLI.Commands publishReadyToRun += "true"; } - string publishSingleFile = "/p:PublishSingleFile="; + var publishSingleFile = "/p:PublishSingleFile="; + if (parser.Arguments.ContainsKey(_paramPublishSingleFile)) { publishSingleFile += parser.Arguments[_paramPublishSingleFile][0]; @@ -88,18 +90,22 @@ namespace ElectronNET.CLI.Commands // Format is the same as the build command. // If target is not specified, autodetect it. var platformInfo = GetTargetPlatformInformation.Do(string.Empty, string.Empty); + if (parser.Arguments.ContainsKey(_paramTarget)) { var desiredPlatform = parser.Arguments[_paramTarget][0]; - string specifiedFromCustom = string.Empty; + var specifiedFromCustom = string.Empty; + if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1) { specifiedFromCustom = parser.Arguments[_paramTarget][1]; } + platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom); } - string configuration = "Debug"; + var configuration = "Debug"; + if (parser.Arguments.ContainsKey(_paramDotNetConfig)) { configuration = parser.Arguments[_paramDotNetConfig][0]; @@ -117,31 +123,12 @@ namespace ElectronNET.CLI.Commands } DeployEmbeddedElectronFiles.Do(tempPath); + ProcessHelper.CheckNodeModules(tempPath); - var nodeModulesDirPath = Path.Combine(tempPath, "node_modules"); + Console.WriteLine("ElectronHostHook handling started ..."); + ProcessHelper.BundleHostHook(tempPath); - Console.WriteLine("node_modules missing in: " + nodeModulesDirPath); - - 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)) - { - string hosthookDir = Path.Combine(tempPath, "ElectronHostHook"); - DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List() { "node_modules" }); - - Console.WriteLine("Start npm install for typescript & hosthooks..."); - ProcessHelper.CmdExecute("npm install", hosthookDir); - - // ToDo: Not sure if this runs under linux/macos - ProcessHelper.CmdExecute(@"npx tsc -p ../../ElectronHostHook", tempPath); - } - - string arguments = ""; + var arguments = string.Empty; if (parser.Arguments.ContainsKey(_arguments)) { @@ -163,19 +150,18 @@ namespace ElectronNET.CLI.Commands arguments += " --watch=true"; } - string path = Path.Combine(tempPath, "node_modules", ".bin"); - bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + var path = Path.Combine(tempPath, "node_modules", ".bin"); + var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); if (isWindows) { Console.WriteLine("Invoke electron.cmd - in dir: " + path); - ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path); - + ProcessHelper.CmdExecute(@"electron.cmd ""..\..\dist\main.js"" " + arguments, path); } else { Console.WriteLine("Invoke electron - in dir: " + path); - ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path); + ProcessHelper.CmdExecute(@"./electron ""../../dist/main.js"" " + arguments, path); } return true; diff --git a/src/ElectronNET.CLI/ElectronNET.CLI.csproj b/src/ElectronNET.CLI/ElectronNET.CLI.csproj index 38a40a1..c4d12cc 100644 --- a/src/ElectronNET.CLI/ElectronNET.CLI.csproj +++ b/src/ElectronNET.CLI/ElectronNET.CLI.csproj @@ -43,10 +43,13 @@ - + + + + diff --git a/src/ElectronNET.CLI/ProcessHelper.cs b/src/ElectronNET.CLI/ProcessHelper.cs index 9e0048f..0cd5d0a 100644 --- a/src/ElectronNET.CLI/ProcessHelper.cs +++ b/src/ElectronNET.CLI/ProcessHelper.cs @@ -1,11 +1,37 @@ using System; using System.Diagnostics; +using System.IO; using System.Runtime.InteropServices; namespace ElectronNET.CLI { public class ProcessHelper { + public static void CheckNodeModules(string tempPath, bool force = false) + { + var nodeModulesDirPath = Path.Combine(tempPath, "node_modules"); + + if (!Directory.Exists(nodeModulesDirPath) || force) + { + Console.WriteLine("Starting npm install ..."); + ProcessHelper.CmdExecute("npm install", tempPath); + } + } + + public static void BundleHostHook(string tempPath) + { + var electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook"); + + if (Directory.Exists(electronhosthookDir)) + { + // TODO: should be more complex, i.e., look at package.json, determine "source" or "main" and resolve it + var hookSource = Path.Combine(electronhosthookDir, "index.ts"); + var hookTarget = Path.Combine(tempPath, "dist", "host-hook.js"); + Console.WriteLine("Bundle ElectronHostHook ..."); + CmdExecute($"npm start --outfile={hookTarget}", electronhosthookDir); + } + } + public static int CmdExecute(string command, string workingDirectoryPath, bool output = true, bool waitForExit = true) { using (Process cmd = new Process()) diff --git a/src/ElectronNET.Host/src/build-helper.ts b/src/ElectronNET.Host/src/build-helper.ts index 846c8f7..2114a79 100644 --- a/src/ElectronNET.Host/src/build-helper.ts +++ b/src/ElectronNET.Host/src/build-helper.ts @@ -3,8 +3,9 @@ import { writeFile, existsSync } from "fs"; import { resolve } from "path"; const manifestFileName = process.argv[2]; +const cwd = process.cwd(); -const manifestFilePath = resolve(__dirname, ".bin", manifestFileName); +const manifestFilePath = resolve(cwd, ".bin", manifestFileName); const manifestFile = require(manifestFilePath); const builderConfiguration = { ...manifestFile.build }; @@ -19,7 +20,7 @@ if (process.argv.length > 3) { } if (builderConfiguration.hasOwnProperty("buildVersion")) { - const packageJsonPath = resolve(__dirname, "package.json"); + const packageJsonPath = resolve(cwd, "package.json"); const packageJson = require(packageJsonPath); packageJson.name = dasherize(manifestFile.name || "electron-net"); packageJson.author = manifestFile.author || ""; @@ -32,7 +33,7 @@ if (builderConfiguration.hasOwnProperty("buildVersion")) { logError ); - const packageLockJsonPath = resolve(__dirname, "package-lock.json"); + const packageLockJsonPath = resolve(cwd, "package-lock.json"); if (existsSync(packageLockJsonPath)) { const packageLockJson = require(packageLockJsonPath); diff --git a/src/ElectronNET.Host/src/main.ts b/src/ElectronNET.Host/src/main.ts index 779a1b5..9621c73 100644 --- a/src/ElectronNET.Host/src/main.ts +++ b/src/ElectronNET.Host/src/main.ts @@ -307,14 +307,28 @@ function startSocketApiBridge(port: number) { } }); - try { - if (isModuleAvailable(hostHookScriptFilePath) && hostHook === undefined) { + if (isModuleAvailable(hostHookScriptFilePath) && hostHook === undefined) { + try { const { HookService } = require(hostHookScriptFilePath); + + if (typeof HookService !== "function") { + throw new Error( + 'The host hook needs to export a class "HookService" from the module.' + ); + } + hostHook = new HookService(socket, app); + + if (typeof hostHook.onHostReady !== "function") { + throw new Error( + 'The exported host hook class needs to have a function "onHostReady".' + ); + } + hostHook.onHostReady(); + } catch (error) { + console.error(error.message); } - } catch (error) { - console.error(error.message); } }); } diff --git a/src/ElectronNET.Host/tsconfig.json b/src/ElectronNET.Host/tsconfig.json index 32c2b81..bfb5369 100644 --- a/src/ElectronNET.Host/tsconfig.json +++ b/src/ElectronNET.Host/tsconfig.json @@ -1,12 +1,10 @@ { - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "ES2019", - "sourceMap": true, - "skipLibCheck": true - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "target": "ES2020", + "sourceMap": true, + "skipLibCheck": true + }, + "exclude": ["node_modules"] +} diff --git a/src/ElectronNET.HostHook/.gitignore b/src/ElectronNET.HostHook/.gitignore index f06235c..3c3629e 100644 --- a/src/ElectronNET.HostHook/.gitignore +++ b/src/ElectronNET.HostHook/.gitignore @@ -1,2 +1 @@ node_modules -dist diff --git a/src/ElectronNET.HostHook/src/connector.ts b/src/ElectronNET.HostHook/index.ts similarity index 60% rename from src/ElectronNET.HostHook/src/connector.ts rename to src/ElectronNET.HostHook/index.ts index 8020d4b..604b708 100644 --- a/src/ElectronNET.HostHook/src/connector.ts +++ b/src/ElectronNET.HostHook/index.ts @@ -1,15 +1,15 @@ -import { Socket } from "socket.io"; import { App } from "electron"; +import { Socket } from "socket.io"; -export class Connector { +export class HookService { constructor(private socket: Socket, public app: App) {} - on(key: string, javaScriptCode: Function): void { - this.socket.on(key, (...args: any[]) => { + private on(key: string, cb: (...args: Array) => void): void { + this.socket.on(key, (...args: Array) => { const id: string = args.pop(); try { - javaScriptCode(...args, (data) => { + cb(...args, (data) => { if (data) { this.socket.emit(`${key}Complete${id}`, data); } @@ -19,4 +19,8 @@ export class Connector { } }); } + + onHostReady(): void { + // execute your own JavaScript Host logic here + } } diff --git a/src/ElectronNET.HostHook/package.json b/src/ElectronNET.HostHook/package.json index 2236d19..be6df0e 100644 --- a/src/ElectronNET.HostHook/package.json +++ b/src/ElectronNET.HostHook/package.json @@ -5,12 +5,10 @@ "repository": { "url": "https://github.com/ElectronNET/Electron.NET" }, - "main": "dist/index.js", "author": "Gregor Biswanger, Florian Rappl", "license": "MIT", "scripts": { - "start": "npm run build:main", - "build:main": "esbuild src/index.ts --external:electron --platform=node --target=es2020 --bundle --outfile=dist/host-hook.js" + "start": "esbuild index.ts --external:electron --platform=node --target=es2020 --bundle" }, "keywords": [], "devDependencies": { diff --git a/src/ElectronNET.HostHook/src/index.ts b/src/ElectronNET.HostHook/src/index.ts deleted file mode 100644 index 38d9d76..0000000 --- a/src/ElectronNET.HostHook/src/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { App } from "electron"; -import { Socket } from "socket.io"; -import { Connector } from "./connector"; - -export class HookService extends Connector { - constructor(socket: Socket, public app: App) { - super(socket, app); - } - - onHostReady(): void { - // execute your own JavaScript Host logic here - } -} diff --git a/src/ElectronNET.HostHook/tsconfig.json b/src/ElectronNET.HostHook/tsconfig.json index 01f4d55..d68c54f 100644 --- a/src/ElectronNET.HostHook/tsconfig.json +++ b/src/ElectronNET.HostHook/tsconfig.json @@ -1,11 +1,9 @@ { - "compilerOptions": { - "module": "commonjs", - "sourceMap": true, - "skipLibCheck": true, - "target": "es2015" - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "sourceMap": true, + "skipLibCheck": true, + "target": "es2020" + }, + "exclude": ["node_modules"] +}