mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-08-03 14:30:15 +00:00
Merge remote-tracking branch 'origin/master' into powerMonitor
This commit is contained in:
@@ -3,8 +3,10 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -31,7 +33,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.On("app-window-all-closed" + GetHashCode(), () =>
|
||||
{
|
||||
if (!Electron.WindowManager.IsQuitOnWindowAllClosed)
|
||||
if (!Electron.WindowManager.IsQuitOnWindowAllClosed || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
_windowAllClosed();
|
||||
}
|
||||
@@ -351,6 +353,46 @@ namespace ElectronNET.API
|
||||
|
||||
private event Action<bool> _accessibilitySupportChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the application has finished basic startup.
|
||||
/// </summary>
|
||||
public event Action Ready
|
||||
{
|
||||
add
|
||||
{
|
||||
if(IsReady)
|
||||
{
|
||||
value();
|
||||
}
|
||||
|
||||
_ready += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_ready -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _ready;
|
||||
|
||||
/// <summary>
|
||||
/// Application host fully started.
|
||||
/// </summary>
|
||||
public bool IsReady
|
||||
{
|
||||
get { return _isReady; }
|
||||
internal set
|
||||
{
|
||||
_isReady = value;
|
||||
|
||||
if(value)
|
||||
{
|
||||
_ready?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool _isReady = false;
|
||||
|
||||
/// <summary>
|
||||
/// A property that indicates the current application's name, which is the
|
||||
/// name in the application's `package.json` file.
|
||||
@@ -1527,6 +1569,34 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.Emit("appDockSetIcon", image);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A String which is the user agent string Electron will use as a global fallback.
|
||||
/// </summary>
|
||||
public string UserAgentFallback
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<string>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("appGetUserAgentFallbackCompleted", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("appGetUserAgentFallbackCompleted");
|
||||
taskCompletionSource.SetResult((string)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("appGetUserAgentFallback");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("appSetUserAgentFallback", value);
|
||||
}
|
||||
}
|
||||
|
||||
internal void PreventQuit()
|
||||
{
|
||||
_preventQuit = true;
|
||||
|
||||
154
ElectronNET.API/Cookies.cs
Normal file
154
ElectronNET.API/Cookies.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Query and modify a session's cookies.
|
||||
/// </summary>
|
||||
public class Cookies
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The identifier.
|
||||
/// </value>
|
||||
public int Id { get; private set; }
|
||||
|
||||
internal Cookies(int id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a cookie is changed because it was added, edited, removed, or expired.
|
||||
/// </summary>
|
||||
public event Action<Cookie, CookieChangedCause, bool> OnChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_changed == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-changed" + Id, (args) =>
|
||||
{
|
||||
Cookie cookie = ((JArray)args)[0].ToObject<Cookie>();
|
||||
CookieChangedCause cause = ((JArray)args)[1].ToObject<CookieChangedCause>();
|
||||
bool removed = ((JArray)args)[2].ToObject<bool>();
|
||||
_changed(cookie, cause, removed);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-webContents-session-cookies-changed", Id);
|
||||
}
|
||||
_changed += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_changed -= value;
|
||||
|
||||
if (_changed == null)
|
||||
BridgeConnector.Socket.Off("webContents-session-cookies-changed" + Id);
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<Cookie, CookieChangedCause, bool> _changed;
|
||||
|
||||
/// <summary>
|
||||
/// Sends a request to get all cookies matching filter, and resolves a callack with the response.
|
||||
/// </summary>
|
||||
/// <param name="filter">
|
||||
/// </param>
|
||||
/// <returns>A task which resolves an array of cookie objects.</returns>
|
||||
public Task<Cookie[]> GetAsync(CookieFilter filter)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Cookie[]>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-get-completed" + guid, (cookies) =>
|
||||
{
|
||||
Cookie[] result = ((JArray)cookies).ToObject<Cookie[]>();
|
||||
|
||||
BridgeConnector.Socket.Off("webContents-session-cookies-get-completed" + guid);
|
||||
taskCompletionSource.SetResult(result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-cookies-get", Id, JObject.FromObject(filter, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="details"></param>
|
||||
/// <returns></returns>
|
||||
public Task SetAsync(CookieDetails details)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-set-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-cookies-set-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-cookies-set", Id, JObject.FromObject(details, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cookies matching url and name
|
||||
/// </summary>
|
||||
/// <param name="url">The URL associated with the cookie.</param>
|
||||
/// <param name="name">The name of cookie to remove.</param>
|
||||
/// <returns>A task which resolves when the cookie has been removed</returns>
|
||||
public Task RemoveAsync(string url, string name)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-remove-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-cookies-remove-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-cookies-remove", Id, url, name, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes any unwritten cookies data to disk.
|
||||
/// </summary>
|
||||
/// <returns>A task which resolves when the cookie store has been flushed</returns>
|
||||
public Task FlushStoreAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-flushStore-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-cookies-flushStore-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-cookies-flushStore", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
51
ElectronNET.API/Entities/Cookie.cs
Normal file
51
ElectronNET.API/Entities/Cookie.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Cookie {
|
||||
/// <summary>
|
||||
/// The name of the cookie.
|
||||
/// </summary>
|
||||
public string Name { get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// The value of the cookie.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains.
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is a host-only cookie; this will only be true if no domain was passed.
|
||||
/// </summary>
|
||||
public bool HostOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure.
|
||||
/// </summary>
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as HTTP only.
|
||||
/// </summary>
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is a session cookie or a persistent cookie with an expiration date.
|
||||
/// </summary>
|
||||
public bool Session { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies.
|
||||
/// </summary>
|
||||
public long ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
38
ElectronNET.API/Entities/CookieChangedCause.cs
Normal file
38
ElectronNET.API/Entities/CookieChangedCause.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
/// The cause of the change
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum CookieChangedCause
|
||||
{
|
||||
/// <summary>
|
||||
///The cookie was changed directly by a consumer's action.
|
||||
/// </summary>
|
||||
[JsonProperty("explicit")]
|
||||
@explicit,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically removed due to an insert operation that overwrote it.
|
||||
/// </summary>
|
||||
overwrite,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically removed as it expired.
|
||||
/// </summary>
|
||||
expired,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically evicted during garbage collection.
|
||||
/// </summary>
|
||||
evicted,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was overwritten with an already-expired expiration date.
|
||||
/// </summary>
|
||||
[JsonProperty("expired_overwrite")]
|
||||
expiredOverwrite
|
||||
}
|
||||
}
|
||||
56
ElectronNET.API/Entities/CookieDetails.cs
Normal file
56
ElectronNET.API/Entities/CookieDetails.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CookieDetails {
|
||||
/// <summary>
|
||||
/// The URL to associate the cookie with. The callback will be rejected if the URL is invalid.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The name of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The value of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as HTTP only. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch.
|
||||
/// If omitted then the cookie becomes a session cookie and will not be retained between sessions.
|
||||
/// </summary>
|
||||
[DefaultValue(0)]
|
||||
public long ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
43
ElectronNET.API/Entities/CookieFilter.cs
Normal file
43
ElectronNET.API/Entities/CookieFilter.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CookieFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// (optional) - Retrieves cookies which are associated with url.Empty implies retrieving cookies of all URLs.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Filters cookies by name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Retrieves cookies whose domains match or are subdomains of domains.
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Retrieves cookies whose path matches path.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Filters cookies by their Secure property.
|
||||
/// </summary>
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Filters out session or persistent cookies.
|
||||
/// </summary>
|
||||
public bool Session { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Error
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the stack.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The stack.
|
||||
/// </value>
|
||||
public string Stack { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -10,28 +10,28 @@ namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// A title for the notification, which will be shown at the top of the notification
|
||||
/// window when it is shown
|
||||
/// window when it is shown.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A subtitle for the notification, which will be displayed below the title.
|
||||
/// </summary>
|
||||
public string SubTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The body text of the notification, which will be displayed below the title or
|
||||
/// subtitle
|
||||
/// subtitle.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A subtitle for the notification, which will be displayed below the title.
|
||||
/// </summary>
|
||||
public string Subtitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to emit an OS notification noise when showing the notification
|
||||
/// Whether or not to emit an OS notification noise when showing the notification.
|
||||
/// </summary>
|
||||
public bool Silent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An icon to use in the notification
|
||||
/// An icon to use in the notification.
|
||||
/// </summary>
|
||||
public string Icon { get; set; }
|
||||
|
||||
@@ -40,6 +40,11 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public bool HasReply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timeout duration of the notification. Can be 'default' or 'never'.
|
||||
/// </summary>
|
||||
public string TimeoutType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The placeholder to write in the inline reply input field.
|
||||
/// </summary>
|
||||
@@ -50,16 +55,27 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string Sound { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
|
||||
/// </summary>
|
||||
public string Urgency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Actions to add to the notification. Please read the available actions and
|
||||
/// limitations in the NotificationAction documentation
|
||||
/// limitations in the NotificationAction documentation.
|
||||
/// </summary>
|
||||
public NotificationAction Actions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the notification is shown to the user,
|
||||
/// note this could be fired multiple times as a notification
|
||||
/// can be shown multiple times through the Show() method.
|
||||
/// A custom title for the close button of an alert. An empty string will cause the
|
||||
/// default localized text to be used.
|
||||
/// </summary>
|
||||
public string CloseButtonText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the notification is shown to the user, note this could be fired
|
||||
/// multiple times as a notification can be shown multiple times through the Show()
|
||||
/// method.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Action OnShow { get; set; }
|
||||
@@ -148,4 +164,4 @@ namespace ElectronNET.API.Entities
|
||||
Body = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,22 @@
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Controls the behavior of OpenExternal.
|
||||
/// </summary>
|
||||
public class OpenExternalOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// true to bring the opened application to the foreground. The default is true.
|
||||
/// <see langword="true"/> to bring the opened application to the foreground. The default is <see langword="true"/>.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public bool Activate { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// The working directory.
|
||||
/// </summary>
|
||||
public string WorkingDirectory { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,38 @@
|
||||
namespace ElectronNET.API
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Structure of a shortcut.
|
||||
/// </summary>
|
||||
public class ShortcutDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// The Application User Model ID. Default is empty.
|
||||
/// The Application User Model ID. Default is <see cref="string.Empty"/>.
|
||||
/// </summary>
|
||||
public string AppUserModelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The arguments to be applied to target when launching from this shortcut. Default is empty.
|
||||
/// The arguments to be applied to <see cref="Target"/> when launching from this shortcut. Default is <see cref="string.Empty"/>.
|
||||
/// </summary>
|
||||
public string Args { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The working directory. Default is empty.
|
||||
/// The working directory. Default is <see cref="string.Empty"/>.
|
||||
/// </summary>
|
||||
public string Cwd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The description of the shortcut. Default is empty.
|
||||
/// The description of the shortcut. Default is <see cref="string.Empty"/>.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the icon, can be a DLL or EXE. icon and iconIndex have to be set
|
||||
/// together.Default is empty, which uses the target's icon.
|
||||
/// The path to the icon, can be a DLL or EXE. <see cref="Icon"/> and <see cref="IconIndex"/> have to be set
|
||||
/// together. Default is <see cref="string.Empty"/>, which uses the target's icon.
|
||||
/// </summary>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The resource ID of icon when icon is a DLL or EXE. Default is 0.
|
||||
/// The resource ID of icon when <see cref="Icon"/> is a DLL or EXE. Default is 0.
|
||||
/// </summary>
|
||||
public int IconIndex { get; set; }
|
||||
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
namespace ElectronNET.API
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Defines the ShortcutLinkOperation enumeration.
|
||||
/// </summary>
|
||||
public enum ShortcutLinkOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new shortcut, overwriting if necessary.
|
||||
/// </summary>
|
||||
create,
|
||||
[Description("create")]
|
||||
Create,
|
||||
|
||||
/// <summary>
|
||||
/// Updates specified properties only on an existing shortcut.
|
||||
/// </summary>
|
||||
update,
|
||||
[Description("update")]
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// Overwrites an existing shortcut, fails if the shortcut doesn’t exist.
|
||||
/// Overwrites an existing shortcut, fails if the shortcut doesn't exist.
|
||||
/// </summary>
|
||||
replace
|
||||
[Description("replace")]
|
||||
Replace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
ElectronNET.API/Entities/ThemeSourceMode.cs
Normal file
28
ElectronNET.API/Entities/ThemeSourceMode.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the ThemeSourceMode enumeration.
|
||||
/// </summary>
|
||||
public enum ThemeSourceMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Operating system default.
|
||||
/// </summary>
|
||||
[Description("system")]
|
||||
System,
|
||||
|
||||
/// <summary>
|
||||
/// Light theme.
|
||||
/// </summary>
|
||||
[Description("light")]
|
||||
Light,
|
||||
|
||||
/// <summary>
|
||||
/// Dark theme.
|
||||
/// </summary>
|
||||
[Description("dark")]
|
||||
Dark
|
||||
}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ namespace ElectronNET.API.Entities
|
||||
|
||||
/// <summary>
|
||||
/// Whether to run Electron APIs and the specified preload script in a separate
|
||||
/// JavaScript context.Defaults to false. The context that the preload script runs
|
||||
/// JavaScript context. Defaults to false. The context that the preload script runs
|
||||
/// in will still have full access to the document and window globals but it will
|
||||
/// use its own set of JavaScript builtins (Array, Object, JSON, etc.) and will be
|
||||
/// isolated from any changes made to the global environment by the loaded page.The
|
||||
@@ -185,8 +185,8 @@ namespace ElectronNET.API.Entities
|
||||
/// Context' entry in the combo box at the top of the Console tab. This option is
|
||||
/// currently experimental and may change or be removed in future Electron releases.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public bool ContextIsolation { get; set; } = true;
|
||||
[DefaultValue(false)]
|
||||
public bool ContextIsolation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use native window.open(). Defaults to false. This option is currently experimental.
|
||||
|
||||
@@ -48,5 +48,24 @@ namespace ElectronNET.API.Extensions
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MenuItem[] AddSubmenuTypes(this MenuItem[] menuItems)
|
||||
{
|
||||
for (int index = 0; index < menuItems.Length; index++)
|
||||
{
|
||||
var menuItem = menuItems[index];
|
||||
if (menuItem?.Submenu?.Length > 0)
|
||||
{
|
||||
if(menuItem.Type == MenuType.normal)
|
||||
{
|
||||
menuItem.Type = MenuType.submenu;
|
||||
}
|
||||
|
||||
AddSubmenuTypes(menuItem.Submenu);
|
||||
}
|
||||
}
|
||||
|
||||
return menuItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
ElectronNET.API/LifetimeServiceHost.cs
Normal file
41
ElectronNET.API/LifetimeServiceHost.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class that reports if ASP.NET Core has fully started.
|
||||
/// </summary>
|
||||
internal class LifetimeServiceHost : IHostedService
|
||||
{
|
||||
public LifetimeServiceHost(IHostApplicationLifetime lifetime)
|
||||
{
|
||||
lifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
App.Instance.IsReady = true;
|
||||
|
||||
Console.WriteLine("ASP.NET Core host has fully started.");
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the application host is ready to start the service.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the application host is performing a graceful shutdown.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,8 @@ namespace ElectronNET.API
|
||||
_menuItems.Clear();
|
||||
|
||||
menuItems.AddMenuItemsId();
|
||||
menuItems.AddSubmenuTypes();
|
||||
|
||||
BridgeConnector.Socket.Emit("menu-setApplicationMenu", JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_menuItems.AddRange(menuItems);
|
||||
|
||||
@@ -83,6 +85,8 @@ namespace ElectronNET.API
|
||||
public void SetContextMenu(BrowserWindow browserWindow, MenuItem[] menuItems)
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
menuItems.AddSubmenuTypes();
|
||||
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
|
||||
if (!_contextMenuItems.ContainsKey(browserWindow.Id))
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Extensions;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -32,11 +35,95 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A `Boolean` for if the OS / Chromium currently has a dark mode enabled or is
|
||||
/// being instructed to show a dark-style UI.If you want to modify this value you
|
||||
/// should use `themeSource` below.
|
||||
/// Setting this property to <see cref="ThemeSourceMode.System"/> will remove the override and everything will be reset to the OS default. By default 'ThemeSource' is <see cref="ThemeSourceMode.System"/>.
|
||||
/// <para/>
|
||||
/// Settings this property to <see cref="ThemeSourceMode.Dark"/> will have the following effects:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="true"/> when accessed</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the dark UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the dark UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'prefers-color-scheme' CSS query will match 'dark' mode.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para/>
|
||||
/// Settings this property to <see cref="ThemeSourceMode.Light"/> will have the following effects:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="false"/> when accessed</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the light UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the light UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'prefers-color-scheme' CSS query will match 'light' mode.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// The usage of this property should align with a classic "dark mode" state machine in your application where the user has three options.
|
||||
/// <para/>
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description>Follow OS: SetThemeSource(ThemeSourceMode.System);</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Dark Mode: SetThemeSource(ThemeSourceMode.Dark);</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Light Mode: SetThemeSource(ThemeSourceMode.Light);</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// Your application should then always use <see cref="ShouldUseDarkColorsAsync"/> to determine what CSS to apply.
|
||||
/// </summary>
|
||||
/// <param name="themeSourceMode">The new ThemeSource.</param>
|
||||
public void SetThemeSource(ThemeSourceMode themeSourceMode)
|
||||
{
|
||||
var themeSource = themeSourceMode.GetDescription();
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-themeSource", themeSource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ThemeSourceMode"/> property that can be <see cref="ThemeSourceMode.System"/>, <see cref="ThemeSourceMode.Light"/> or <see cref="ThemeSourceMode.Dark"/>. It is used to override (<seealso cref="SetThemeSource"/>) and
|
||||
/// supercede the value that Chromium has chosen to use internally.
|
||||
/// </summary>
|
||||
public Task<ThemeSourceMode> GetThemeSourceAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ThemeSourceMode>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-themeSource-getCompleted", (themeSource) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("nativeTheme-themeSource-getCompleted");
|
||||
|
||||
var themeSourceValue = (ThemeSourceMode)Enum.Parse(typeof(ThemeSourceMode), (string)themeSource, true);
|
||||
|
||||
taskCompletionSource.SetResult(themeSourceValue);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-themeSource-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has a dark mode enabled or is
|
||||
/// being instructed to show a dark-style UI. If you want to modify this value you
|
||||
/// should use <see cref="SetThemeSource"/>.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<bool> ShouldUseDarkColorsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
@@ -51,5 +138,75 @@ namespace ElectronNET.API
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has high-contrast mode enabled or is
|
||||
/// being instructed to show a high-contrast UI.
|
||||
/// </summary>
|
||||
public Task<bool> ShouldUseHighContrastColorsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-shouldUseHighContrastColors-completed", (shouldUseHighContrastColors) => {
|
||||
BridgeConnector.Socket.Off("nativeTheme-shouldUseHighContrastColors-completed");
|
||||
|
||||
taskCompletionSource.SetResult((bool)shouldUseHighContrastColors);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-shouldUseHighContrastColors");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has an inverted color scheme or is
|
||||
/// being instructed to use an inverted color scheme.
|
||||
/// </summary>
|
||||
public Task<bool> ShouldUseInvertedColorSchemeAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-shouldUseInvertedColorScheme-completed", (shouldUseInvertedColorScheme) => {
|
||||
BridgeConnector.Socket.Off("nativeTheme-shouldUseInvertedColorScheme-completed");
|
||||
|
||||
taskCompletionSource.SetResult((bool)shouldUseInvertedColorScheme);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-shouldUseInvertedColorScheme");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of <see cref="ShouldUseDarkColorsAsync"/>,
|
||||
/// <see cref="ShouldUseHighContrastColorsAsync"/> or <see cref="ShouldUseInvertedColorSchemeAsync"/> has changed. You will have to check them to determine which one has changed.
|
||||
/// </summary>
|
||||
public event Action Updated
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_updated == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("nativeTheme-updated" + GetHashCode(), () =>
|
||||
{
|
||||
_updated();
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-nativeTheme-updated-event", GetHashCode());
|
||||
}
|
||||
_updated += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_updated -= value;
|
||||
|
||||
if (_updated == null)
|
||||
{
|
||||
BridgeConnector.Socket.Off("nativeTheme-updated" + GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _updated;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,15 @@ namespace ElectronNET.API
|
||||
/// </value>
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Query and modify a session's cookies.
|
||||
/// </summary>
|
||||
public Cookies Cookies { get; }
|
||||
|
||||
internal Session(int id)
|
||||
{
|
||||
Id = id;
|
||||
Cookies = new Cookies(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Extensions;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -40,17 +39,14 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Show the given file in a file manager. If possible, select the file.
|
||||
/// </summary>
|
||||
/// <param name="fullPath"></param>
|
||||
/// <returns>Whether the item was successfully shown.</returns>
|
||||
public Task<bool> ShowItemInFolderAsync(string fullPath)
|
||||
/// <param name="fullPath">The full path to the directory / file.</param>
|
||||
public Task ShowItemInFolderAsync(string fullPath)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-showItemInFolderCompleted", (success) =>
|
||||
BridgeConnector.Socket.On("shell-showItemInFolderCompleted", () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-showItemInFolderCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-showItemInFolder", fullPath);
|
||||
@@ -59,22 +55,22 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the given file in the desktop’s default manner.
|
||||
/// Open the given file in the desktop's default manner.
|
||||
/// </summary>
|
||||
/// <param name="fullPath"></param>
|
||||
/// <returns>Whether the item was successfully opened.</returns>
|
||||
public Task<bool> OpenItemAsync(string fullPath)
|
||||
/// <param name="path">The path to the directory / file.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
public Task<string> OpenPathAsync(string path)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-openItemCompleted", (success) =>
|
||||
BridgeConnector.Socket.On("shell-openPathCompleted", (errorMessage) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-openItemCompleted");
|
||||
BridgeConnector.Socket.Off("shell-openPathCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
taskCompletionSource.SetResult((string) errorMessage);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openItem", fullPath);
|
||||
BridgeConnector.Socket.Emit("shell-openPath", path);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
@@ -83,95 +79,50 @@ namespace ElectronNET.API
|
||||
/// Open the given external protocol URL in the desktop’s default manner.
|
||||
/// (For example, mailto: URLs in the user’s default mail agent).
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns>Whether an application was available to open the URL.
|
||||
/// If callback is specified, always returns true.</returns>
|
||||
public Task<bool> OpenExternalAsync(string url)
|
||||
/// <param name="url">Max 2081 characters on windows.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
public Task<string> OpenExternalAsync(string url)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-openExternalCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-openExternalCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return OpenExternalAsync(url, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the given external protocol URL in the desktop’s default manner.
|
||||
/// (For example, mailto: URLs in the user’s default mail agent).
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="options">macOS only</param>
|
||||
/// <returns>Whether an application was available to open the URL.
|
||||
/// If callback is specified, always returns true.</returns>
|
||||
public Task<bool> OpenExternalAsync(string url, OpenExternalOptions options)
|
||||
/// <param name="url">Max 2081 characters on windows.</param>
|
||||
/// <param name="options">Controls the behavior of OpenExternal.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
public Task<string> OpenExternalAsync(string url, OpenExternalOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-openExternalCompleted", (success) =>
|
||||
BridgeConnector.Socket.On("shell-openExternalCompleted", (error) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-openExternalCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
taskCompletionSource.SetResult((string) error);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url, JObject.FromObject(options, _jsonSerializer));
|
||||
if (options == null)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url, JObject.FromObject(options, _jsonSerializer));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the given external protocol URL in the desktop’s default manner.
|
||||
/// (For example, mailto: URLs in the user’s default mail agent).
|
||||
/// Move the given file to trash and returns a <see cref="bool"/> status for the operation.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="options">macOS only</param>
|
||||
/// <param name="errorAction">Action to get the error message.</param>
|
||||
/// <returns>Whether an application was available to open the URL.
|
||||
/// If callback is specified, always returns true.</returns>
|
||||
public Task<bool> OpenExternalAsync(string url, OpenExternalOptions options, Action<Error> errorAction)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-openExternalCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-openExternalCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Off("shell-openExternalCallback");
|
||||
BridgeConnector.Socket.On("shell-openExternalCallback", (args) => {
|
||||
var urlKey = ((JArray)args).First.ToString();
|
||||
var error = ((JArray)args).Last.ToObject<Error>();
|
||||
|
||||
if(_openExternalCallbacks.ContainsKey(urlKey))
|
||||
{
|
||||
_openExternalCallbacks[urlKey](error);
|
||||
}
|
||||
});
|
||||
|
||||
_openExternalCallbacks.Add(url, errorAction);
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url, JObject.FromObject(options, _jsonSerializer), true);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private Dictionary<string, Action<Error>> _openExternalCallbacks = new Dictionary<string, Action<Error>>();
|
||||
|
||||
/// <summary>
|
||||
/// Move the given file to trash and returns a boolean status for the operation.
|
||||
/// </summary>
|
||||
/// <param name="fullPath"></param>
|
||||
/// <param name="fullPath">The full path to the directory / file.</param>
|
||||
/// <param name="deleteOnFail">Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume.</param>
|
||||
/// <returns> Whether the item was successfully moved to the trash.</returns>
|
||||
public Task<bool> MoveItemToTrashAsync(string fullPath)
|
||||
public Task<bool> MoveItemToTrashAsync(string fullPath, bool deleteOnFail)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
@@ -179,10 +130,10 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-moveItemToTrashCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
taskCompletionSource.SetResult((bool) success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-moveItemToTrash", fullPath);
|
||||
BridgeConnector.Socket.Emit("shell-moveItemToTrash", fullPath, deleteOnFail);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
@@ -198,9 +149,9 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Creates or updates a shortcut link at shortcutPath.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="shortcutPath">The path to the shortcut.</param>
|
||||
/// <param name="operation">Default is <see cref="ShortcutLinkOperation.Create"/></param>
|
||||
/// <param name="options">Structure of a shortcut.</param>
|
||||
/// <returns>Whether the shortcut was created successfully.</returns>
|
||||
public Task<bool> WriteShortcutLinkAsync(string shortcutPath, ShortcutLinkOperation operation, ShortcutDetails options)
|
||||
{
|
||||
@@ -210,21 +161,20 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-writeShortcutLinkCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
taskCompletionSource.SetResult((bool) success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-writeShortcutLink", shortcutPath, operation.ToString(), JObject.FromObject(options, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("shell-writeShortcutLink", shortcutPath, operation.GetDescription(), JObject.FromObject(options, _jsonSerializer));
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the shortcut link at shortcutPath.
|
||||
///
|
||||
/// An exception will be thrown when any error happens.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="shortcutPath">The path tot the shortcut.</param>
|
||||
/// <returns><see cref="ShortcutDetails"/> of the shortcut.</returns>
|
||||
public Task<ShortcutDetails> ReadShortcutLinkAsync(string shortcutPath)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ShortcutDetails>();
|
||||
@@ -233,7 +183,10 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-readShortcutLinkCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((ShortcutDetails)shortcutDetails);
|
||||
var shortcutObject = shortcutDetails as JObject;
|
||||
var details = shortcutObject?.ToObject<ShortcutDetails>();
|
||||
|
||||
taskCompletionSource.SetResult(details);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-readShortcutLink", shortcutPath);
|
||||
@@ -241,11 +194,11 @@ namespace ElectronNET.API
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
private readonly JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -32,6 +33,11 @@ namespace ElectronNET.API
|
||||
|
||||
if (HybridSupport.IsElectronActive)
|
||||
{
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
services.AddHostedService<LifetimeServiceHost>();
|
||||
});
|
||||
|
||||
// check for the content folder if its exists in base director otherwise no need to include
|
||||
// It was used before because we are publishing the project which copies everything to bin folder and contentroot wwwroot was folder there.
|
||||
// now we have implemented the live reload if app is run using /watch then we need to use the default project path.
|
||||
@@ -49,4 +55,4 @@ namespace ElectronNET.API
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user