Remove ElectronNET.CLI project

This commit is contained in:
softworkz
2025-10-13 13:06:50 +02:00
parent d6e39fef24
commit 14722e1f63
18 changed files with 0 additions and 1547 deletions

View File

@@ -1,54 +0,0 @@
using System.IO;
namespace ElectronNET.CLI.Commands.Actions
{
public static class DeployEmbeddedElectronFiles
{
public static void Do(string tempPath)
{
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "main.js");
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "package.json");
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "build-helper.js");
string vscodeFolder = Path.Combine(tempPath, ".vscode");
if (Directory.Exists(vscodeFolder) == false)
{
Directory.CreateDirectory(vscodeFolder);
}
EmbeddedFileHelper.DeployEmbeddedFile(vscodeFolder, "launch.json", ".vscode.");
EmbeddedFileHelper.DeployEmbeddedFile(vscodeFolder, "tasks.json", ".vscode.");
string hostApiFolder = Path.Combine(tempPath, "api");
if (Directory.Exists(hostApiFolder) == false)
{
Directory.CreateDirectory(hostApiFolder);
}
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "commandLine.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dock.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "tray.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "webContents.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "globalShortcut.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "shell.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "screen.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "clipboard.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "autoUpdater.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserView.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "powerMonitor.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "nativeTheme.js", "api.");
string splashscreenFolder = Path.Combine(tempPath, "splashscreen");
if (Directory.Exists(splashscreenFolder) == false)
{
Directory.CreateDirectory(splashscreenFolder);
}
EmbeddedFileHelper.DeployEmbeddedFile(splashscreenFolder, "index.html", "splashscreen.");
}
}
}

View File

@@ -1,67 +0,0 @@
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);
}
}
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace ElectronNET.CLI.Commands.Actions
{
public static class GetTargetPlatformInformation
{
public struct GetTargetPlatformInformationResult
{
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;
switch (desiredPlatform)
{
case "win":
netCorePublishRid = "win-x64";
electronPackerPlatform = "win";
break;
case "osx":
netCorePublishRid = "osx-x64";
electronPackerPlatform = "mac";
break;
case "linux":
netCorePublishRid = "linux-x64";
electronPackerPlatform = "linux";
break;
case "linux-arm":
netCorePublishRid = "linux-arm";
electronPackerPlatform = "linux";
break;
case "custom":
var splittedSpecified = specifiedPlatfromFromCustom.Split(';');
netCorePublishRid = splittedSpecified[0];
electronPackerPlatform = splittedSpecified[1];
break;
default:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
netCorePublishRid = $"win-x{(Environment.Is64BitOperatingSystem ? "64" : "86")}";
electronPackerPlatform = "win";
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
netCorePublishRid = RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ? "osx-arm64" : "osx-x64";
electronPackerPlatform = "mac";
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
netCorePublishRid = "linux-x64";
electronPackerPlatform = "linux";
}
break;
}
return new GetTargetPlatformInformationResult()
{
ElectronPackerPlatform = electronPackerPlatform,
NetCorePublishRid = netCorePublishRid
};
}
}
}

View File

@@ -1,139 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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
// ToDo: Not sure if this runs under linux/macos
ProcessHelper.CmdExecute(@"npx tsc -p ../../", targetFilePath);
// search .csproj or .fsproj (.csproj has higher precedence)
Console.WriteLine($"Search your .csproj/.fsproj to add configure CopyToPublishDirectory to 'Never'");
var projectFile = Directory.EnumerateFiles(currentDirectory, "*.csproj", SearchOption.TopDirectoryOnly)
.Union(Directory.EnumerateFiles(currentDirectory, "*.fsproj", SearchOption.TopDirectoryOnly))
.FirstOrDefault();
var extension = Path.GetExtension(projectFile);
Console.WriteLine($"Found your {extension}: {projectFile} - check for existing CopyToPublishDirectory setting or update it.");
if (!EditProjectFile(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 EditProjectFile(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/fsproj!");
return true;
}
}
}

View File

@@ -1,263 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ElectronNET.CLI.Commands.Actions;
namespace ElectronNET.CLI.Commands
{
public class BuildCommand : ICommand
{
public const string COMMAND_NAME = "build";
public const string COMMAND_DESCRIPTION = "Build your Electron Application.";
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;win\"'" + Environment.NewLine +
"Optional: '/dotnet-configuration' with the desired .NET Core build config e.g. release or debug. Default = Release" + Environment.NewLine +
"Optional: '/no-restore' to disable nuget packages restore" + 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 +
"Optional: '/relative-path' to specify output a subdirectory for output." + Environment.NewLine +
"Optional: '/absolute-path to specify and absolute path for output." + Environment.NewLine +
"Optional: '/package-json' to specify a custom package.json file." + Environment.NewLine +
"Optional: '/install-modules' to force node module install. Implied by '/package-json'" + Environment.NewLine +
"Optional: '/Version' to specify the version that should be applied to both the `dotnet publish` and `electron-builder` commands. Implied by '/Version'" + Environment.NewLine +
"Optional: '/p:[property]' or '/property:[property]' to pass in dotnet publish properties. Example: '/property:Version=1.0.0' to override the FileVersion" + 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 \"";
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
private string[] _args;
public BuildCommand(string[] args)
{
_args = args;
}
private string _paramTarget = "target";
private string _paramDotNetConfig = "dotnet-configuration";
private string _paramElectronArch = "electron-arch";
private string _paramElectronParams = "electron-params";
private string _paramOutputDirectory = "relative-path";
private string _paramAbsoluteOutput = "absolute-path";
private string _paramPackageJson = "package-json";
private string _paramForceNodeInstall = "install-modules";
private string _manifest = "manifest";
private string _paramPublishReadyToRun = "PublishReadyToRun";
private string _paramPublishSingleFile = "PublishSingleFile";
private string _paramSelfContained = "SelfContained";
private string _paramNoRestore = "no-restore";
private string _paramVersion = "Version";
public Task<bool> ExecuteAsync()
{
return Task.Run(() =>
{
Console.WriteLine("Build Electron Application...");
SimpleCommandLineParser parser = new SimpleCommandLineParser();
parser.Parse(_args);
//This version will be shared between the dotnet publish and electron-builder commands
string version = null;
if (parser.Arguments.ContainsKey(_paramVersion))
version = parser.Arguments[_paramVersion][0];
if (!parser.Arguments.ContainsKey(_paramTarget))
{
Console.WriteLine($"Error: missing '{_paramTarget}' argument.");
Console.WriteLine(COMMAND_ARGUMENTS);
return false;
}
var desiredPlatform = parser.Arguments[_paramTarget][0];
string specifiedFromCustom = string.Empty;
if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
{
specifiedFromCustom = parser.Arguments[_paramTarget][1];
}
string configuration = "Release";
if (parser.Arguments.ContainsKey(_paramDotNetConfig))
{
configuration = parser.Arguments[_paramDotNetConfig][0];
}
string noRestore = parser.Arguments.ContainsKey(_paramNoRestore)
? " --no-restore"
: string.Empty;
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);
if (Directory.Exists(tempPath) == false)
{
Directory.CreateDirectory(tempPath);
}
else
{
Directory.Delete(tempPath, true);
Directory.CreateDirectory(tempPath);
}
Console.WriteLine("Executing dotnet publish in this directory: " + tempPath);
string tempBinPath = Path.Combine(tempPath, "bin");
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}\"{noRestore} --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}";
// output the command
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(command);
Console.ResetColor();
var resultCode = ProcessHelper.CmdExecute(command, Directory.GetCurrentDirectory());
if (resultCode != 0)
{
Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
return false;
}
DeployEmbeddedElectronFiles.Do(tempPath);
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
if (parser.Arguments.ContainsKey(_paramPackageJson))
{
Console.WriteLine("Copying custom package.json.");
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);
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", hosthookDir);
// ToDo: Not sure if this runs under linux/macos
ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
}
Console.WriteLine("Build Electron Desktop Application...");
// Specifying an absolute path supercedes a relative path
string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop");
if (parser.Arguments.ContainsKey(_paramAbsoluteOutput))
{
buildPath = parser.Arguments[_paramAbsoluteOutput][0];
}
else if (parser.Arguments.ContainsKey(_paramOutputDirectory))
{
buildPath = Path.Combine(Directory.GetCurrentDirectory(), parser.Arguments[_paramOutputDirectory][0]);
}
Console.WriteLine("Executing electron magic in this directory: " + buildPath);
string electronArch = "x64";
if (parser.Arguments.ContainsKey(_paramElectronArch))
{
electronArch = parser.Arguments[_paramElectronArch][0];
}
string electronParams = "";
if (parser.Arguments.ContainsKey(_paramElectronParams))
{
electronParams = parser.Arguments[_paramElectronParams][0];
}
// 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";
if (parser.Arguments.ContainsKey(_manifest))
{
manifestFileName = parser.Arguments[_manifest].First();
}
ProcessHelper.CmdExecute(
string.IsNullOrWhiteSpace(version)
? $"node build-helper.js {manifestFileName}"
: $"node build-helper.js {manifestFileName} {version}", tempPath);
Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=30.0.3 {electronParams}", tempPath);
Console.WriteLine("... done");
return true;
});
}
private Dictionary<string, string> GetDotNetPublishFlags(SimpleCommandLineParser parser)
{
var dotNetPublishFlags = new Dictionary<string, string>
{
{"/p:PublishReadyToRun", parser.TryGet(_paramPublishReadyToRun, out var rtr) ? rtr[0] : "true"},
{"/p:PublishSingleFile", parser.TryGet(_paramPublishSingleFile, out var psf) ? psf[0] : "true"},
{"/p:SelfContained", parser.TryGet(_paramSelfContained, out var sc) ? sc[0] : "true"},
};
if (parser.Arguments.ContainsKey(_paramVersion))
{
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=")))
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:"))
{
key = key.Replace("/property:", "/p:");
}
var value = parm.Substring(split + 1);
if (dotNetPublishFlags.ContainsKey(key))
{
dotNetPublishFlags[key] = value;
}
else
{
dotNetPublishFlags.Add(key, value);
}
}
return dotNetPublishFlags;
}
}
}

View File

@@ -1,53 +0,0 @@
namespace ElectronNET.CLI.Commands
{
/// <summary>
/// The definitionn of an option for a command.
/// </summary>
public class CommandOption
{
/// <summary>
/// An enum for the possible values for an option
/// </summary>
public enum CommandOptionValueType { NoValue, StringValue, BoolValue, IntValue, CommaDelimitedList, KeyValuePairs }
/// <summary>
/// The name of the option.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The short form of the command line switch. This will start with just one dash e.g. -f for framework
/// </summary>
public string ShortSwitch { get; set; }
/// <summary>
/// The full form of the command line switch. This will start with two dashes e.g. --framework
/// </summary>
public string Switch { get; set; }
/// <summary>
/// The description of the option
/// </summary>
public string Description { get; set; }
/// <summary>
/// The type of value that is expected with this command option
/// </summary>
public CommandOptionValueType ValueType { get; set; }
/// <summary>
/// The JSON key used in configuration file.`
/// </summary>
public string ConfigFileKey
{
get
{
var key = this.Switch;
if (key.StartsWith("--"))
key = key.Substring(2);
return key;
}
}
}
}

View File

@@ -1,12 +0,0 @@
using System.Threading.Tasks;
namespace ElectronNET.CLI.Commands
{
/// <summary>
/// Interface for commands to implement.
/// </summary>
public interface ICommand
{
Task<bool> ExecuteAsync();
}
}

View File

@@ -1,214 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace ElectronNET.CLI.Commands
{
public class InitCommand : ICommand
{
public const string COMMAND_NAME = "init";
public const string COMMAND_DESCRIPTION = "Creates the needed Electron.NET config for your Electron Application.";
public const string COMMAND_ARGUMENTS = "<Path> from ASP.NET Core Project.";
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
private static SimpleCommandLineParser _parser = new SimpleCommandLineParser();
private static string ConfigName = "electron.manifest.json";
private const string DefaultConfigFileName = "electron.manifest.json";
public InitCommand(string[] args)
{
_parser.Parse(args);
}
private static string _aspCoreProjectPath = "project-path";
private static string _manifest = "manifest";
public Task<bool> ExecuteAsync()
{
return Task.Run(() =>
{
string aspCoreProjectPath = "";
if (_parser.Arguments.ContainsKey(_aspCoreProjectPath))
{
string projectPath = _parser.Arguments[_aspCoreProjectPath].First();
if (Directory.Exists(projectPath))
{
aspCoreProjectPath = projectPath;
}
}
else
{
aspCoreProjectPath = Directory.GetCurrentDirectory();
}
var currentDirectory = aspCoreProjectPath;
if(_parser.Arguments.ContainsKey(_manifest))
{
ConfigName = "electron.manifest." + _parser.Arguments[_manifest].First() + ".json";
Console.WriteLine($"Adding your custom {ConfigName} config file to your project...");
}
else
{
Console.WriteLine("Adding our config file to your project...");
}
var targetFilePath = Path.Combine(currentDirectory, ConfigName);
if (File.Exists(targetFilePath))
{
Console.WriteLine("Config file already in your project.");
return false;
}
// Deploy config file
EmbeddedFileHelper.DeployEmbeddedFileToTargetFile(currentDirectory, DefaultConfigFileName, ConfigName);
// 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));
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;
// search launchSettings.json
Console.WriteLine($"Search your .launchSettings to add our electron debug profile...");
EditLaunchSettings(currentDirectory);
Console.WriteLine($"Everything done - happy electronizing!");
return true;
});
}
private static void EditLaunchSettings(string currentDirectory)
{
// super stupid implementation, but because there is no nativ way to parse json
// and cli extensions and other nuget packages are buggy
// this is should solve the problem for 80% of the users
// for the other 20% we might fail...
var launchSettingFile = Path.Combine(currentDirectory, "Properties", "launchSettings.json");
if (File.Exists(launchSettingFile) == false)
{
Console.WriteLine("launchSettings.json not found - do nothing.");
return;
}
string launchSettingText = File.ReadAllText(launchSettingFile);
if(_parser.Arguments.ContainsKey(_manifest))
{
string manifestName = _parser.Arguments[_manifest].First();
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(" },");
launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString());
File.WriteAllText(launchSettingFile, launchSettingText);
Console.WriteLine($"Debug profile added!");
}
else
{
Console.WriteLine($"Debug profile already existing");
}
}
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(" },");
launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString());
File.WriteAllText(launchSettingFile, launchSettingText);
Console.WriteLine($"Debug profile added!");
}
else
{
Console.WriteLine($"Debug profile already existing");
}
}
private static bool EditProjectFile(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;
}
if (xmlDocument.ToString().Contains($"Content Update=\"{ConfigName}\""))
{
Console.WriteLine($"{ConfigName} already in csproj/fsproj.");
return false;
}
Console.WriteLine($"{ConfigName} will be added to csproj/fsproj.");
string itemGroupXmlString = "<ItemGroup>" +
"<Content Update=\"" + ConfigName + "\">" +
"<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>" +
"</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($"{ConfigName} added in csproj/fsproj!");
return true;
}
}
}

View File

@@ -1,185 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ElectronNET.CLI.Commands.Actions;
namespace ElectronNET.CLI.Commands
{
public class StartElectronCommand : ICommand
{
public const string COMMAND_NAME = "start";
public const string COMMAND_DESCRIPTION = "Start your ASP.NET Core Application with Electron, without package it as a single exe. Faster for development.";
public const string COMMAND_ARGUMENTS = "<Path> from ASP.NET Core Project.";
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
private string[] _args;
public StartElectronCommand(string[] args)
{
_args = args;
}
private string _aspCoreProjectPath = "project-path";
private string _arguments = "args";
private string _manifest = "manifest";
private string _clearCache = "clear-cache";
private string _paramPublishReadyToRun = "PublishReadyToRun";
private string _paramPublishSingleFile = "PublishSingleFile";
private string _paramDotNetConfig = "dotnet-configuration";
private string _paramTarget = "target";
public Task<bool> ExecuteAsync()
{
return Task.Run(() =>
{
Console.WriteLine("Start Electron Desktop Application...");
SimpleCommandLineParser parser = new SimpleCommandLineParser();
parser.Parse(_args);
string aspCoreProjectPath = "";
if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
{
string projectPath = parser.Arguments[_aspCoreProjectPath].First();
if (Directory.Exists(projectPath))
{
aspCoreProjectPath = projectPath;
}
}
else
{
aspCoreProjectPath = Directory.GetCurrentDirectory();
}
string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");
if (Directory.Exists(tempPath) == false)
{
Directory.CreateDirectory(tempPath);
}
string tempBinPath = Path.Combine(tempPath, "bin");
var resultCode = 0;
string publishReadyToRun = "/p:PublishReadyToRun=";
if (parser.Arguments.ContainsKey(_paramPublishReadyToRun))
{
publishReadyToRun += parser.Arguments[_paramPublishReadyToRun][0];
}
else
{
publishReadyToRun += "true";
}
string publishSingleFile = "/p:PublishSingleFile=";
if (parser.Arguments.ContainsKey(_paramPublishSingleFile))
{
publishSingleFile += parser.Arguments[_paramPublishSingleFile][0];
}
else
{
publishSingleFile += "true";
}
// If target is specified as a command line argument, use it.
// 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;
if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
{
specifiedFromCustom = parser.Arguments[_paramTarget][1];
}
platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);
}
string configuration = "Debug";
if (parser.Arguments.ContainsKey(_paramDotNetConfig))
{
configuration = parser.Arguments[_paramDotNetConfig][0];
}
if (parser != null && !parser.Arguments.ContainsKey("watch"))
{
resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {publishReadyToRun} {publishSingleFile} --no-self-contained", aspCoreProjectPath);
}
if (resultCode != 0)
{
Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
return false;
}
DeployEmbeddedElectronFiles.Do(tempPath);
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
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<string>() { "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 = "";
if (parser.Arguments.ContainsKey(_arguments))
{
arguments = string.Join(' ', parser.Arguments[_arguments]);
}
if (parser.Arguments.ContainsKey(_manifest))
{
arguments += " --manifest=" + parser.Arguments[_manifest].First();
}
if (parser.Arguments.ContainsKey(_clearCache))
{
arguments += " --clear-cache=true";
}
if (parser.Arguments.ContainsKey("watch"))
{
arguments += " --watch=true";
}
string path = Path.Combine(tempPath, "node_modules", ".bin");
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
Console.WriteLine("Invoke electron.cmd - in dir: " + path);
ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
}
else
{
Console.WriteLine("Invoke electron - in dir: " + path);
ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
}
return true;
});
}
}
}

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
namespace ElectronNET.CLI.Commands
{
public class VersionCommand : ICommand
{
public const string COMMAND_NAME = "version";
public const string COMMAND_DESCRIPTION = "Displays the ElectronNET.CLI version";
public const string COMMAND_ARGUMENTS = "";
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
public VersionCommand(string[] args)
{
}
public Task<bool> ExecuteAsync()
{
return Task.Run(() =>
{
var runtimeVersion = typeof(VersionCommand)
.GetTypeInfo()
.Assembly
.GetCustomAttribute<AssemblyFileVersionAttribute>();
Console.WriteLine($"ElectronNET.CLI Version: " + runtimeVersion.Version);
return true;
});
}
}
}

View File

@@ -1,88 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<AssemblyName>dotnet-electronize</AssemblyName>
<ToolCommandName>electronize</ToolCommandName>
<PackageType>DotnetCliTool</PackageType>
<PackageOutputPath>..\..\artifacts</PackageOutputPath>
<PackageId>ElectronNET.CLI</PackageId>
<!-- Version 99 is just set for local development stuff to avoid a conflict with "real" packages on NuGet.org -->
<Version>99.0.0.0</Version>
<Authors>Gregor Biswanger, Florian Rappl</Authors>
<Product>Electron.NET</Product>
<Company />
<Description>
Building cross platform electron based desktop apps with .NET Core and ASP.NET Core.
This package contains the dotnet tooling to electronize your application.
</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/ElectronNET/Electron.NET/</PackageProjectUrl>
<RepositoryUrl>https://github.com/ElectronNET/Electron.NET/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageTags>electron aspnetcore</PackageTags>
<PackageReleaseNotes>Changelog: https://github.com/ElectronNET/Electron.NET/blob/main/Changelog.md</PackageReleaseNotes>
<PackageIcon>PackageIcon.png</PackageIcon>
<PackAsTool>true</PackAsTool>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<None Remove="ElectronHost\package-lock.json" />
<None Remove="ElectronHost\package.json" />
</ItemGroup>
<ItemGroup>
<None Include="PackageIcon.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\electron.manifest.json" Link="ElectronHost\electron.manifest.json" />
<EmbeddedResource Include="..\ElectronNET.Host\package.json" Link="ElectronHost\package.json" />
<EmbeddedResource Include="..\ElectronNET.Host\main.js" Link="ElectronHost\main.js" />
<EmbeddedResource Include="..\ElectronNET.Host\build-helper.js" Link="ElectronHost\build-helper.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\ipc.js" Link="ElectronHost\api\ipc.js" />
<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" />
<EmbeddedResource Include="..\ElectronNET.Host\splashscreen\index.html" Link="ElectronHost\splashscreen\index.html" />
<EmbeddedResource Include="..\ElectronNET.Host\api\app.js" Link="ElectronHost\api\app.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\browserWindows.js" Link="ElectronHost\api\browserWindows.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\commandLine.js" Link="ElectronHost\api\commandLine.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\dialog.js" Link="ElectronHost\api\dialog.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\dock.js" Link="ElectronHost\api\dock.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\menu.js" Link="ElectronHost\api\menu.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\notification.js" Link="ElectronHost\api\notification.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\tray.js" Link="ElectronHost\api\tray.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\globalShortcut.js" Link="ElectronHost\api\globalShortcut.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\screen.js" Link="ElectronHost\api\screen.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\shell.js" Link="ElectronHost\api\shell.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\webContents.js" Link="ElectronHost\api\webContents.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\clipboard.js" Link="ElectronHost\api\clipboard.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\autoUpdater.js" Link="ElectronHost\api\autoUpdater.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\browserView.js" Link="ElectronHost\api\browserView.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\powerMonitor.js" Link="ElectronHost\api\powerMonitor.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\nativeTheme.js" Link="ElectronHost\api\nativeTheme.js" />
<EmbeddedResource Include="..\ElectronNET.Host\.vscode\launch.json" Link="ElectronHost\.vscode\launch.json" />
<EmbeddedResource Include="..\ElectronNET.Host\.vscode\tasks.json" Link="ElectronHost\.vscode\tasks.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.4.421302">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' == 'Windows_NT'">
<Exec Command="$(ProjectDir)devCleanup.cmd" IgnoreExitCode="true" />
</Target>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' != 'Windows_NT'">
<Exec Command="$(ProjectDir)devCleanup.sh" IgnoreExitCode="true" />
</Target>
</Project>

View File

@@ -1,47 +0,0 @@
using System;
using System.IO;
using System.Reflection;
namespace ElectronNET.CLI
{
public static class EmbeddedFileHelper
{
private const string ResourcePath = "ElectronNET.CLI.{0}";
private static Stream GetTestResourceFileStream(string folderAndFileInProjectPath)
{
var asm = Assembly.GetExecutingAssembly();
var resource = string.Format(ResourcePath, folderAndFileInProjectPath);
return asm.GetManifestResourceStream(resource);
}
public static void DeployEmbeddedFile(string targetPath, string file, string namespacePath = "")
{
using (var fileStream = File.Create(Path.Combine(targetPath, file)))
{
var streamFromEmbeddedFile = GetTestResourceFileStream("ElectronHost." + namespacePath + file);
if (streamFromEmbeddedFile == null)
{
Console.WriteLine("Error: Couldn't find embedded file: " + file);
}
streamFromEmbeddedFile.CopyTo(fileStream);
}
}
public static void DeployEmbeddedFileToTargetFile(string targetPath, string embeddedFile, string targetFile, string namespacePath = "")
{
using (var fileStream = File.Create(Path.Combine(targetPath, targetFile)))
{
var streamFromEmbeddedFile = GetTestResourceFileStream("ElectronHost." + namespacePath + embeddedFile);
if (streamFromEmbeddedFile == null)
{
Console.WriteLine("Error: Couldn't find embedded file: " + embeddedFile);
}
streamFromEmbeddedFile.CopyTo(fileStream);
}
}
}
}

View File

@@ -1,53 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ElectronNET.CLI
{
public class ProcessHelper
{
public static int CmdExecute(string command, string workingDirectoryPath, bool output = true, bool waitForExit = true)
{
using (Process cmd = new Process())
{
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
cmd.StartInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
}
else
{
// works for OSX and Linux (at least on Ubuntu)
var escapedArgs = command.Replace("\"", "\\\"");
cmd.StartInfo = new ProcessStartInfo("bash", $"-c \"{escapedArgs}\"");
}
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.RedirectStandardError = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.WorkingDirectory = workingDirectoryPath;
if (output)
{
cmd.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
cmd.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
}
Console.WriteLine(command);
cmd.Start();
cmd.BeginOutputReadLine();
cmd.BeginErrorReadLine();
if (waitForExit)
{
cmd.WaitForExit();
}
return cmd.ExitCode;
}
}
}
}

View File

@@ -1,201 +0,0 @@
using ElectronNET.CLI.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace ElectronNET.CLI
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
PrintUsageHeader();
PrintUsage();
Environment.Exit(-1);
}
ICommand command = null;
switch (args[0])
{
case StartElectronCommand.COMMAND_NAME:
command = new StartElectronCommand(args.Skip(1).ToArray());
break;
case BuildCommand.COMMAND_NAME:
command = new BuildCommand(args.Skip(1).ToArray());
break;
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;
case "--help":
case "--h":
case "help":
PrintUsageHeader();
if (args.Length > 1)
PrintUsage(args[1]);
else
PrintUsage();
break;
default:
Console.Error.WriteLine($"Unknown command {args[0]}");
PrintUsage();
Environment.Exit(-1);
break;
}
if (command != null)
{
var success = command.ExecuteAsync().Result;
if (!success)
{
Environment.Exit(-1);
}
}
}
private static void PrintUsageHeader()
{
var sb = new StringBuilder("Electron.NET Tools");
var version = Version;
if (!string.IsNullOrEmpty(version))
{
sb.Append($" ({version})");
}
Console.WriteLine(sb.ToString());
Console.WriteLine("Project Home: https://github.com/ElectronNET/Electron.NET");
Console.WriteLine("\t");
}
private static void PrintUsage()
{
const int NAME_WIDTH = 23;
Console.WriteLine("\t");
Console.WriteLine("Commands to start the Electron Application:");
Console.WriteLine("\t");
Console.WriteLine($"\t{StartElectronCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {StartElectronCommand.COMMAND_DESCRIPTION}");
Console.WriteLine("\t");
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("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");
Console.WriteLine($"\t{VersionCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {VersionCommand.COMMAND_DESCRIPTION}");
Console.WriteLine("\t");
Console.WriteLine("\t");
Console.WriteLine("To get help on individual commands execute:");
Console.WriteLine("\tdotnet electronize help <command>");
}
private static void PrintUsage(string command)
{
switch (command)
{
case StartElectronCommand.COMMAND_NAME:
PrintUsage(StartElectronCommand.COMMAND_NAME, StartElectronCommand.COMMAND_DESCRIPTION, StartElectronCommand.CommandOptions, StartElectronCommand.COMMAND_ARGUMENTS);
break;
case BuildCommand.COMMAND_NAME:
PrintUsage(BuildCommand.COMMAND_NAME, BuildCommand.COMMAND_DESCRIPTION, BuildCommand.CommandOptions, BuildCommand.COMMAND_ARGUMENTS);
break;
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;
default:
Console.Error.WriteLine($"Unknown command {command}");
PrintUsage();
break;
}
}
private static void PrintUsage(string command, string description, IList<CommandOption> options, string arguments)
{
const int INDENT = 3;
Console.WriteLine($"{command}: ");
Console.WriteLine($"{new string(' ', INDENT)}{description}");
Console.WriteLine("\t");
if (!string.IsNullOrEmpty(arguments))
{
Console.WriteLine($"{new string(' ', INDENT)}dotnet electronize {command} [arguments] [options]");
Console.WriteLine($"{new string(' ', INDENT)}Arguments:");
Console.WriteLine($"{new string(' ', INDENT * 2)}{arguments}");
}
else
{
Console.WriteLine($"{new string(' ', INDENT)}dotnet electronize {command} [options]");
}
const int SWITCH_COLUMN_WIDTH = 40;
Console.WriteLine($"{new string(' ', INDENT)}Options:");
foreach (var option in options)
{
StringBuilder stringBuilder = new StringBuilder();
if (option.ShortSwitch != null)
{
stringBuilder.Append($"{option.ShortSwitch.PadRight(6)} | ");
}
stringBuilder.Append($"{option.Switch}");
if (stringBuilder.Length < SWITCH_COLUMN_WIDTH)
{
stringBuilder.Append(new string(' ', SWITCH_COLUMN_WIDTH - stringBuilder.Length));
}
stringBuilder.Append(option.Description);
Console.WriteLine($"{new string(' ', INDENT * 2)}{stringBuilder.ToString()}");
}
}
private static string Version
{
get
{
AssemblyInformationalVersionAttribute attribute = null;
try
{
attribute = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>();
}
catch (AmbiguousMatchException)
{
// Catch exception and continue if multiple attributes are found.
}
return attribute?.InformationalVersion;
}
}
}
}

View File

@@ -1,8 +0,0 @@
{
"profiles": {
"ElectronNET.CLI": {
"commandName": "Project",
"commandLineArgs": "start /project-path \"$(SolutionDir)ElectronNET.WebApp\" /watch"
}
}
}

View File

@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ElectronNET.CLI
{
public class SimpleCommandLineParser
{
public SimpleCommandLineParser()
{
Arguments = new Dictionary<string, string[]>();
}
public IDictionary<string, string[]> Arguments { get; private set; }
public void Parse(string[] args)
{
var currentName = "";
var values = new List<string>();
foreach (var arg in args)
{
if (arg.StartsWith("/"))
{
if (currentName != "")
Arguments[currentName] = values.ToArray();
values.Clear();
currentName = arg.Substring(1);
}
else if (currentName == "")
Arguments[arg] = new string[0];
else
values.Add(arg);
}
if (currentName != "")
Arguments[currentName] = values.ToArray();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Arguments: \n\t{string.Join("\n\t",Arguments.Keys.Select(i => $"{i} = {string.Join(" ", Arguments[i])}"))}");
Console.ResetColor();
}
public bool Contains(string name)
{
return Arguments.ContainsKey(name);
}
internal bool TryGet(string key, out string[] value)
{
value = null;
if (!Contains(key)) {
return false;
}
value = Arguments[key];
return true;
}
}
}

View File

@@ -1,3 +0,0 @@
rd /s /q %userprofile%\.nuget\packages\.tools\electronnet.cli
rd /s /q %userprofile%\.nuget\packages\electronnet.cli
del ..\artifacts\ElectronNET.CLI.1.0.0.nupkg

View File

@@ -1 +0,0 @@
rm -rf ~/.nuget/packages/electronnet.cli