diff --git a/.devops/build-nuget.yaml b/.devops/build-nuget.yaml
new file mode 100644
index 0000000..b559186
--- /dev/null
+++ b/.devops/build-nuget.yaml
@@ -0,0 +1,84 @@
+variables:
+ PackageVersion: 19.0.9.$(Build.BuildId)
+ projectAPI: './ElectronNET.API/ElectronNET.API.csproj'
+ projectCLI: './ElectronNET.CLI/ElectronNET.CLI.csproj'
+
+trigger:
+- master
+
+pool:
+ vmImage: windows-latest
+
+steps:
+- checkout: self
+ submodules: true
+ fetchDepth: 10
+
+- task: NuGetToolInstaller@1
+
+- task: UseDotNet@2
+ displayName: 'Use .NET Core sdk'
+ inputs:
+ packageType: sdk
+ version: 6.0.100
+ installationPath: $(Agent.ToolsDirectory)/dotnet
+
+- task: DotNetCoreCLI@2
+ displayName: 'restore nuget'
+ inputs:
+ command: 'restore'
+ projects: '$(projectAPI)'
+
+- task: DotNetCoreCLI@2
+ displayName: 'restore nuget'
+ inputs:
+ command: 'restore'
+ projects: '$(projectCLI)'
+
+
+- task: DotNetCoreCLI@2
+ inputs:
+ command: 'build'
+ projects: '$(projectAPI)'
+ arguments: '--configuration Release --force /property:Version=$(PackageVersion)'
+
+- task: DotNetCoreCLI@2
+ inputs:
+ command: 'build'
+ projects: '$(projectCLI)'
+ arguments: '--configuration Release --force /property:Version=$(PackageVersion)'
+
+- task: DotNetCoreCLI@2
+ inputs:
+ command: 'pack'
+ packagesToPack: '$(projectAPI)'
+ configuration: 'Release'
+ versioningScheme: 'off'
+ buildProperties: 'Version=$(PackageVersion)'
+ arguments: -IncludeReferencedProjects
+
+- task: DotNetCoreCLI@2
+ inputs:
+ command: 'pack'
+ packagesToPack: '$(projectCLI)'
+ configuration: 'Release'
+ versioningScheme: 'off'
+ buildProperties: 'Version=$(PackageVersion)'
+
+
+
+- task: NuGetCommand@2
+ displayName: 'push API to nuget'
+ inputs:
+ command: 'push'
+ packagesToPush: '$(Build.ArtifactStagingDirectory)/h5.ElectronNET.API.$(PackageVersion).nupkg'
+ nuGetFeedType: 'external'
+ publishFeedCredentials: 'nuget-curiosity'
+
+- task: NuGetCommand@2
+ displayName: 'push CLI to nuget'
+ inputs:
+ command: 'push'
+ packagesToPush: '$(Build.ArtifactStagingDirectory)/h5.ElectronNET.CLI.$(PackageVersion).nupkg'
+ nuGetFeedType: 'external'
+ publishFeedCredentials: 'nuget-curiosity'
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 03e64bf..1a4851e 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,16 +1,21 @@
{
- "version": "0.1.0",
+ "version": "2.0.0",
"command": "dotnet",
- "isShellCommand": true,
"args": [],
"tasks": [
{
- "taskName": "build",
+ "label": "build",
+ "type": "shell",
+ "command": "dotnet",
"args": [
+ "build",
"${workspaceRoot}/ElectronNET.CLI/ElectronNET.CLI.csproj"
],
- "isBuildCommand": true,
- "problemMatcher": "$msCompile"
+ "problemMatcher": "$msCompile",
+ "group": {
+ "_id": "build",
+ "isDefault": false
+ }
}
]
}
\ No newline at end of file
diff --git a/.vscode/tasks.json.old b/.vscode/tasks.json.old
new file mode 100644
index 0000000..03e64bf
--- /dev/null
+++ b/.vscode/tasks.json.old
@@ -0,0 +1,16 @@
+{
+ "version": "0.1.0",
+ "command": "dotnet",
+ "isShellCommand": true,
+ "args": [],
+ "tasks": [
+ {
+ "taskName": "build",
+ "args": [
+ "${workspaceRoot}/ElectronNET.CLI/ElectronNET.CLI.csproj"
+ ],
+ "isBuildCommand": true,
+ "problemMatcher": "$msCompile"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ElectronNET.API/App.cs b/ElectronNET.API/App.cs
index 0a41610..ab992df 100755
--- a/ElectronNET.API/App.cs
+++ b/ElectronNET.API/App.cs
@@ -8,7 +8,11 @@ using System.Threading;
using System.Threading.Tasks;
using ElectronNET.API.Extensions;
using ElectronNET.API.Interfaces;
+using System.Runtime.Versioning;
+//TODO: Implement app.showEmojiPanel and app.isEmojiPanelSupported: https://www.electronjs.org/docs/api/app#appshowemojipanel-macos-windows
+//TODO: Implement app.moveToApplicationsFolder: https://www.electronjs.org/docs/api/app#appmovetoapplicationsfolderoptions-macos
+//TODO: Implement apprunningUnderRosettaTranslation: https://www.electronjs.org/docs/api/app#apprunningunderrosettatranslation-macos-readonly
namespace ElectronNET.API
{
///
@@ -21,6 +25,90 @@ namespace ElectronNET.API
///
public static bool SocketDebug { get; set; }
+ ///
+ /// Handle hard fails of connecting to the socket. The application must exit when this event is raised.
+ /// The default behavior is to exit with code 0xDEAD
+ ///
+ public static event Action OnSocketConnectFail;
+
+ internal static bool TryRaiseOnSocketConnectFail()
+ {
+ if (OnSocketConnectFail is object)
+ {
+ OnSocketConnectFail();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Emitted when the user clicks on the dock on Mac
+ ///
+ ///
+ [SupportedOSPlatform("macos")]
+ public event Action Activate
+ {
+ add
+ {
+ if (_appActivate == null)
+ {
+ BridgeConnector.On("app-activate", () =>
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ _appActivate();
+ }
+ });
+ }
+ _appActivate += value;
+ }
+ remove
+ {
+ _appActivate -= value;
+
+ if (_appActivate == null)
+ {
+ BridgeConnector.Off("app-activate");
+ }
+ }
+ }
+
+ private event Action _appActivate;
+
+ ///
+ /// Emitted on the first instance when the user opens a second instance of the app, and the app is single instance
+ ///
+ ///
+ public event Action ActivateFromSecondInstance
+ {
+ add
+ {
+ if (_appActivateFromSecondInstance == null)
+ {
+ BridgeConnector.On("app-activate-from-second-instance", (args) =>
+ {
+ _appActivateFromSecondInstance(args);
+ });
+ }
+ _appActivateFromSecondInstance += value;
+ }
+ remove
+ {
+ _appActivateFromSecondInstance -= value;
+
+ if (_appActivateFromSecondInstance == null)
+ {
+ BridgeConnector.Off("app-activate-from-second-instance");
+ }
+ }
+ }
+
+ private event Action _appActivateFromSecondInstance;
+
+
///
/// Emitted when all windows have been closed.
///
@@ -338,6 +426,8 @@ namespace ElectronNET.API
/// screen readers, are enabled or disabled. See https://www.chromium.org/developers/design-documents/accessibility for more details.
///
/// when Chrome's accessibility support is enabled, otherwise.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public event Action AccessibilitySupportChanged
{
add
@@ -412,6 +502,7 @@ namespace ElectronNET.API
///
/// On Windows, you have to parse the arguments using App.CommandLine to get the filepath.
///
+ [SupportedOSPlatform("macos")]
public event Action OpenFile
{
add
@@ -440,8 +531,7 @@ namespace ElectronNET.API
///
- /// Emitted when a MacOS user wants to open a URL with the application. Your application's Info.plist file must
- /// define the URL scheme within the CFBundleURLTypes key, and set NSPrincipalClass to AtomApplication.
+ /// Emitted when a user wants to open a URL with the application. See https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app for more information.
///
public event Action OpenUrl
{
@@ -493,12 +583,16 @@ namespace ElectronNET.API
/// should usually also specify a productName field, which is your application's full capitalized name, and
/// which will be preferred over name by Electron.
///
- public Task GetNameAsync() => BridgeConnector.OnResult("appGetName", "appGetNameCompleted");
+ public Task GetNameAsync => BridgeConnector.OnResult("appGetName", "appGetNameCompleted");
- internal App()
+ private App()
{
- CommandLine = new CommandLine();
+ if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
+ {
+ AppContext.SetSwitch("System.Drawing.EnableUnixSupport", true);
+ }
+ CommandLine = CommandLine.Instance;
}
internal static App Instance
@@ -529,7 +623,7 @@ namespace ElectronNET.API
}
private static App _app;
- private static object _syncRoot = new object();
+ private static readonly object _syncRoot = new();
///
/// Try to close all windows. The event will be emitted first. If all windows are successfully
@@ -600,6 +694,7 @@ namespace ElectronNET.API
///
/// You should seek to use the option as sparingly as possible.
///
+ [SupportedOSPlatform("macos")]
public void Focus(FocusOptions focusOptions)
{
BridgeConnector.Emit("appFocus", JObject.FromObject(focusOptions, _jsonSerializer));
@@ -608,6 +703,7 @@ namespace ElectronNET.API
///
/// Hides all application windows without minimizing them.
///
+ [SupportedOSPlatform("macos")]
public void Hide()
{
BridgeConnector.Emit("appHide");
@@ -616,6 +712,7 @@ namespace ElectronNET.API
///
/// Shows application windows after they were hidden. Does not automatically focus them.
///
+ [SupportedOSPlatform("macos")]
public void Show()
{
BridgeConnector.Emit("appShow");
@@ -689,6 +786,8 @@ namespace ElectronNET.API
/// list from the task bar, and on macOS you can visit it from dock menu.
///
/// Path to add.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public void AddRecentDocument(string path)
{
BridgeConnector.Emit("appAddRecentDocument", path);
@@ -697,6 +796,8 @@ namespace ElectronNET.API
///
/// Clears the recent documents list.
///
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public void ClearRecentDocuments()
{
BridgeConnector.Emit("appClearRecentDocuments");
@@ -727,6 +828,8 @@ namespace ElectronNET.API
/// call this method with electron as the parameter.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task SetAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
{
return await SetAsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -758,6 +861,8 @@ namespace ElectronNET.API
/// The path to the Electron executable. Defaults to process.execPath
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task SetAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
{
return await SetAsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -790,6 +895,8 @@ namespace ElectronNET.API
/// Arguments passed to the executable. Defaults to an empty array.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public Task SetAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appSetAsDefaultProtocolClient", "appSetAsDefaultProtocolClientCompleted", cancellationToken, protocol, path, args);
///
@@ -799,6 +906,8 @@ namespace ElectronNET.API
/// The name of your protocol, without ://.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task RemoveAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
{
return await RemoveAsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -812,6 +921,8 @@ namespace ElectronNET.API
/// Defaults to process.execPath.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task RemoveAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
{
return await RemoveAsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -826,6 +937,8 @@ namespace ElectronNET.API
/// Defaults to an empty array.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public Task RemoveAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appRemoveAsDefaultProtocolClient", "appRemoveAsDefaultProtocolClientCompleted", cancellationToken, protocol, path, args);
@@ -842,6 +955,8 @@ namespace ElectronNET.API
/// The name of your protocol, without ://.
/// The cancellation token.
/// Whether the current executable is the default handler for a protocol (aka URI scheme).
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task IsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
{
return await IsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -861,6 +976,8 @@ namespace ElectronNET.API
/// Defaults to process.execPath.
/// The cancellation token.
/// Whether the current executable is the default handler for a protocol (aka URI scheme).
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public async Task IsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
{
return await IsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -881,6 +998,8 @@ namespace ElectronNET.API
/// Defaults to an empty array.
/// The cancellation token.
/// Whether the current executable is the default handler for a protocol (aka URI scheme).
+ [SupportedOSPlatform("macos")]
+ [SupportedOSPlatform("windows")]
public Task IsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appIsDefaultProtocolClient", "appIsDefaultProtocolClientCompleted", cancellationToken, protocol, path, args);
@@ -892,6 +1011,7 @@ namespace ElectronNET.API
/// Array of objects.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("windows")]
public Task SetUserTasksAsync(UserTask[] userTasks, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appSetUserTasks", "appSetUserTasksCompleted", cancellationToken, JArray.FromObject(userTasks, _jsonSerializer));
///
@@ -899,6 +1019,7 @@ namespace ElectronNET.API
///
/// The cancellation token.
/// Jump List settings.
+ [SupportedOSPlatform("windows")]
public Task GetJumpListSettingsAsync(CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appGetJumpListSettings", "appGetJumpListSettingsCompleted", cancellationToken);
///
@@ -917,6 +1038,7 @@ namespace ElectronNET.API
/// omitted from the Jump List. The list of removed items can be obtained using .
///
/// Array of objects.
+ [SupportedOSPlatform("windows")]
public void SetJumpList(JumpListCategory[] categories)
{
BridgeConnector.Emit("appSetJumpList", JArray.FromObject(categories, _jsonSerializer));
@@ -992,6 +1114,7 @@ namespace ElectronNET.API
///
/// Uniquely identifies the activity. Maps to NSUserActivity.activityType.
/// App-specific state to store for use by another device.
+ [SupportedOSPlatform("macos")]
public void SetUserActivity(string type, object userInfo)
{
SetUserActivity(type, userInfo, null);
@@ -1009,6 +1132,7 @@ namespace ElectronNET.API
///
/// The webpage to load in a browser if no suitable app is installed on the resuming device. The scheme must be http or https.
///
+ [SupportedOSPlatform("macos")]
public void SetUserActivity(string type, object userInfo, string webpageUrl)
{
BridgeConnector.Emit("appSetUserActivity", type, userInfo, webpageUrl);
@@ -1018,12 +1142,14 @@ namespace ElectronNET.API
/// The type of the currently running activity.
///
/// The cancellation token.
+ [SupportedOSPlatform("macos")]
public Task GetCurrentActivityTypeAsync(CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appGetCurrentActivityType", "appGetCurrentActivityTypeCompleted", cancellationToken);
///
/// Invalidates the current Handoff user activity.
///
+ [SupportedOSPlatform("macos")]
public void InvalidateCurrentActivity()
{
BridgeConnector.Emit("appInvalidateCurrentActivity");
@@ -1032,6 +1158,7 @@ namespace ElectronNET.API
///
/// Marks the current Handoff user activity as inactive without invalidating it.
///
+ [SupportedOSPlatform("macos")]
public void ResignCurrentActivity()
{
BridgeConnector.Emit("appResignCurrentActivity");
@@ -1041,6 +1168,7 @@ namespace ElectronNET.API
/// Changes the Application User Model ID to id.
///
/// Model Id.
+ [SupportedOSPlatform("windows")]
public void SetAppUserModelId(string id)
{
BridgeConnector.Emit("appSetAppUserModelId", id);
@@ -1055,6 +1183,7 @@ namespace ElectronNET.API
///
/// The cancellation token.
/// Result of import. Value of 0 indicates success.
+ [SupportedOSPlatform("linux")]
public Task ImportCertificateAsync(ImportCertificateOptions options, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appImportCertificate", "appImportCertificateCompleted", cancellationToken, JObject.FromObject(options, _jsonSerializer));
///
@@ -1085,12 +1214,16 @@ namespace ElectronNET.API
/// Counter badge.
/// The cancellation token.
/// Whether the call succeeded.
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
public Task SetBadgeCountAsync(int count, CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appSetBadgeCount", "appSetBadgeCountCompleted", cancellationToken, count);
///
/// The current value displayed in the counter badge.
///
/// The cancellation token.
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
public Task GetBadgeCountAsync(CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appGetBadgeCount", "appGetBadgeCountCompleted", cancellationToken);
///
@@ -1102,12 +1235,15 @@ namespace ElectronNET.API
/// Whether the current desktop environment is Unity launcher.
///
/// The cancellation token.
+ [SupportedOSPlatform("linux")]
public Task IsUnityRunningAsync(CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appIsUnityRunning", "appIsUnityRunningCompleted", cancellationToken);
///
/// If you provided path and args options to then you need to pass the same
/// arguments here for to be set correctly.
///
+ [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("macos")]
public async Task GetLoginItemSettingsAsync(CancellationToken cancellationToken = default)
{
return await GetLoginItemSettingsAsync(null, cancellationToken);
@@ -1119,6 +1255,8 @@ namespace ElectronNET.API
///
///
/// The cancellation token.
+ [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("macos")]
public Task GetLoginItemSettingsAsync(LoginItemSettingsOptions options, CancellationToken cancellationToken = default) =>
options is null ? BridgeConnector.OnResult("appGetLoginItemSettings", "appGetLoginItemSettingsCompleted", cancellationToken)
: BridgeConnector.OnResult("appGetLoginItemSettings", "appGetLoginItemSettingsCompleted", cancellationToken, JObject.FromObject(options, _jsonSerializer));
@@ -1129,6 +1267,8 @@ namespace ElectronNET.API
/// you'll want to set the launch path to Update.exe, and pass arguments that specify your application name.
///
///
+ [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("macos")]
public void SetLoginItemSettings(LoginSettings loginSettings)
{
BridgeConnector.Emit("appSetLoginItemSettings", JObject.FromObject(loginSettings, _jsonSerializer));
@@ -1140,6 +1280,8 @@ namespace ElectronNET.API
/// See Chromium's accessibility docs for more details.
///
/// if Chrome’s accessibility support is enabled, otherwise.
+ [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("macos")]
public Task IsAccessibilitySupportEnabledAsync(CancellationToken cancellationToken = default) => BridgeConnector.OnResult("appIsAccessibilitySupportEnabled", "appIsAccessibilitySupportEnabledCompleted", cancellationToken);
@@ -1153,6 +1295,8 @@ namespace ElectronNET.API
/// Note: Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
///
/// Enable or disable accessibility tree rendering.
+ [SupportedOSPlatform("windows")]
+ [SupportedOSPlatform("macos")]
public void SetAccessibilitySupportEnabled(bool enabled)
{
BridgeConnector.Emit("appSetAboutPanelOptions", enabled);
@@ -1183,6 +1327,13 @@ namespace ElectronNET.API
BridgeConnector.Emit("appSetAboutPanelOptions", JObject.FromObject(options, _jsonSerializer));
}
+ ///
+ /// Fetches a path's associated icon.
+ ///
+ ///
+ ///
+ public Task GetFileIcon(string path) => BridgeConnector.OnResult("appGetFileIcon", "appGetFileIconCompleted", path);
+
///
/// A which is the user agent string Electron will use as a global fallback.
///
@@ -1207,7 +1358,7 @@ namespace ElectronNET.API
/// custom value as early as possible in your app's initialization to ensure that your overridden value
/// is used.
///
- public Task GetUserAgentFallbackAsync() => BridgeConnector.OnResult("appGetUserAgentFallback", "appGetUserAgentFallbackCompleted");
+ public Task GetUserAgentFallbackAsync => BridgeConnector.OnResult("appGetUserAgentFallback", "appGetUserAgentFallbackCompleted");
internal void PreventQuit()
{
@@ -1245,7 +1396,14 @@ namespace ElectronNET.API
/// The handler
public void Once(string eventName, Action