mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-02-13 13:44:57 +00:00
implement Demo App sections: Dialogs, Menu, Tray, Shell, CrashHang, Notification, Shortcuts etc. Fix some API bugs and implement GlobalShortcut-, Shell- and WebContents-API.
This commit is contained in:
@@ -156,7 +156,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
if (_unresponsive == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("browserWindow-unresponsive", () =>
|
||||
BridgeConnector.Socket.On("browserWindow-unresponsive" + Id, () =>
|
||||
{
|
||||
_unresponsive();
|
||||
});
|
||||
@@ -182,7 +182,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
if (_responsive == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("browserWindow-responsive", () =>
|
||||
BridgeConnector.Socket.On("browserWindow-responsive" + Id, () =>
|
||||
{
|
||||
_responsive();
|
||||
});
|
||||
@@ -807,6 +807,7 @@ namespace ElectronNET.API
|
||||
|
||||
internal BrowserWindow(int id) {
|
||||
Id = id;
|
||||
WebContents = new WebContents(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2148,6 +2149,11 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.Emit("browserWindowSetVibrancy", Id, type.GetDescription());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render and control web pages.
|
||||
/// </summary>
|
||||
public WebContents WebContents { get; internal set; }
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
|
||||
@@ -36,5 +36,15 @@
|
||||
/// Add icons and context menus to the system’s notification area.
|
||||
/// </summary>
|
||||
public static Tray Tray { get { return Tray.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Detect keyboard events when the application does not have keyboard focus.
|
||||
/// </summary>
|
||||
public static GlobalShortcut GlobalShortcut { get { return GlobalShortcut.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Manage files and URLs using their default applications.
|
||||
/// </summary>
|
||||
public static Shell Shell { get { return Shell.Instance; } }
|
||||
}
|
||||
}
|
||||
|
||||
15
ElectronNET.API/Entities/DevToolsMode.cs
Normal file
15
ElectronNET.API/Entities/DevToolsMode.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the devtools with specified dock state, can be right, bottom, undocked,
|
||||
/// detach.Defaults to last used dock state.In undocked mode it's possible to dock
|
||||
/// back.In detach mode it's not.
|
||||
/// </summary>
|
||||
public enum DevToolsMode
|
||||
{
|
||||
right,
|
||||
bottom,
|
||||
undocked,
|
||||
detach
|
||||
}
|
||||
}
|
||||
7
ElectronNET.API/Entities/Error.cs
Normal file
7
ElectronNET.API/Entities/Error.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class Error
|
||||
{
|
||||
public string Stack { get; set; }
|
||||
}
|
||||
}
|
||||
16
ElectronNET.API/Entities/OpenDevToolsOptions.cs
Normal file
16
ElectronNET.API/Entities/OpenDevToolsOptions.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class OpenDevToolsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the devtools with specified dock state, can be right, bottom, undocked,
|
||||
/// detach.Defaults to last used dock state.In undocked mode it's possible to dock
|
||||
/// back.In detach mode it's not.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public DevToolsMode Mode { get; set; }
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/OpenExternalOptions.cs
Normal file
13
ElectronNET.API/Entities/OpenExternalOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class OpenExternalOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// true to bring the opened application to the foreground. The default is true.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public bool Activate { get; set; } = true;
|
||||
}
|
||||
}
|
||||
41
ElectronNET.API/Entities/ShortcutDetails.cs
Normal file
41
ElectronNET.API/Entities/ShortcutDetails.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
public class ShortcutDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// The Application User Model ID. Default is empty.
|
||||
/// </summary>
|
||||
public string AppUserModelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The arguments to be applied to target when launching from this shortcut. Default is empty.
|
||||
/// </summary>
|
||||
public string Args { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The working directory. Default is empty.
|
||||
/// </summary>
|
||||
public string Cwd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The description of the shortcut. Default is 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.
|
||||
/// </summary>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The resource ID of icon when icon is a DLL or EXE. Default is 0.
|
||||
/// </summary>
|
||||
public int IconIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The target to launch from this shortcut.
|
||||
/// </summary>
|
||||
public string Target { get; set; }
|
||||
}
|
||||
}
|
||||
20
ElectronNET.API/Entities/ShortcutLinkOperation.cs
Normal file
20
ElectronNET.API/Entities/ShortcutLinkOperation.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
public enum ShortcutLinkOperation
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new shortcut, overwriting if necessary.
|
||||
/// </summary>
|
||||
create,
|
||||
|
||||
/// <summary>
|
||||
/// Updates specified properties only on an existing shortcut.
|
||||
/// </summary>
|
||||
update,
|
||||
|
||||
/// <summary>
|
||||
/// Overwrites an existing shortcut, fails if the shortcut doesn’t exist.
|
||||
/// </summary>
|
||||
replace
|
||||
}
|
||||
}
|
||||
98
ElectronNET.API/GlobalShortcut.cs
Normal file
98
ElectronNET.API/GlobalShortcut.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Detect keyboard events when the application does not have keyboard focus.
|
||||
/// </summary>
|
||||
public sealed class GlobalShortcut
|
||||
{
|
||||
private static GlobalShortcut _globalShortcut;
|
||||
|
||||
internal GlobalShortcut() { }
|
||||
|
||||
internal static GlobalShortcut Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_globalShortcut == null)
|
||||
{
|
||||
_globalShortcut = new GlobalShortcut();
|
||||
}
|
||||
|
||||
return _globalShortcut;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, Action> _shortcuts = new Dictionary<string, Action>();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global shortcut of accelerator.
|
||||
/// The callback is called when the registered shortcut is pressed by the user.
|
||||
///
|
||||
/// When the accelerator is already taken by other applications, this call will
|
||||
/// silently fail.This behavior is intended by operating systems, since they don’t
|
||||
/// want applications to fight for global shortcuts.
|
||||
/// </summary>
|
||||
public void Register(string accelerator, Action function)
|
||||
{
|
||||
if (!_shortcuts.ContainsKey(accelerator))
|
||||
{
|
||||
_shortcuts.Add(accelerator, function);
|
||||
|
||||
BridgeConnector.Socket.Off("globalShortcut-pressed");
|
||||
BridgeConnector.Socket.On("globalShortcut-pressed", (shortcut) =>
|
||||
{
|
||||
if (_shortcuts.ContainsKey(shortcut.ToString()))
|
||||
{
|
||||
_shortcuts[shortcut.ToString()]();
|
||||
}
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("globalShortcut-register", accelerator);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the accelerator is already taken by other applications,
|
||||
/// this call will still return false. This behavior is intended by operating systems,
|
||||
/// since they don’t want applications to fight for global shortcuts.
|
||||
/// </summary>
|
||||
/// <returns>Whether this application has registered accelerator.</returns>
|
||||
public Task<bool> IsRegisteredAsync(string accelerator)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("globalShortcut-isRegisteredCompleted", (isRegistered) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("globalShortcut-isRegisteredCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)isRegistered);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("globalShortcut-isRegistered", accelerator);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the global shortcut of accelerator.
|
||||
/// </summary>
|
||||
public void Unregister(string accelerator)
|
||||
{
|
||||
_shortcuts.Remove(accelerator);
|
||||
BridgeConnector.Socket.Emit("globalShortcut-unregister", accelerator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all of the global shortcuts.
|
||||
/// </summary>
|
||||
public void UnregisterAll()
|
||||
{
|
||||
_shortcuts.Clear();
|
||||
BridgeConnector.Socket.Emit("globalShortcut-unregisterAll");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,25 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.On(channel, listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process synchronously via channel,
|
||||
/// you can also send arbitrary arguments.
|
||||
///
|
||||
/// Note: Sending a synchronous message will block the whole renderer process,
|
||||
/// unless you know what you are doing you should never use it.
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="listener"></param>
|
||||
public void OnSync(string channel, Func<object, object> listener)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("registerSyncIpcMainChannel", channel);
|
||||
BridgeConnector.Socket.On(channel, (args) => {
|
||||
var result = listener(args);
|
||||
|
||||
BridgeConnector.Socket.Emit(channel + "Sync", result);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a one time listener method for the event. This listener is invoked only
|
||||
/// the next time a message is sent to channel, after which it is removed.
|
||||
|
||||
@@ -4,6 +4,9 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using ElectronNET.API.Extensions;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -26,22 +29,55 @@ namespace ElectronNET.API
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<MenuItem> Items { get { return _items.AsReadOnly(); } }
|
||||
private List<MenuItem> _items = new List<MenuItem>();
|
||||
public IReadOnlyCollection<MenuItem> MenuItems { get { return _menuItems.AsReadOnly(); } }
|
||||
private List<MenuItem> _menuItems = new List<MenuItem>();
|
||||
|
||||
public void SetApplicationMenu(MenuItem[] menuItems)
|
||||
{
|
||||
_menuItems.Clear();
|
||||
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("menu-setApplicationMenu", JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_items.AddRange(menuItems);
|
||||
_menuItems.AddRange(menuItems);
|
||||
|
||||
BridgeConnector.Socket.Off("menuItemClicked");
|
||||
BridgeConnector.Socket.On("menuItemClicked", (id) => {
|
||||
MenuItem menuItem = _items.GetMenuItem(id.ToString());
|
||||
menuItem?.Click();
|
||||
MenuItem menuItem = _menuItems.GetMenuItem(id.ToString());
|
||||
menuItem.Click?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<int, ReadOnlyCollection<MenuItem>> ContextMenuItems { get; internal set; }
|
||||
private Dictionary<int, List<MenuItem>> _contextMenuItems = new Dictionary<int, List<MenuItem>>();
|
||||
|
||||
public void SetContextMenu(BrowserWindow browserWindow, MenuItem[] menuItems)
|
||||
{
|
||||
if (!_contextMenuItems.ContainsKey(browserWindow.Id))
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_contextMenuItems.Add(browserWindow.Id, menuItems.ToList());
|
||||
|
||||
var x = _contextMenuItems.ToDictionary(kv => kv.Key, kv => kv.Value.AsReadOnly());
|
||||
ContextMenuItems = new ReadOnlyDictionary<int, ReadOnlyCollection<MenuItem>>(x);
|
||||
|
||||
BridgeConnector.Socket.Off("contextMenuItemClicked");
|
||||
BridgeConnector.Socket.On("contextMenuItemClicked", (results) =>
|
||||
{
|
||||
var id = ((JArray)results).First.ToString();
|
||||
var browserWindowId = (int)((JArray)results).Last;
|
||||
|
||||
MenuItem menuItem = _contextMenuItems[browserWindowId].GetMenuItem(id);
|
||||
menuItem.Click?.Invoke();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void ContextMenuPopup(BrowserWindow browserWindow)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("menu-contextMenuPopup", browserWindow.Id);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
|
||||
244
ElectronNET.API/Shell.cs
Normal file
244
ElectronNET.API/Shell.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage files and URLs using their default applications.
|
||||
/// </summary>
|
||||
public sealed class Shell
|
||||
{
|
||||
private static Shell _shell;
|
||||
|
||||
internal Shell() { }
|
||||
|
||||
internal static Shell Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_shell == null)
|
||||
{
|
||||
_shell = new Shell();
|
||||
}
|
||||
|
||||
return _shell;
|
||||
}
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-showItemInFolderCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-showItemInFolderCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-showItemInFolder", fullPath);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-openItemCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-openItemCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openItem", fullPath);
|
||||
|
||||
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).
|
||||
/// </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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
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, 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).
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="options">macOS only</param>
|
||||
/// <param name="action">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, Action<Error> action)
|
||||
{
|
||||
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, action);
|
||||
|
||||
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>
|
||||
/// <returns> Whether the item was successfully moved to the trash.</returns>
|
||||
public Task<bool> MoveItemToTrashAsync(string fullPath)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-moveItemToTrashCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-moveItemToTrashCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-moveItemToTrash", fullPath);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play the beep sound.
|
||||
/// </summary>
|
||||
public void Beep()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("shell-beep");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates or updates a shortcut link at shortcutPath.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns>Whether the shortcut was created successfully.</returns>
|
||||
public Task<bool> WriteShortcutLinkAsync(string shortcutPath, ShortcutLinkOperation operation, ShortcutDetails options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-writeShortcutLinkCompleted", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-writeShortcutLinkCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-writeShortcutLink", shortcutPath, operation.ToString(), 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>
|
||||
public Task<ShortcutDetails> ReadShortcutLinkAsync(string shortcutPath)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ShortcutDetails>();
|
||||
|
||||
BridgeConnector.Socket.On("shell-readShortcutLinkCompleted", (shortcutDetails) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("shell-readShortcutLinkCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((ShortcutDetails)shortcutDetails);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-readShortcutLink", shortcutPath);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -199,6 +199,11 @@ namespace ElectronNET.API
|
||||
public IReadOnlyCollection<MenuItem> Items { get { return _items.AsReadOnly(); } }
|
||||
private List<MenuItem> _items = new List<MenuItem>();
|
||||
|
||||
public void Show(string image, MenuItem menuItem)
|
||||
{
|
||||
Show(image, new MenuItem[] { menuItem });
|
||||
}
|
||||
|
||||
public void Show(string image, MenuItem[] menuItems)
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
@@ -218,6 +223,7 @@ namespace ElectronNET.API
|
||||
public void Destroy()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("tray-destroy");
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
99
ElectronNET.API/WebContents.cs
Normal file
99
ElectronNET.API/WebContents.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Render and control web pages.
|
||||
/// </summary>
|
||||
public class WebContents
|
||||
{
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the renderer process crashes or is killed.
|
||||
/// </summary>
|
||||
public event Action<bool> OnCrashed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_crashed == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("webContents-crashed" + Id, (killed) =>
|
||||
{
|
||||
_crashed((bool)killed);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-webContents-crashed", Id);
|
||||
}
|
||||
_crashed += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_crashed -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<bool> _crashed;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the navigation is done, i.e. the spinner of the tab has
|
||||
/// stopped spinning, and the onload event was dispatched.
|
||||
/// </summary>
|
||||
public event Action OnDidFinishLoad
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_didFinishLoad == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("webContents-didFinishLoad" + Id, () =>
|
||||
{
|
||||
_didFinishLoad();
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-webContents-didFinishLoad", Id);
|
||||
}
|
||||
_didFinishLoad += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_didFinishLoad -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _didFinishLoad;
|
||||
|
||||
internal WebContents(int id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the devtools.
|
||||
/// </summary>
|
||||
public void OpenDevTools()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContentsOpenDevTools", Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the devtools.
|
||||
/// </summary>
|
||||
/// <param name="openDevToolsOptions"></param>
|
||||
public void OpenDevTools(OpenDevToolsOptions openDevToolsOptions)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContentsOpenDevTools", Id, JObject.FromObject(openDevToolsOptions, _jsonSerializer));
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user