Implemented Electrons CommandLine-API, Implemented arguments support, Implemented different manifest file support

This commit is contained in:
Gregor Biswanger
2019-11-30 01:30:22 +01:00
parent f5e2abfdb4
commit a788d71530
13 changed files with 223 additions and 97 deletions

View File

@@ -351,7 +351,10 @@ namespace ElectronNET.API
private event Action<bool> _accessibilitySupportChanged;
internal App() { }
internal App()
{
CommandLine = new CommandLine();
}
internal static App Instance
{
@@ -1224,7 +1227,7 @@ namespace ElectronNET.API
taskCompletionSource.SetResult((bool)success);
});
BridgeConnector.Socket.Emit("appSetBadgeCount");
BridgeConnector.Socket.Emit("appSetBadgeCount", count);
return await taskCompletionSource.Task
.ConfigureAwait(false);
@@ -1255,6 +1258,11 @@ namespace ElectronNET.API
}
}
/// <summary>
/// Manipulate the command line arguments for your app that Chromium reads.
/// </summary>
public CommandLine CommandLine { get; internal set; }
/// <summary>
/// Whether the current desktop environment is Unity launcher.
/// </summary>
@@ -1380,39 +1388,6 @@ namespace ElectronNET.API
BridgeConnector.Socket.Emit("appSetAboutPanelOptions", JObject.FromObject(options, _jsonSerializer));
}
/// <summary>
/// Append a switch (with optional value) to Chromium's command line. Note: This
/// will not affect process.argv, and is mainly used by developers to control some
/// low-level Chromium behaviors.
/// </summary>
/// <param name="theSwtich">A command-line switch.</param>
public void CommandLineAppendSwitch(string theSwtich)
{
BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", theSwtich);
}
/// <summary>
/// Append a switch (with optional value) to Chromium's command line. Note: This
/// will not affect process.argv, and is mainly used by developers to control some
/// low-level Chromium behaviors.
/// </summary>
/// <param name="theSwtich">A command-line switch.</param>
/// <param name="value">A value for the given switch.</param>
public void CommandLineAppendSwitch(string theSwtich, string value)
{
BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", theSwtich, value);
}
/// <summary>
/// Append an argument to Chromium's command line. The argument will be quoted
/// correctly.Note: This will not affect process.argv.
/// </summary>
/// <param name="value">The argument to append to the command line.</param>
public void CommandLineAppendArgument(string value)
{
BridgeConnector.Socket.Emit("appCommandLineAppendArgument", value);
}
/// <summary>
/// When critical is passed, the dock icon will bounce until either the application
/// becomes active or the request is canceled.When informational is passed, the

View File

@@ -0,0 +1,116 @@
using System.Threading;
using System.Threading.Tasks;
namespace ElectronNET.API
{
/// <summary>
/// Manipulate the command line arguments for your app that Chromium reads.
/// </summary>
public sealed class CommandLine
{
internal CommandLine() { }
internal static CommandLine Instance
{
get
{
if (_commandLine == null)
{
lock (_syncRoot)
{
if (_commandLine == null)
{
_commandLine = new CommandLine();
}
}
}
return _commandLine;
}
}
private static CommandLine _commandLine;
private static object _syncRoot = new object();
/// <summary>
/// Append a switch (with optional value) to Chromium's command line.
/// </summary>
/// <param name="the_switch">A command-line switch, without the leading --</param>
/// <param name="value">(optional) - A value for the given switch</param>
/// <remarks>
/// Note: This will not affect process.argv. The intended usage of this function is to control Chromium's behavior.
/// </remarks>
public void AppendSwitch(string the_switch, string value = "")
{
BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", the_switch, value);
}
/// <summary>
/// Append an argument to Chromium's command line. The argument will be quoted correctly. Switches will precede arguments regardless of appending order.
///
/// If you're appending an argument like <code>--switch=value</code>, consider using <code>appendSwitch('switch', 'value')</code> instead.
/// </summary>
/// <param name="value">The argument to append to the command line</param>
/// <remarks>
/// Note: This will not affect process.argv. The intended usage of this function is to control Chromium's behavior.
/// </remarks>
public void AppendArgument(string value)
{
BridgeConnector.Socket.Emit("appCommandLineAppendArgument", value);
}
/// <summary>
/// Whether the command-line switch is present.
/// </summary>
/// <param name="switchName">A command-line switch</param>
/// <param name="cancellationToken"></param>
/// <returns>Whether the command-line switch is present.</returns>
public async Task<bool> HasSwitchAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
var taskCompletionSource = new TaskCompletionSource<bool>();
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
{
BridgeConnector.Socket.On("appCommandLineHasSwitchCompleted", (result) =>
{
BridgeConnector.Socket.Off("appCommandLineHasSwitchCompleted");
taskCompletionSource.SetResult((bool)result);
});
BridgeConnector.Socket.Emit("appCommandLineHasSwitch", switchName);
return await taskCompletionSource.Task.ConfigureAwait(false);
}
}
/// <summary>
/// The command-line switch value.
/// </summary>
/// <param name="switchName">A command-line switch</param>
/// <param name="cancellationToken"></param>
/// <returns>The command-line switch value.</returns>
/// <remarks>
/// Note: When the switch is not present or has no value, it returns empty string.
/// </remarks>
public async Task<string> GetSwitchValueAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
var taskCompletionSource = new TaskCompletionSource<string>();
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
{
BridgeConnector.Socket.On("appCommandLineGetSwitchValueCompleted", (result) =>
{
BridgeConnector.Socket.Off("appCommandLineGetSwitchValueCompleted");
taskCompletionSource.SetResult((string)result);
});
BridgeConnector.Socket.Emit("appCommandLineGetSwitchValue", switchName);
return await taskCompletionSource.Task.ConfigureAwait(false);
}
}
}
}

View File

@@ -18,6 +18,7 @@ namespace ElectronNET.CLI.Commands.Actions
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, "menu.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api.");

View File

@@ -1,6 +1,7 @@
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;
@@ -21,19 +22,27 @@ namespace ElectronNET.CLI.Commands
_args = args;
}
private string _aspCoreProjectPath = "project-path";
private string _arguments = "args";
private string _manifest = "manifest";
public Task<bool> ExecuteAsync()
{
return Task.Run(() =>
{
Console.WriteLine("Start Electron Desktop Application...");
SimpleCommandLineParser parser = new SimpleCommandLineParser();
parser.Parse(_args);
string aspCoreProjectPath = "";
if (_args.Length > 0)
if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
{
if (Directory.Exists(_args[0]))
string projectPath = parser.Arguments[_aspCoreProjectPath].First();
if (Directory.Exists(projectPath))
{
aspCoreProjectPath = _args[0];
aspCoreProjectPath = projectPath;
}
}
else
@@ -83,19 +92,30 @@ namespace ElectronNET.CLI.Commands
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();
}
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""", path);
ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
}
else
{
Console.WriteLine("Invoke electron - in dir: " + path);
ProcessHelper.CmdExecute(@"./electron ""../../main.js""", path);
ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
}
return true;

View File

@@ -4,7 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>electronize</AssemblyName>
<PackageType>DotnetCliTool</PackageType>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageOutputPath>..\artifacts</PackageOutputPath>
@@ -14,8 +14,10 @@
<Authors>Gregor Biswanger, Robert Muehsig</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>
<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>
@@ -31,63 +33,34 @@ This package contains the dotnet tooling to electronize your application.</Descr
<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" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\package.json" Link="ElectronHost\package.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\main.js" Link="ElectronHost\main.js" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\build-helper.js" Link="ElectronHost\build-helper.js" />
</ItemGroup>
<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\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" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\api\app.js" Link="ElectronHost\api\app.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\browserWindows.js" Link="ElectronHost\api\browserWindows.js" />
</ItemGroup>
<ItemGroup>
<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\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" />
</ItemGroup>
<ItemGroup>
<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" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\ElectronNET.Host\api\clipboard.js" Link="ElectronHost\api\clipboard.js" />
<EmbeddedResource Include="..\ElectronNET.Host\api\autoUpdater.js" Link="ElectronHost\api\autoUpdater.js" />
</ItemGroup>

View File

@@ -10,7 +10,11 @@
"name": "Launch Electron App",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"program": "${workspaceFolder}/main.js",
"sourceMaps": true
"sourceMaps": true,
"args": [
"--test=true",
"--blub=wuhuu"
]
}
]
}

View File

@@ -217,12 +217,6 @@ module.exports = (socket, app) => {
socket.on('appSetAboutPanelOptions', (options) => {
app.setAboutPanelOptions(options);
});
socket.on('appCommandLineAppendSwitch', (theSwitch, value) => {
app.commandLine.appendSwitch(theSwitch, value);
});
socket.on('appCommandLineAppendArgument', (value) => {
app.commandLine.appendArgument(value);
});
socket.on('appDockBounce', (type) => {
const id = app.dock.bounce(type);
electronSocket.emit('appDockBounceCompleted', id);

File diff suppressed because one or more lines are too long

View File

@@ -262,14 +262,6 @@ export = (socket: SocketIO.Socket, app: Electron.App) => {
app.setAboutPanelOptions(options);
});
socket.on('appCommandLineAppendSwitch', (theSwitch, value) => {
app.commandLine.appendSwitch(theSwitch, value);
});
socket.on('appCommandLineAppendArgument', (value) => {
app.commandLine.appendArgument(value);
});
socket.on('appDockBounce', (type) => {
const id = app.dock.bounce(type);
electronSocket.emit('appDockBounceCompleted', id);

View File

@@ -0,0 +1,20 @@
"use strict";
let electronSocket;
module.exports = (socket, app) => {
electronSocket = socket;
socket.on('appCommandLineAppendSwitch', (the_switch, value) => {
app.commandLine.appendSwitch(the_switch, value);
});
socket.on('appCommandLineAppendArgument', (value) => {
app.commandLine.appendArgument(value);
});
socket.on('appCommandLineHasSwitch', (value) => {
const hasSwitch = app.commandLine.hasSwitch(value);
electronSocket.emit('appCommandLineHasSwitchCompleted', hasSwitch);
});
socket.on('appCommandLineGetSwitchValue', (the_switch) => {
const value = app.commandLine.getSwitchValue(the_switch);
electronSocket.emit('appCommandLineGetSwitchValueCompleted', value);
});
};
//# sourceMappingURL=commandLine.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"commandLine.js","sourceRoot":"","sources":["commandLine.ts"],"names":[],"mappings":";AAAA,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,GAAiB,EAAE,EAAE;IACpD,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,CAAC,UAAkB,EAAE,KAAa,EAAE,EAAE;QAC1E,GAAG,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,CAAC,KAAa,EAAE,EAAE;QACxD,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAa,EAAE,EAAE;QACnD,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnD,cAAc,CAAC,IAAI,CAAC,kCAAkC,EAAE,SAAS,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,CAAC,UAAkB,EAAE,EAAE;QAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACzD,cAAc,CAAC,IAAI,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}

View File

@@ -0,0 +1,23 @@
let electronSocket;
export = (socket: SocketIO.Socket, app: Electron.App) => {
electronSocket = socket;
socket.on('appCommandLineAppendSwitch', (the_switch: string, value: string) => {
app.commandLine.appendSwitch(the_switch, value);
});
socket.on('appCommandLineAppendArgument', (value: string) => {
app.commandLine.appendArgument(value);
});
socket.on('appCommandLineHasSwitch', (value: string) => {
const hasSwitch = app.commandLine.hasSwitch(value);
electronSocket.emit('appCommandLineHasSwitchCompleted', hasSwitch);
});
socket.on('appCommandLineGetSwitchValue', (the_switch: string) => {
const value = app.commandLine.getSwitchValue(the_switch);
electronSocket.emit('appCommandLineGetSwitchValueCompleted', value);
});
};

View File

@@ -7,10 +7,16 @@ const imageSize = require('image-size');
let io, server, browserWindows, ipc, apiProcess, loadURL;
let appApi, menu, dialogApi, notification, tray, webContents;
let globalShortcut, shellApi, screen, clipboard, autoUpdater;
let commandLine;
let splashScreen, hostHook;
let manifestJsonFileName = 'electron.manifest.json';
if(app.commandLine.hasSwitch('manifest')) {
manifestJsonFileName = app.commandLine.getSwitchValue('manifest');
};
const currentBinPath = path.join(__dirname.replace('app.asar', ''), 'bin');
const manifestJsonFilePath = path.join(currentBinPath, 'electron.manifest.json');
const manifestJsonFilePath = path.join(currentBinPath, manifestJsonFileName);
const manifestJsonFile = require(manifestJsonFilePath);
if (manifestJsonFile.singleInstance || manifestJsonFile.aspCoreBackendPort) {
const mainInstance = app.requestSingleInstanceLock();
@@ -110,6 +116,7 @@ function startSocketApiBridge(port) {
appApi = require('./api/app')(socket, app);
browserWindows = require('./api/browserWindows')(socket, app);
commandLine = require('./api/commandLine')(socket, app);
autoUpdater = require('./api/autoUpdater')(socket);
ipc = require('./api/ipc')(socket);
menu = require('./api/menu')(socket);