diff --git a/ElectronNET.API/Clipboard.cs b/ElectronNET.API/Clipboard.cs
new file mode 100644
index 0000000..06f05fc
--- /dev/null
+++ b/ElectronNET.API/Clipboard.cs
@@ -0,0 +1,240 @@
+using ElectronNET.API.Entities;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace ElectronNET.API
+{
+ ///
+ /// Perform copy and paste operations on the system clipboard.
+ ///
+ public sealed class Clipboard
+ {
+ private static Clipboard _clipboard;
+
+ internal Clipboard() { }
+
+ internal static Clipboard Instance
+ {
+ get
+ {
+ if (_clipboard == null)
+ {
+ _clipboard = new Clipboard();
+ }
+
+ return _clipboard;
+ }
+ }
+
+ ///
+ /// Read the content in the clipboard as plain text.
+ ///
+ ///
+ /// The content in the clipboard as plain text.
+ public Task ReadTextAsync(string type = "")
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-readText-Completed", (text) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-readText-Completed");
+
+ taskCompletionSource.SetResult(text.ToString());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-readText", type);
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// Writes the text into the clipboard as plain text.
+ ///
+ ///
+ ///
+ public void WriteText(string text, string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-writeText", text, type);
+ }
+
+ ///
+ /// The content in the clipboard as markup.
+ ///
+ ///
+ ///
+ public Task ReadHTMLAsync(string type = "")
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-readHTML-Completed", (text) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-readHTML-Completed");
+
+ taskCompletionSource.SetResult(text.ToString());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-readHTML", type);
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// Writes markup to the clipboard.
+ ///
+ ///
+ ///
+ public void WriteHTML(string markup, string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-writeHTML", markup, type);
+ }
+
+ ///
+ /// The content in the clipboard as RTF.
+ ///
+ ///
+ ///
+ public Task ReadRTFAsync(string type = "")
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-readRTF-Completed", (text) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-readRTF-Completed");
+
+ taskCompletionSource.SetResult(text.ToString());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-readRTF", type);
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// Writes the text into the clipboard in RTF.
+ ///
+ ///
+ ///
+ public void WriteRTF(string text, string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-writeHTML", text, type);
+ }
+
+ ///
+ /// Returns an Object containing title and url keys representing
+ /// the bookmark in the clipboard. The title and url values will
+ /// be empty strings when the bookmark is unavailable.
+ ///
+ ///
+ public Task ReadBookmarkAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-readBookmark-Completed", (bookmark) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-readBookmark-Completed");
+
+ taskCompletionSource.SetResult(((JObject)bookmark).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-readBookmark");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// Writes the title and url into the clipboard as a bookmark.
+ ///
+ /// Note: Most apps on Windows don’t support pasting bookmarks
+ /// into them so you can use clipboard.write to write both a
+ /// bookmark and fallback text to the clipboard.
+ ///
+ ///
+ ///
+ ///
+ public void WriteBookmark(string title, string url, string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-writeBookmark", title, url, type);
+ }
+
+ ///
+ /// macOS: The text on the find pasteboard. This method uses synchronous IPC
+ /// when called from the renderer process. The cached value is reread from the
+ /// find pasteboard whenever the application is activated.
+ ///
+ ///
+ public Task ReadFindTextAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-readFindText-Completed", (text) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-readFindText-Completed");
+
+ taskCompletionSource.SetResult(text.ToString());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-readFindText");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// macOS: Writes the text into the find pasteboard as plain text. This method uses
+ /// synchronous IPC when called from the renderer process.
+ ///
+ ///
+ public void WriteFindText(string text)
+ {
+ BridgeConnector.Socket.Emit("clipboard-writeFindText", text);
+ }
+
+ ///
+ /// Clears the clipboard content.
+ ///
+ ///
+ public void Clear(string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-clear", type);
+ }
+
+ ///
+ /// An array of supported formats for the clipboard type.
+ ///
+ ///
+ ///
+ public Task AvailableFormatsAsync(string type = "")
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("clipboard-availableFormats-Completed", (formats) =>
+ {
+ BridgeConnector.Socket.Off("clipboard-availableFormats-Completed");
+
+ taskCompletionSource.SetResult(((JArray)formats).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("clipboard-availableFormats", type);
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// Writes data to the clipboard.
+ ///
+ ///
+ ///
+ public void Write(Data data, string type = "")
+ {
+ BridgeConnector.Socket.Emit("clipboard-write", JObject.FromObject(data, _jsonSerializer), type);
+ }
+
+ private JsonSerializer _jsonSerializer = new JsonSerializer()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Electron.cs b/ElectronNET.API/Electron.cs
index 6e42e27..8e273d7 100644
--- a/ElectronNET.API/Electron.cs
+++ b/ElectronNET.API/Electron.cs
@@ -46,5 +46,15 @@
/// Manage files and URLs using their default applications.
///
public static Shell Shell { get { return Shell.Instance; } }
+
+ ///
+ /// Retrieve information about screen size, displays, cursor position, etc.
+ ///
+ public static Screen Screen { get { return Screen.Instance; } }
+
+ ///
+ /// Perform copy and paste operations on the system clipboard.
+ ///
+ public static Clipboard Clipboard { get { return Clipboard.Instance; } }
}
}
diff --git a/ElectronNET.API/Entities/Data.cs b/ElectronNET.API/Entities/Data.cs
new file mode 100644
index 0000000..06ead56
--- /dev/null
+++ b/ElectronNET.API/Entities/Data.cs
@@ -0,0 +1,14 @@
+namespace ElectronNET.API.Entities
+{
+ public class Data
+ {
+ public string Text { get; set; }
+ public string Html { get; set; }
+ public string Rtf { get; set; }
+
+ ///
+ /// The title of the url at text.
+ ///
+ public string Bookmark { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/Display.cs b/ElectronNET.API/Entities/Display.cs
new file mode 100644
index 0000000..0e2b311
--- /dev/null
+++ b/ElectronNET.API/Entities/Display.cs
@@ -0,0 +1,50 @@
+using Newtonsoft.Json;
+
+namespace ElectronNET.API.Entities
+{
+ ///
+ ///
+ ///
+ public class Display
+ {
+ ///
+ ///
+ ///
+ public Rectangle Bounds { get; set; }
+
+ ///
+ /// Unique identifier associated with the display.
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees.
+ ///
+ public int Rotation { get; set; }
+
+ ///
+ /// Output device's pixel scale factor.
+ ///
+ public int ScaleFactor { get; set; }
+
+ ///
+ ///
+ ///
+ public Size Size { get; set; }
+
+ ///
+ /// Can be available, unavailable, unknown.
+ ///
+ public string TouchSupport { get; set; }
+
+ ///
+ ///
+ ///
+ public Rectangle WorkArea { get; set; }
+
+ ///
+ ///
+ ///
+ public Size WorkAreaSize { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/Point.cs b/ElectronNET.API/Entities/Point.cs
new file mode 100644
index 0000000..265237a
--- /dev/null
+++ b/ElectronNET.API/Entities/Point.cs
@@ -0,0 +1,8 @@
+namespace ElectronNET.API.Entities
+{
+ public class Point
+ {
+ public int X { get; set; }
+ public int Y { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/PrintToPDFOptions.cs b/ElectronNET.API/Entities/PrintToPDFOptions.cs
new file mode 100644
index 0000000..53d24a8
--- /dev/null
+++ b/ElectronNET.API/Entities/PrintToPDFOptions.cs
@@ -0,0 +1,32 @@
+namespace ElectronNET.API.Entities
+{
+ public class PrintToPDFOptions
+ {
+ ///
+ /// Specifies the type of margins to use. Uses 0 for default margin, 1 for no
+ /// margin, and 2 for minimum margin.
+ ///
+ public int MarginsType { get; set; }
+
+ ///
+ /// Specify page size of the generated PDF. Can be A3, A4, A5, Legal, Letter,
+ /// Tabloid or an Object containing height and width in microns.
+ ///
+ public string PageSize { get; set; }
+
+ ///
+ /// Whether to print CSS backgrounds.
+ ///
+ public bool PrintBackground { get; set; }
+
+ ///
+ /// Whether to print selection only.
+ ///
+ public bool PrintSelectionOnly { get; set; }
+
+ ///
+ /// true for landscape, false for portrait.
+ ///
+ public bool Landscape { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/ReadBookmark.cs b/ElectronNET.API/Entities/ReadBookmark.cs
new file mode 100644
index 0000000..76bc611
--- /dev/null
+++ b/ElectronNET.API/Entities/ReadBookmark.cs
@@ -0,0 +1,8 @@
+namespace ElectronNET.API.Entities
+{
+ public class ReadBookmark
+ {
+ public string Title { get; set; }
+ public string Url { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/Entities/Size.cs b/ElectronNET.API/Entities/Size.cs
index 459428a..35b0a0d 100644
--- a/ElectronNET.API/Entities/Size.cs
+++ b/ElectronNET.API/Entities/Size.cs
@@ -1,9 +1,18 @@
namespace ElectronNET.API.Entities
{
+ ///
+ ///
+ ///
public class Size
{
+ ///
+ ///
+ ///
public int Width { get; set; }
+ ///
+ ///
+ ///
public int Height { get; set; }
}
}
\ No newline at end of file
diff --git a/ElectronNET.API/Extensions/MenuItemExtensions.cs b/ElectronNET.API/Extensions/MenuItemExtensions.cs
index 0ca7282..6644bd1 100644
--- a/ElectronNET.API/Extensions/MenuItemExtensions.cs
+++ b/ElectronNET.API/Extensions/MenuItemExtensions.cs
@@ -17,7 +17,7 @@ namespace ElectronNET.API.Extensions
AddMenuItemsId(menuItem.Submenu);
}
- if (string.IsNullOrEmpty(menuItem.Id))
+ if (string.IsNullOrEmpty(menuItem.Id) && menuItem.Click != null)
{
menuItem.Id = Guid.NewGuid().ToString();
}
diff --git a/ElectronNET.API/IpcMain.cs b/ElectronNET.API/IpcMain.cs
index 48f9713..ee8c2dd 100644
--- a/ElectronNET.API/IpcMain.cs
+++ b/ElectronNET.API/IpcMain.cs
@@ -2,6 +2,9 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
namespace ElectronNET.API
{
@@ -36,7 +39,35 @@ namespace ElectronNET.API
public void On(string channel, Action listener)
{
BridgeConnector.Socket.Emit("registerIpcMainChannel", channel);
- BridgeConnector.Socket.On(channel, listener);
+ BridgeConnector.Socket.On(channel, (args) =>
+ {
+ List objectArray = FormatArguments(args);
+
+ if(objectArray.Count == 1)
+ {
+ listener(objectArray.First());
+ }
+ else
+ {
+ listener(objectArray);
+ }
+ });
+ }
+
+ private List FormatArguments(object args)
+ {
+ List objectArray = ((JArray)args).ToObject().ToList();
+
+ for (int index = 0; index < objectArray.Count; index++)
+ {
+ var item = objectArray[index];
+ if (item == null)
+ {
+ objectArray.Remove(item);
+ }
+ }
+
+ return objectArray;
}
///
@@ -52,8 +83,18 @@ namespace ElectronNET.API
{
BridgeConnector.Socket.Emit("registerSyncIpcMainChannel", channel);
BridgeConnector.Socket.On(channel, (args) => {
- var result = listener(args);
+ List objectArray = FormatArguments(args);
+ object parameter;
+ if (objectArray.Count == 1)
+ {
+ parameter = objectArray.First();
+ }
+ else
+ {
+ parameter = objectArray;
+ }
+ var result = listener(parameter);
BridgeConnector.Socket.Emit(channel + "Sync", result);
});
}
@@ -67,7 +108,19 @@ namespace ElectronNET.API
public void Once(string channel, Action listener)
{
BridgeConnector.Socket.Emit("registerOnceIpcMainChannel", channel);
- BridgeConnector.Socket.On(channel, listener);
+ BridgeConnector.Socket.On(channel, (args) =>
+ {
+ List objectArray = FormatArguments(args);
+
+ if (objectArray.Count == 1)
+ {
+ listener(objectArray.First());
+ }
+ else
+ {
+ listener(objectArray);
+ }
+ });
}
///
@@ -90,7 +143,32 @@ namespace ElectronNET.API
/// Arguments data.
public void Send(BrowserWindow browserWindow, string channel, params object[] data)
{
- BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data);
+ List jobjects = new List();
+ List jarrays = new List();
+ List objects = new List();
+
+ foreach (var parameterObject in data)
+ {
+ if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
+ {
+ jarrays.Add(JArray.FromObject(parameterObject, _jsonSerializer));
+ } else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
+ {
+ jobjects.Add(JObject.FromObject(parameterObject, _jsonSerializer));
+ } else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
+ {
+ objects.Add(parameterObject);
+ }
+ }
+
+ if(jobjects.Count > 0 || jarrays.Count > 0)
+ {
+ BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, jarrays.ToArray(), jobjects.ToArray(), objects.ToArray());
+ }
+ else
+ {
+ BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data);
+ }
}
private JsonSerializer _jsonSerializer = new JsonSerializer()
diff --git a/ElectronNET.API/Screen.cs b/ElectronNET.API/Screen.cs
new file mode 100644
index 0000000..1e9153c
--- /dev/null
+++ b/ElectronNET.API/Screen.cs
@@ -0,0 +1,243 @@
+using ElectronNET.API.Entities;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Threading.Tasks;
+
+namespace ElectronNET.API
+{
+ ///
+ /// Retrieve information about screen size, displays, cursor position, etc.
+ ///
+ public sealed class Screen
+ {
+ ///
+ /// Emitted when an new Display has been added.
+ ///
+ public event Action OnDisplayAdded
+ {
+ add
+ {
+ if (_onDisplayAdded == null)
+ {
+ BridgeConnector.Socket.On("screen-display-added-event" + GetHashCode(), (display) =>
+ {
+ _onDisplayAdded(((JObject)display).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("register-screen-display-added", GetHashCode());
+ }
+ _onDisplayAdded += value;
+ }
+ remove
+ {
+ _onDisplayAdded -= value;
+ }
+ }
+
+ private event Action _onDisplayAdded;
+
+ ///
+ /// Emitted when oldDisplay has been removed.
+ ///
+ public event Action OnDisplayRemoved
+ {
+ add
+ {
+ if (_onDisplayRemoved == null)
+ {
+ BridgeConnector.Socket.On("screen-display-removed-event" + GetHashCode(), (display) =>
+ {
+ _onDisplayRemoved(((JObject)display).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("register-screen-display-removed", GetHashCode());
+ }
+ _onDisplayRemoved += value;
+ }
+ remove
+ {
+ _onDisplayRemoved -= value;
+ }
+ }
+
+ private event Action _onDisplayRemoved;
+
+ ///
+ /// Emitted when one or more metrics change in a display.
+ /// The changedMetrics is an array of strings that describe the changes.
+ /// Possible changes are bounds, workArea, scaleFactor and rotation.
+ ///
+ public event Action OnDisplayMetricsChanged
+ {
+ add
+ {
+ if (_onDisplayMetricsChanged == null)
+ {
+ BridgeConnector.Socket.On("screen-display-metrics-changed-event" + GetHashCode(), (args) =>
+ {
+ var display = ((JArray)args).First.ToObject();
+ var metrics = ((JArray)args).Last.ToObject();
+
+ _onDisplayMetricsChanged(display, metrics);
+ });
+
+ BridgeConnector.Socket.Emit("register-screen-display-metrics-changed", GetHashCode());
+ }
+ _onDisplayMetricsChanged += value;
+ }
+ remove
+ {
+ _onDisplayMetricsChanged -= value;
+ }
+ }
+
+ private event Action _onDisplayMetricsChanged;
+
+ private static Screen _screen;
+
+ internal Screen() { }
+
+ internal static Screen Instance
+ {
+ get
+ {
+ if (_screen == null)
+ {
+ _screen = new Screen();
+ }
+
+ return _screen;
+ }
+ }
+
+ ///
+ /// The current absolute position of the mouse pointer.
+ ///
+ ///
+ public Task GetCursorScreenPointAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getCursorScreenPointCompleted", (point) =>
+ {
+ BridgeConnector.Socket.Off("screen-getCursorScreenPointCompleted");
+
+ taskCompletionSource.SetResult(((JObject)point).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("screen-getCursorScreenPoint");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// macOS: The height of the menu bar in pixels.
+ ///
+ /// The height of the menu bar in pixels.
+ public Task GetMenuBarHeightAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getMenuBarHeightCompleted", (height) =>
+ {
+ BridgeConnector.Socket.Off("screen-getMenuBarHeightCompleted");
+
+ taskCompletionSource.SetResult(int.Parse(height.ToString()));
+ });
+
+ BridgeConnector.Socket.Emit("screen-getMenuBarHeight");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// The primary display.
+ ///
+ ///
+ public Task GetPrimaryDisplayAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getPrimaryDisplayCompleted", (display) =>
+ {
+ BridgeConnector.Socket.Off("screen-getPrimaryDisplayCompleted");
+
+ taskCompletionSource.SetResult(((JObject)display).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("screen-getPrimaryDisplay");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// An array of displays that are currently available.
+ ///
+ /// An array of displays that are currently available.
+ public Task GetAllDisplaysAsync()
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getAllDisplaysCompleted", (displays) =>
+ {
+ BridgeConnector.Socket.Off("screen-getAllDisplaysCompleted");
+
+ taskCompletionSource.SetResult(((JArray)displays).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("screen-getAllDisplays");
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// The display nearest the specified point.
+ ///
+ /// The display nearest the specified point.
+ public Task GetDisplayNearestPointAsync(Point point)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getDisplayNearestPointCompleted", (display) =>
+ {
+ BridgeConnector.Socket.Off("screen-getDisplayNearestPointCompleted");
+
+ taskCompletionSource.SetResult(((JObject)display).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("screen-getDisplayNearestPoint", JObject.FromObject(point, _jsonSerializer));
+
+ return taskCompletionSource.Task;
+ }
+
+ ///
+ /// The display that most closely intersects the provided bounds.
+ ///
+ ///
+ /// The display that most closely intersects the provided bounds.
+ public Task GetDisplayMatchingAsync(Rectangle rectangle)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("screen-getDisplayMatching", (display) =>
+ {
+ BridgeConnector.Socket.Off("screen-getDisplayMatching");
+
+ taskCompletionSource.SetResult(((JObject)display).ToObject());
+ });
+
+ BridgeConnector.Socket.Emit("screen-getDisplayMatching", JObject.FromObject(rectangle, _jsonSerializer));
+
+ return taskCompletionSource.Task;
+ }
+
+ private JsonSerializer _jsonSerializer = new JsonSerializer()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore
+ };
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.API/WebContents.cs b/ElectronNET.API/WebContents.cs
index 70fa998..68ce8f3 100644
--- a/ElectronNET.API/WebContents.cs
+++ b/ElectronNET.API/WebContents.cs
@@ -4,6 +4,7 @@ using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Diagnostics;
+using System.Threading.Tasks;
namespace ElectronNET.API
{
@@ -89,6 +90,37 @@ namespace ElectronNET.API
BridgeConnector.Socket.Emit("webContentsOpenDevTools", Id, JObject.FromObject(openDevToolsOptions, _jsonSerializer));
}
+ ///
+ /// Prints window's web page as PDF with Chromium's preview printing custom
+ /// settings.The landscape will be ignored if @page CSS at-rule is used in the web page.
+ /// By default, an empty options will be regarded as: Use page-break-before: always;
+ /// CSS style to force to print to a new page.
+ ///
+ ///
+ ///
+ /// success
+ public Task PrintToPDFAsync(string path, PrintToPDFOptions options = null)
+ {
+ var taskCompletionSource = new TaskCompletionSource();
+
+ BridgeConnector.Socket.On("webContents-printToPDF-completed", (success) =>
+ {
+ BridgeConnector.Socket.Off("webContents-printToPDF-completed");
+ taskCompletionSource.SetResult((bool)success);
+ });
+
+ if(options == null)
+ {
+ BridgeConnector.Socket.Emit("webContents-printToPDF", Id, "", path);
+ }
+ else
+ {
+ BridgeConnector.Socket.Emit("webContents-printToPDF", Id, JObject.FromObject(options, _jsonSerializer), path);
+ }
+
+ return taskCompletionSource.Task;
+ }
+
private JsonSerializer _jsonSerializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
diff --git a/ElectronNET.CLI/Commands/BuildCommand.cs b/ElectronNET.CLI/Commands/BuildCommand.cs
index 3c788ac..9e3913f 100644
--- a/ElectronNET.CLI/Commands/BuildCommand.cs
+++ b/ElectronNET.CLI/Commands/BuildCommand.cs
@@ -106,6 +106,8 @@ namespace ElectronNET.CLI.Commands
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "webContents.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "globalShortcut.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "shell.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "screen.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "clipboard.js", "api.");
Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install", tempPath);
diff --git a/ElectronNET.CLI/Commands/StartElectronCommand.cs b/ElectronNET.CLI/Commands/StartElectronCommand.cs
index 3dc9213..3ec5147 100644
--- a/ElectronNET.CLI/Commands/StartElectronCommand.cs
+++ b/ElectronNET.CLI/Commands/StartElectronCommand.cs
@@ -68,6 +68,8 @@ namespace ElectronNET.CLI.Commands
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "webContents.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "globalShortcut.js", "api.");
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "shell.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "screen.js", "api.");
+ EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "clipboard.js", "api.");
Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install", tempPath);
diff --git a/ElectronNET.CLI/ElectronNET.CLI.csproj b/ElectronNET.CLI/ElectronNET.CLI.csproj
index 7763b89..8a6a5ec 100644
--- a/ElectronNET.CLI/ElectronNET.CLI.csproj
+++ b/ElectronNET.CLI/ElectronNET.CLI.csproj
@@ -49,10 +49,6 @@ This package contains the dotnet tooling to electronize your application.
-
-
-
-
@@ -70,9 +66,14 @@ This package contains the dotnet tooling to electronize your application.
-
-
-
+
+
+
+
+
+
+
+
diff --git a/ElectronNET.Host/api/clipboard.js b/ElectronNET.Host/api/clipboard.js
new file mode 100644
index 0000000..2f86a6d
--- /dev/null
+++ b/ElectronNET.Host/api/clipboard.js
@@ -0,0 +1,51 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+module.exports = function (socket) {
+ socket.on('clipboard-readText', function (type) {
+ var text = electron_1.clipboard.readText(type);
+ socket.emit('clipboard-readText-Completed', text);
+ });
+ socket.on('clipboard-writeText', function (text, type) {
+ electron_1.clipboard.writeText(text, type);
+ });
+ socket.on('clipboard-readHTML', function (type) {
+ var content = electron_1.clipboard.readHTML(type);
+ socket.emit('clipboard-readHTML-Completed', content);
+ });
+ socket.on('clipboard-writeHTML', function (markup, type) {
+ electron_1.clipboard.writeHTML(markup, type);
+ });
+ socket.on('clipboard-readRTF', function (type) {
+ var content = electron_1.clipboard.readRTF(type);
+ socket.emit('clipboard-readRTF-Completed', content);
+ });
+ socket.on('clipboard-writeRTF', function (text, type) {
+ electron_1.clipboard.writeHTML(text, type);
+ });
+ socket.on('clipboard-readBookmark', function () {
+ var bookmark = electron_1.clipboard.readBookmark();
+ socket.emit('clipboard-readBookmark-Completed', bookmark);
+ });
+ socket.on('clipboard-writeBookmark', function (title, url, type) {
+ electron_1.clipboard.writeBookmark(title, url, type);
+ });
+ socket.on('clipboard-readFindText', function () {
+ var content = electron_1.clipboard.readFindText();
+ socket.emit('clipboard-readFindText-Completed', content);
+ });
+ socket.on('clipboard-writeFindText', function (text) {
+ electron_1.clipboard.writeFindText(text);
+ });
+ socket.on('clipboard-clear', function (type) {
+ electron_1.clipboard.clear(type);
+ });
+ socket.on('clipboard-availableFormats', function (type) {
+ var formats = electron_1.clipboard.availableFormats(type);
+ socket.emit('clipboard-availableFormats-Completed', formats);
+ });
+ socket.on('clipboard-write', function (data, type) {
+ electron_1.clipboard.write(data, type);
+ });
+};
+//# sourceMappingURL=clipboard.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/clipboard.js.map b/ElectronNET.Host/api/clipboard.js.map
new file mode 100644
index 0000000..c8d4b6e
--- /dev/null
+++ b/ElectronNET.Host/api/clipboard.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["clipboard.ts"],"names":[],"mappings":";;AAAA,qCAAqC;AAErC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IAErC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,IAAI;QACjC,IAAM,IAAI,GAAG,oBAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,IAAI,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,UAAC,IAAI,EAAE,IAAI;QACxC,oBAAS,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,IAAI;QACjC,IAAM,OAAO,GAAG,oBAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,UAAC,MAAM,EAAE,IAAI;QAC1C,oBAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,IAAI;QAChC,IAAM,OAAO,GAAG,oBAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,IAAI,EAAE,IAAI;QACvC,oBAAS,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE;QAChC,IAAM,QAAQ,GAAG,oBAAS,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,KAAK,EAAE,GAAG,EAAE,IAAI;QAClD,oBAAS,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE;QAChC,IAAM,OAAO,GAAG,oBAAS,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,IAAI;QACtC,oBAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,UAAC,IAAI;QAC9B,oBAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,IAAI;QACzC,IAAM,OAAO,GAAG,oBAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,UAAC,IAAI,EAAE,IAAI;QACpC,oBAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/clipboard.ts b/ElectronNET.Host/api/clipboard.ts
new file mode 100644
index 0000000..e6bf71c
--- /dev/null
+++ b/ElectronNET.Host/api/clipboard.ts
@@ -0,0 +1,62 @@
+import { clipboard } from "electron";
+
+module.exports = (socket: SocketIO.Server) => {
+
+ socket.on('clipboard-readText', (type) => {
+ const text = clipboard.readText(type);
+ socket.emit('clipboard-readText-Completed', text);
+ });
+
+ socket.on('clipboard-writeText', (text, type) => {
+ clipboard.writeText(text, type);
+ });
+
+ socket.on('clipboard-readHTML', (type) => {
+ const content = clipboard.readHTML(type);
+ socket.emit('clipboard-readHTML-Completed', content);
+ });
+
+ socket.on('clipboard-writeHTML', (markup, type) => {
+ clipboard.writeHTML(markup, type);
+ });
+
+ socket.on('clipboard-readRTF', (type) => {
+ const content = clipboard.readRTF(type);
+ socket.emit('clipboard-readRTF-Completed', content);
+ });
+
+ socket.on('clipboard-writeRTF', (text, type) => {
+ clipboard.writeHTML(text, type);
+ });
+
+ socket.on('clipboard-readBookmark', () => {
+ const bookmark = clipboard.readBookmark();
+ socket.emit('clipboard-readBookmark-Completed', bookmark);
+ });
+
+ socket.on('clipboard-writeBookmark', (title, url, type) => {
+ clipboard.writeBookmark(title, url, type);
+ });
+
+ socket.on('clipboard-readFindText', () => {
+ const content = clipboard.readFindText();
+ socket.emit('clipboard-readFindText-Completed', content);
+ });
+
+ socket.on('clipboard-writeFindText', (text) => {
+ clipboard.writeFindText(text);
+ });
+
+ socket.on('clipboard-clear', (type) => {
+ clipboard.clear(type);
+ });
+
+ socket.on('clipboard-availableFormats', (type) => {
+ const formats = clipboard.availableFormats(type);
+ socket.emit('clipboard-availableFormats-Completed', formats);
+ });
+
+ socket.on('clipboard-write', (data, type) => {
+ clipboard.write(data, type);
+ });
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/ipc.js b/ElectronNET.Host/api/ipc.js
index f20924e..8bb0fa5 100644
--- a/ElectronNET.Host/api/ipc.js
+++ b/ElectronNET.Host/api/ipc.js
@@ -32,8 +32,9 @@ module.exports = function (socket) {
}
var window = electron_1.BrowserWindow.fromId(browserWindow.id);
if (window) {
- window.webContents.send(channel, data);
+ (_a = window.webContents).send.apply(_a, [channel].concat(data));
}
+ var _a;
});
};
//# sourceMappingURL=ipc.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/ipc.js.map b/ElectronNET.Host/api/ipc.js.map
index 2a6d9eb..e0347aa 100644
--- a/ElectronNET.Host/api/ipc.js.map
+++ b/ElectronNET.Host/api/ipc.js.map
@@ -1 +1 @@
-{"version":3,"file":"ipc.js","sourceRoot":"","sources":["ipc.ts"],"names":[],"mappings":";;AAAA,qCAAkD;AAElD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,OAAO;QACxC,kBAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,kBAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,IAAI,CAAC,GAAQ,MAAM,CAAC;YACpB,CAAC,CAAC,kBAAkB,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;YACvC,MAAM,CAAC,EAAE,CAAC,OAAO,GAAG,MAAM,EAAE,UAAC,MAAM;gBAC/B,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,kBAAO,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,UAAC,OAAO;QAClD,kBAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,aAAa,EAAE,OAAO;QAAE,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,6BAAO;;QAC3D,IAAM,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtD,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACT,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
+{"version":3,"file":"ipc.js","sourceRoot":"","sources":["ipc.ts"],"names":[],"mappings":";;AAAA,qCAAkD;AAElD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,OAAO;QACxC,kBAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,kBAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,IAAI,CAAC,GAAQ,MAAM,CAAC;YACpB,CAAC,CAAC,kBAAkB,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;YACvC,MAAM,CAAC,EAAE,CAAC,OAAO,GAAG,MAAM,EAAE,UAAC,MAAM;gBAC/B,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,kBAAO,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,UAAC,OAAO;QAClD,kBAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,aAAa,EAAE,OAAO;QAAE,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,6BAAO;;QAC3D,IAAM,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtD,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACT,CAAA,KAAA,MAAM,CAAC,WAAW,CAAA,CAAC,IAAI,YAAC,OAAO,SAAK,IAAI,GAAE;QAC9C,CAAC;;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/ipc.ts b/ElectronNET.Host/api/ipc.ts
index 8028c14..3ff6586 100644
--- a/ElectronNET.Host/api/ipc.ts
+++ b/ElectronNET.Host/api/ipc.ts
@@ -33,7 +33,7 @@ module.exports = (socket: SocketIO.Server) => {
const window = BrowserWindow.fromId(browserWindow.id);
if (window) {
- window.webContents.send(channel, data);
+ window.webContents.send(channel, ...data);
}
});
}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/screen.js b/ElectronNET.Host/api/screen.js
new file mode 100644
index 0000000..dee3ea8
--- /dev/null
+++ b/ElectronNET.Host/api/screen.js
@@ -0,0 +1,45 @@
+"use strict";
+exports.__esModule = true;
+var electron_1 = require("electron");
+module.exports = function (socket) {
+ socket.on('register-screen-display-added', function (id) {
+ electron_1.screen.on('display-added', function (event, display) {
+ socket.emit('screen-display-added-event' + id, display);
+ });
+ });
+ socket.on('register-screen-display-removed', function (id) {
+ electron_1.screen.on('display-removed', function (event, display) {
+ socket.emit('screen-display-removed-event' + id, display);
+ });
+ });
+ socket.on('register-screen-display-metrics-changed', function (id) {
+ electron_1.screen.on('display-metrics-changed', function (event, display, changedMetrics) {
+ socket.emit('screen-display-metrics-changed-event' + id, [display, changedMetrics]);
+ });
+ });
+ socket.on('screen-getCursorScreenPoint', function () {
+ var point = electron_1.screen.getCursorScreenPoint();
+ socket.emit('screen-getCursorScreenPointCompleted', point);
+ });
+ socket.on('screen-getMenuBarHeight', function () {
+ var height = electron_1.screen.getMenuBarHeight();
+ socket.emit('screen-getMenuBarHeightCompleted', height);
+ });
+ socket.on('screen-getPrimaryDisplay', function () {
+ var display = electron_1.screen.getPrimaryDisplay();
+ socket.emit('screen-getPrimaryDisplayCompleted', display);
+ });
+ socket.on('screen-getAllDisplays', function () {
+ var display = electron_1.screen.getAllDisplays();
+ socket.emit('screen-getAllDisplaysCompleted', display);
+ });
+ socket.on('screen-getDisplayNearestPoint', function (point) {
+ var display = electron_1.screen.getDisplayNearestPoint(point);
+ socket.emit('screen-getDisplayNearestPointCompleted', display);
+ });
+ socket.on('screen-getDisplayMatching', function (rectangle) {
+ var display = electron_1.screen.getDisplayMatching(rectangle);
+ socket.emit('screen-getDisplayMatchingCompleted', display);
+ });
+};
+//# sourceMappingURL=screen.js.map
\ No newline at end of file
diff --git a/ElectronNET.Host/api/screen.js.map b/ElectronNET.Host/api/screen.js.map
new file mode 100644
index 0000000..a92cc4a
--- /dev/null
+++ b/ElectronNET.Host/api/screen.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"screen.js","sourceRoot":"","sources":["screen.ts"],"names":[],"mappings":";;AAAA,qCAAkC;AAElC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,+BAA+B,EAAE,UAAC,EAAE;QAC1C,iBAAM,CAAC,EAAE,CAAC,eAAe,EAAE,UAAC,KAAK,EAAE,OAAO;YACtC,MAAM,CAAC,IAAI,CAAC,4BAA4B,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,UAAC,EAAE;QAC5C,iBAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,UAAC,KAAK,EAAE,OAAO;YACxC,MAAM,CAAC,IAAI,CAAC,8BAA8B,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yCAAyC,EAAE,UAAC,EAAE;QACpD,iBAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,KAAK,EAAE,OAAO,EAAE,cAAc;YAChE,MAAM,CAAC,IAAI,CAAC,sCAAsC,GAAG,EAAE,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,6BAA6B,EAAE;QACrC,IAAI,KAAK,GAAG,iBAAM,CAAC,oBAAoB,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE;QACjC,IAAI,MAAM,GAAG,iBAAM,CAAC,gBAAgB,EAAE,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,0BAA0B,EAAE;QAClC,IAAI,OAAO,GAAG,iBAAM,CAAC,iBAAiB,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE;QAC/B,IAAI,OAAO,GAAG,iBAAM,CAAC,cAAc,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,+BAA+B,EAAE,UAAC,KAAK;QAC7C,IAAI,OAAO,GAAG,iBAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,UAAC,SAAS;QAC7C,IAAI,OAAO,GAAG,iBAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/screen.ts b/ElectronNET.Host/api/screen.ts
new file mode 100644
index 0000000..135c101
--- /dev/null
+++ b/ElectronNET.Host/api/screen.ts
@@ -0,0 +1,51 @@
+import { screen } from "electron";
+
+module.exports = (socket: SocketIO.Server) => {
+ socket.on('register-screen-display-added', (id) => {
+ screen.on('display-added', (event, display) => {
+ socket.emit('screen-display-added-event' + id, display);
+ });
+ });
+
+ socket.on('register-screen-display-removed', (id) => {
+ screen.on('display-removed', (event, display) => {
+ socket.emit('screen-display-removed-event' + id, display);
+ });
+ });
+
+ socket.on('register-screen-display-metrics-changed', (id) => {
+ screen.on('display-metrics-changed', (event, display, changedMetrics) => {
+ socket.emit('screen-display-metrics-changed-event' + id, [display, changedMetrics]);
+ });
+ });
+
+ socket.on('screen-getCursorScreenPoint', () => {
+ var point = screen.getCursorScreenPoint();
+ socket.emit('screen-getCursorScreenPointCompleted', point);
+ });
+
+ socket.on('screen-getMenuBarHeight', () => {
+ var height = screen.getMenuBarHeight();
+ socket.emit('screen-getMenuBarHeightCompleted', height);
+ });
+
+ socket.on('screen-getPrimaryDisplay', () => {
+ var display = screen.getPrimaryDisplay();
+ socket.emit('screen-getPrimaryDisplayCompleted', display);
+ });
+
+ socket.on('screen-getAllDisplays', () => {
+ var display = screen.getAllDisplays();
+ socket.emit('screen-getAllDisplaysCompleted', display);
+ });
+
+ socket.on('screen-getDisplayNearestPoint', (point) => {
+ var display = screen.getDisplayNearestPoint(point);
+ socket.emit('screen-getDisplayNearestPointCompleted', display);
+ });
+
+ socket.on('screen-getDisplayMatching', (rectangle) => {
+ var display = screen.getDisplayMatching(rectangle);
+ socket.emit('screen-getDisplayMatchingCompleted', display);
+ });
+}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/webContents.js b/ElectronNET.Host/api/webContents.js
index 1e00147..4a107b0 100644
--- a/ElectronNET.Host/api/webContents.js
+++ b/ElectronNET.Host/api/webContents.js
@@ -1,6 +1,7 @@
"use strict";
exports.__esModule = true;
var electron_1 = require("electron");
+var fs = require('fs');
module.exports = function (socket) {
socket.on('register-webContents-crashed', function (id) {
var browserWindow = getWindowById(id);
@@ -24,6 +25,21 @@ module.exports = function (socket) {
getWindowById(id).webContents.openDevTools();
}
});
+ socket.on('webContents-printToPDF', function (id, options, path) {
+ getWindowById(id).webContents.printToPDF(options || {}, function (error, data) {
+ if (error) {
+ throw error;
+ }
+ fs.writeFile(path, data, function (error) {
+ if (error) {
+ socket.emit('webContents-printToPDF-completed', false);
+ }
+ else {
+ socket.emit('webContents-printToPDF-completed', true);
+ }
+ });
+ });
+ });
function getWindowById(id) {
return electron_1.BrowserWindow.fromId(id);
}
diff --git a/ElectronNET.Host/api/webContents.js.map b/ElectronNET.Host/api/webContents.js.map
index fdd23b7..aa06d7d 100644
--- a/ElectronNET.Host/api/webContents.js.map
+++ b/ElectronNET.Host/api/webContents.js.map
@@ -1 +1 @@
-{"version":3,"file":"webContents.js","sourceRoot":"","sources":["webContents.ts"],"names":[],"mappings":";;AAAA,qCAAyC;AACzC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,UAAC,EAAE;QACzC,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtC,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACxD,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,UAAC,KAAK,EAAE,MAAM;YAClD,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,oCAAoC,EAAE,UAAC,EAAE;QAC/C,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtC,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAChE,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,iBAAiB,EAAE;YAC5C,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,EAAE,EAAE,OAAO;QAC7C,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACV,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;QACjD,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,uBAAuB,EAAU;QAC7B,MAAM,CAAC,wBAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;AACL,CAAC,CAAC"}
\ No newline at end of file
+{"version":3,"file":"webContents.js","sourceRoot":"","sources":["webContents.ts"],"names":[],"mappings":";;AAAA,qCAAyC;AACzC,IAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzB,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,UAAC,EAAE;QACzC,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtC,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACxD,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,UAAC,KAAK,EAAE,MAAM;YAClD,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,oCAAoC,EAAE,UAAC,EAAE;QAC/C,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtC,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAChE,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,iBAAiB,EAAE;YAC5C,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,EAAE,EAAE,OAAO;QAC7C,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACV,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;QACjD,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,EAAE,EAAE,OAAO,EAAE,IAAI;QAClD,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,UAAC,KAAK,EAAE,IAAI;YAChE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACR,MAAM,KAAK,CAAC;YAChB,CAAC;YAED,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,UAAC,KAAK;gBAC7B,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACV,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;gBACzD,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,uBAAuB,EAAU;QAC7B,MAAM,CAAC,wBAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;AACL,CAAC,CAAC"}
\ No newline at end of file
diff --git a/ElectronNET.Host/api/webContents.ts b/ElectronNET.Host/api/webContents.ts
index 757503e..0f1bc59 100644
--- a/ElectronNET.Host/api/webContents.ts
+++ b/ElectronNET.Host/api/webContents.ts
@@ -1,4 +1,6 @@
import { BrowserWindow } from 'electron';
+const fs = require('fs');
+
module.exports = (socket: SocketIO.Server) => {
socket.on('register-webContents-crashed', (id) => {
var browserWindow = getWindowById(id);
@@ -10,7 +12,7 @@ module.exports = (socket: SocketIO.Server) => {
});
socket.on('register-webContents-didFinishLoad', (id) => {
- var browserWindow = getWindowById(id);
+ let browserWindow = getWindowById(id);
browserWindow.webContents.removeAllListeners('did-finish-load');
browserWindow.webContents.on('did-finish-load', () => {
@@ -26,6 +28,22 @@ module.exports = (socket: SocketIO.Server) => {
}
});
+ socket.on('webContents-printToPDF', (id, options, path) => {
+ getWindowById(id).webContents.printToPDF(options || {}, (error, data) => {
+ if (error) {
+ throw error;
+ }
+
+ fs.writeFile(path, data, (error) => {
+ if (error) {
+ socket.emit('webContents-printToPDF-completed', false);
+ } else {
+ socket.emit('webContents-printToPDF-completed', true);
+ }
+ });
+ });
+ });
+
function getWindowById(id: number): Electron.BrowserWindow {
return BrowserWindow.fromId(id);
}
diff --git a/ElectronNET.Host/main.js b/ElectronNET.Host/main.js
index f8e884e..af3186a 100644
--- a/ElectronNET.Host/main.js
+++ b/ElectronNET.Host/main.js
@@ -5,7 +5,7 @@ const process = require('child_process').spawn;
const portfinder = require('detect-port');
let io, browserWindows, ipc, apiProcess, loadURL;
let appApi, menu, dialog, notification, tray, webContents;
-let globalShortcut, shell;
+let globalShortcut, shell, screen, clipboard;
app.on('ready', () => {
portfinder(8000, (error, port) => {
@@ -30,6 +30,8 @@ function startSocketApiBridge(port) {
webContents = require('./api/webContents')(socket);
globalShortcut = require('./api/globalShortcut')(socket);
shell = require('./api/shell')(socket);
+ screen = require('./api/screen')(socket);
+ clipboard = require('./api/clipboard')(socket);
});
}
diff --git a/ElectronNET.WebApp/Controllers/AppSysInformationController.cs b/ElectronNET.WebApp/Controllers/AppSysInformationController.cs
new file mode 100644
index 0000000..51240e1
--- /dev/null
+++ b/ElectronNET.WebApp/Controllers/AppSysInformationController.cs
@@ -0,0 +1,39 @@
+using System.Linq;
+using Microsoft.AspNetCore.Mvc;
+using ElectronNET.API;
+using ElectronNET.API.Entities;
+
+namespace ElectronNET.WebApp.Controllers
+{
+ public class AppSysInformationController : Controller
+ {
+ public IActionResult Index()
+ {
+ Electron.IpcMain.On("app-info", async (args) =>
+ {
+ string appPath = await Electron.App.GetAppPathAsync();
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.IpcMain.Send(mainWindow, "got-app-path", appPath);
+ });
+
+ Electron.IpcMain.On("sys-info", async (args) =>
+ {
+ string homePath = await Electron.App.GetPathAsync(PathName.home);
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.IpcMain.Send(mainWindow, "got-sys-info", homePath);
+ });
+
+ Electron.IpcMain.On("screen-info", async (args) =>
+ {
+ var display = await Electron.Screen.GetPrimaryDisplayAsync();
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.IpcMain.Send(mainWindow, "got-screen-info", display.Size);
+ });
+
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/ClipboardController.cs b/ElectronNET.WebApp/Controllers/ClipboardController.cs
new file mode 100644
index 0000000..17ccc3f
--- /dev/null
+++ b/ElectronNET.WebApp/Controllers/ClipboardController.cs
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.Mvc;
+using ElectronNET.API;
+using System.Linq;
+
+namespace ElectronNET.WebApp.Controllers
+{
+ public class ClipboardController : Controller
+ {
+ public IActionResult Index()
+ {
+ Electron.IpcMain.On("copy-to", (text) =>
+ {
+ Electron.Clipboard.WriteText(text.ToString());
+ });
+
+ Electron.IpcMain.On("paste-to", async (text) =>
+ {
+ Electron.Clipboard.WriteText(text.ToString());
+ string pasteText = await Electron.Clipboard.ReadTextAsync();
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.IpcMain.Send(mainWindow, "paste-from", pasteText);
+ });
+
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/DesktopCapturerController.cs b/ElectronNET.WebApp/Controllers/DesktopCapturerController.cs
new file mode 100644
index 0000000..9e3da21
--- /dev/null
+++ b/ElectronNET.WebApp/Controllers/DesktopCapturerController.cs
@@ -0,0 +1,12 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace ElectronNET.WebApp.Controllers
+{
+ public class DesktopCapturerController : Controller
+ {
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/HomeController.cs b/ElectronNET.WebApp/Controllers/HomeController.cs
index 03beca1..3d997ef 100644
--- a/ElectronNET.WebApp/Controllers/HomeController.cs
+++ b/ElectronNET.WebApp/Controllers/HomeController.cs
@@ -1,7 +1,4 @@
-using ElectronNET.API;
-using ElectronNET.API.Entities;
-using Microsoft.AspNetCore.Mvc;
-using System.Linq;
+using Microsoft.AspNetCore.Mvc;
namespace ElectronNET.WebApp.Controllers
{
@@ -9,111 +6,7 @@ namespace ElectronNET.WebApp.Controllers
{
public IActionResult Index()
{
- var menu = new MenuItem[] {
- new MenuItem { Label = "Edit", Submenu = new MenuItem[] {
- new MenuItem { Label = "Undo", Accelerator = "CmdOrCtrl+Z", Role = MenuRole.undo },
- new MenuItem { Label = "Redo", Accelerator = "Shift+CmdOrCtrl+Z", Role = MenuRole.redo },
- new MenuItem { Type = MenuType.separator },
- new MenuItem { Label = "Cut", Accelerator = "CmdOrCtrl+X", Role = MenuRole.cut },
- new MenuItem { Label = "Copy", Accelerator = "CmdOrCtrl+C", Role = MenuRole.copy },
- new MenuItem { Label = "Paste", Accelerator = "CmdOrCtrl+V", Role = MenuRole.paste },
- new MenuItem { Label = "Select All", Accelerator = "CmdOrCtrl+A", Role = MenuRole.selectall }
- }
- },
- new MenuItem { Label = "View", Submenu = new MenuItem[] {
- new MenuItem
- {
- Label = "Reload",
- Accelerator = "CmdOrCtrl+R",
- Click = () =>
- {
- // on reload, start fresh and close any old
- // open secondary windows
- Electron.WindowManager.BrowserWindows.ToList().ForEach(browserWindow => {
- if(browserWindow.Id != 1)
- {
- browserWindow.Close();
- }
- else
- {
- browserWindow.Reload();
- }
- });
- }
- },
- new MenuItem
- {
- Label = "Toggle Full Screen",
- Accelerator = "CmdOrCtrl+F",
- Click = async () =>
- {
- bool isFullScreen = await Electron.WindowManager.BrowserWindows.First().IsFullScreenAsync();
- Electron.WindowManager.BrowserWindows.First().SetFullScreen(!isFullScreen);
- }
- },
- new MenuItem
- {
- Label = "Open Developer Tools",
- Accelerator = "CmdOrCtrl+I",
- Click = () => Electron.WindowManager.BrowserWindows.First().WebContents.OpenDevTools()
- },
- new MenuItem
- {
- Type = MenuType.separator
- },
- new MenuItem
- {
- Label = "App Menu Demo",
- Click = async () => {
- var options = new MessageBoxOptions("This demo is for the Menu section, showing how to create a clickable menu item in the application menu.");
- options.Type = MessageBoxType.info;
- options.Title = "Application Menu Demo";
- await Electron.Dialog.ShowMessageBoxAsync(options);
- }
- }
- }
- },
- new MenuItem { Label = "Window", Role = MenuRole.window, Submenu = new MenuItem[] {
- new MenuItem { Label = "Minimize", Accelerator = "CmdOrCtrl+M", Role = MenuRole.minimize },
- new MenuItem { Label = "Close", Accelerator = "CmdOrCtrl+W", Role = MenuRole.close }
- }
- },
- new MenuItem { Label = "Help", Role = MenuRole.help, Submenu = new MenuItem[] {
- new MenuItem
- {
- Label = "Learn More",
- Click = async () => await Electron.Shell.OpenExternalAsync("https://github.com/ElectronNET")
- }
- }
- }
- };
-
- Electron.Menu.SetApplicationMenu(menu);
-
- CreateContextMenu();
-
return View();
}
-
- private void CreateContextMenu()
- {
- var menu = new MenuItem[]
- {
- new MenuItem
- {
- Label = "Hello",
- Click = async () => await Electron.Dialog.ShowMessageBoxAsync("Electron.NET rocks!")
- },
- new MenuItem { Type = MenuType.separator },
- new MenuItem { Label = "Electron.NET", Type = MenuType.checkbox, Checked = true }
- };
-
- var mainWindow = Electron.WindowManager.BrowserWindows.First();
- Electron.Menu.SetContextMenu(mainWindow, menu);
-
- Electron.IpcMain.On("show-context-menu", (args) => {
- Electron.Menu.ContextMenuPopup(mainWindow);
- });
- }
}
}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/MenusController.cs b/ElectronNET.WebApp/Controllers/MenusController.cs
index 47b9c03..7d0fd31 100644
--- a/ElectronNET.WebApp/Controllers/MenusController.cs
+++ b/ElectronNET.WebApp/Controllers/MenusController.cs
@@ -1,8 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using System.Linq;
using Microsoft.AspNetCore.Mvc;
+using ElectronNET.API.Entities;
+using ElectronNET.API;
namespace ElectronNET.WebApp.Controllers
{
@@ -10,7 +9,111 @@ namespace ElectronNET.WebApp.Controllers
{
public IActionResult Index()
{
+ var menu = new MenuItem[] {
+ new MenuItem { Label = "Edit", Submenu = new MenuItem[] {
+ new MenuItem { Label = "Undo", Accelerator = "CmdOrCtrl+Z", Role = MenuRole.undo },
+ new MenuItem { Label = "Redo", Accelerator = "Shift+CmdOrCtrl+Z", Role = MenuRole.redo },
+ new MenuItem { Type = MenuType.separator },
+ new MenuItem { Label = "Cut", Accelerator = "CmdOrCtrl+X", Role = MenuRole.cut },
+ new MenuItem { Label = "Copy", Accelerator = "CmdOrCtrl+C", Role = MenuRole.copy },
+ new MenuItem { Label = "Paste", Accelerator = "CmdOrCtrl+V", Role = MenuRole.paste },
+ new MenuItem { Label = "Select All", Accelerator = "CmdOrCtrl+A", Role = MenuRole.selectall }
+ }
+ },
+ new MenuItem { Label = "View", Submenu = new MenuItem[] {
+ new MenuItem
+ {
+ Label = "Reload",
+ Accelerator = "CmdOrCtrl+R",
+ Click = () =>
+ {
+ // on reload, start fresh and close any old
+ // open secondary windows
+ Electron.WindowManager.BrowserWindows.ToList().ForEach(browserWindow => {
+ if(browserWindow.Id != 1)
+ {
+ browserWindow.Close();
+ }
+ else
+ {
+ browserWindow.Reload();
+ }
+ });
+ }
+ },
+ new MenuItem
+ {
+ Label = "Toggle Full Screen",
+ Accelerator = "CmdOrCtrl+F",
+ Click = async () =>
+ {
+ bool isFullScreen = await Electron.WindowManager.BrowserWindows.First().IsFullScreenAsync();
+ Electron.WindowManager.BrowserWindows.First().SetFullScreen(!isFullScreen);
+ }
+ },
+ new MenuItem
+ {
+ Label = "Open Developer Tools",
+ Accelerator = "CmdOrCtrl+I",
+ Click = () => Electron.WindowManager.BrowserWindows.First().WebContents.OpenDevTools()
+ },
+ new MenuItem
+ {
+ Type = MenuType.separator
+ },
+ new MenuItem
+ {
+ Label = "App Menu Demo",
+ Click = async () => {
+ var options = new MessageBoxOptions("This demo is for the Menu section, showing how to create a clickable menu item in the application menu.");
+ options.Type = MessageBoxType.info;
+ options.Title = "Application Menu Demo";
+ await Electron.Dialog.ShowMessageBoxAsync(options);
+ }
+ }
+ }
+ },
+ new MenuItem { Label = "Window", Role = MenuRole.window, Submenu = new MenuItem[] {
+ new MenuItem { Label = "Minimize", Accelerator = "CmdOrCtrl+M", Role = MenuRole.minimize },
+ new MenuItem { Label = "Close", Accelerator = "CmdOrCtrl+W", Role = MenuRole.close }
+ }
+ },
+ new MenuItem { Label = "Help", Role = MenuRole.help, Submenu = new MenuItem[] {
+ new MenuItem
+ {
+ Label = "Learn More",
+ Click = async () => await Electron.Shell.OpenExternalAsync("https://github.com/ElectronNET")
+ }
+ }
+ }
+ };
+
+ Electron.Menu.SetApplicationMenu(menu);
+
+ CreateContextMenu();
+
return View();
}
+
+ private void CreateContextMenu()
+ {
+ var menu = new MenuItem[]
+ {
+ new MenuItem
+ {
+ Label = "Hello",
+ Click = async () => await Electron.Dialog.ShowMessageBoxAsync("Electron.NET rocks!")
+ },
+ new MenuItem { Type = MenuType.separator },
+ new MenuItem { Label = "Electron.NET", Type = MenuType.checkbox, Checked = true }
+ };
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.Menu.SetContextMenu(mainWindow, menu);
+
+ Electron.IpcMain.On("show-context-menu", (args) => {
+ Electron.Menu.ContextMenuPopup(mainWindow);
+ });
+ }
}
}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Controllers/PdfController.cs b/ElectronNET.WebApp/Controllers/PdfController.cs
new file mode 100644
index 0000000..59ca46c
--- /dev/null
+++ b/ElectronNET.WebApp/Controllers/PdfController.cs
@@ -0,0 +1,39 @@
+using System.Linq;
+using Microsoft.AspNetCore.Mvc;
+using ElectronNET.API;
+using ElectronNET.API.Entities;
+
+namespace ElectronNET.WebApp.Controllers
+{
+ public class PdfController : Controller
+ {
+ public IActionResult Index()
+ {
+ Electron.IpcMain.On("print-pdf", async (args) => {
+ BrowserWindow mainWindow = Electron.WindowManager.BrowserWindows.First();
+
+ var saveOptions = new SaveDialogOptions
+ {
+ Title = "Save an PDF-File",
+ DefaultPath = await Electron.App.GetPathAsync(PathName.documents),
+ Filters = new FileFilter[]
+ {
+ new FileFilter { Name = "PDF", Extensions = new string[] { "pdf" } }
+ }
+ };
+ var path = await Electron.Dialog.ShowSaveDialogAsync(mainWindow, saveOptions);
+
+ if (await mainWindow.WebContents.PrintToPDFAsync(path))
+ {
+ await Electron.Shell.OpenExternalAsync("file://" + path);
+ }
+ else
+ {
+ Electron.Dialog.ShowErrorBox("Error", "Failed to create pdf file.");
+ }
+ });
+
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Startup.cs b/ElectronNET.WebApp/Startup.cs
index b830882..bbae832 100644
--- a/ElectronNET.WebApp/Startup.cs
+++ b/ElectronNET.WebApp/Startup.cs
@@ -48,6 +48,7 @@ namespace ElectronNET.WebApp
});
browserWindow.OnReadyToShow += () => browserWindow.Show();
+ browserWindow.SetTitle("Electron.NET API Demos");
}
}
}
diff --git a/ElectronNET.WebApp/Views/AppSysInformation/Index.cshtml b/ElectronNET.WebApp/Views/AppSysInformation/Index.cshtml
new file mode 100644
index 0000000..a22440e
--- /dev/null
+++ b/ElectronNET.WebApp/Views/AppSysInformation/Index.cshtml
@@ -0,0 +1,187 @@
+
+
+
diff --git a/ElectronNET.WebApp/Views/Clipboard/Index.cshtml b/ElectronNET.WebApp/Views/Clipboard/Index.cshtml
new file mode 100644
index 0000000..77e3098
--- /dev/null
+++ b/ElectronNET.WebApp/Views/Clipboard/Index.cshtml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+ Copy
+ Supports: Win, macOS, Linux | Process: Both
+
+
+
+ Copy
+
+
+
In this example we copy a phrase to the clipboard. After clicking 'Copy' use the text area to paste (CMD + V or CTRL + V) the phrase from the clipboard.
+
Main Process (C#)
+
Electron.IpcMain.On("copy-to", (text) =>
+{
+ Electron.Clipboard.WriteText(text.ToString());
+});
+
+
ProTip
+
Electron.js Support in Electron.NET.
+
The clipboard module is built into Electron.js (therefore you can use this in the renderer processes).
+
const clipboard = require('electron').clipboard;
+
+const copyBtn = document.getElementById('copy-to');
+const copyInput = document.getElementById('copy-to-input');
+
+copyBtn.addEventListener('click', () => {
+ if (copyInput.value !== '') copyInput.value = '';
+ copyInput.placeholder = 'Copied! Paste here to see.';
+ clipboard.writeText('Electron Demo!');
+})
+
+
+
+
+
+
+
+
+ Paste
+ Supports: Win, macOS, Linux | Process: Both
+
+
+
+ Paste
+
+
+
In this example we copy a string to the clipboard and then paste the results into a message above.
+
+
Main Process (C#)
+
Electron.IpcMain.On("paste-to", async (text) =>
+{
+ Electron.Clipboard.WriteText(text.ToString());
+ string pasteText = await Electron.Clipboard.ReadTextAsync();
+
+ var mainWindow = Electron.WindowManager.BrowserWindows.First();
+ Electron.IpcMain.Send(mainWindow, "paste-from", pasteText);
+});
+
+
+
ProTip
+
Electron.js Support in Electron.NET.
+
The clipboard module is built into Electron.js (therefore you can use this in the renderer processes).
+
const clipboard = require('electron').clipboard;
+
+const pasteBtn = document.getElementById('paste-to');
+
+pasteBtn.addEventListener('click', () => {
+ clipboard.writeText('What a demo!');
+ const message = `Clipboard contents: ${clipboard.readText()}`;
+ document.getElementById('paste-from').innerHTML = message;
+})
+
+
+
+
+
+
+
+
+
diff --git a/ElectronNET.WebApp/Views/CrashHang/Index.cshtml b/ElectronNET.WebApp/Views/CrashHang/Index.cshtml
index 26d9847..2a77c5b 100644
--- a/ElectronNET.WebApp/Views/CrashHang/Index.cshtml
+++ b/ElectronNET.WebApp/Views/CrashHang/Index.cshtml
@@ -24,7 +24,7 @@
In this demo we create a new window and provide a link that will force a crash using process.crash().
The window is listening for the crash event and when the event occurs it prompts the user with two options: reload or close.
- Renderer Process
+ Main Process (C#)
var browserWindow = await Electron.WindowManager.CreateWindowAsync(viewPath);
browserWindow.WebContents.OnCrashed += async (killed) => {
var options = new MessageBoxOptions("This process has crashed.") {
@@ -58,7 +58,7 @@ browserWindow.WebContents.OnCrashed += async (killed) => {
In this demo we create a new window and provide a link that will force the process to hang using process.hang().
The window is listening for the process to become officially unresponsive (this can take up to 30 seconds). When this event occurs it prompts the user with two options: reload or close.
- Renderer Process
+ Main Process (C#)
var browserWindow = await Electron.WindowManager.CreateWindowAsync();
browserWindow.OnUnresponsive += async () => {
var options = new MessageBoxOptions("This process is hanging.")
diff --git a/ElectronNET.WebApp/Views/DesktopCapturer/Index.cshtml b/ElectronNET.WebApp/Views/DesktopCapturer/Index.cshtml
new file mode 100644
index 0000000..5e22c04
--- /dev/null
+++ b/ElectronNET.WebApp/Views/DesktopCapturer/Index.cshtml
@@ -0,0 +1,126 @@
+
+
+
diff --git a/ElectronNET.WebApp/Views/Dialogs/Index.cshtml b/ElectronNET.WebApp/Views/Dialogs/Index.cshtml
index 887b030..6e14603 100644
--- a/ElectronNET.WebApp/Views/Dialogs/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Dialogs/Index.cshtml
@@ -26,7 +26,7 @@
In this demo, the ipcRenderer is used to send a message from the renderer process instructing the main process to launch the open file (or directory) dialog. If a file is selected, the main process can send that information back to the renderer process.
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
document.getElementById("select-directory").addEventListener("click", () => {
@@ -36,7 +36,7 @@ document.getElementById("select-directory").addEventListener("click", () => {
ipcRenderer.on("select-directory-reply", (sender, path) => {
document.getElementById("selected-file").innerText = `You selected: ${path}`;;
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("select-directory", async (args) => {
var mainWindow = Electron.WindowManager.BrowserWindows.First();
var options = new OpenDialogOptions {
@@ -65,13 +65,13 @@ ipcRenderer.on("select-directory-reply", (sender, path) => {
In this demo, the ipcRenderer is used to send a message from the renderer process instructing the main process to launch the error dialog.
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
document.getElementById("error-dialog").addEventListener("click", () => {
ipcRenderer.send("error-dialog");
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("error-dialog", (args) =>
{
Electron.Dialog.ShowErrorBox("An Error Message", "Demonstrating an error message.");
@@ -96,7 +96,7 @@ document.getElementById("error-dialog").addEventListener("click", () => {
Note: The title property is not displayed in macOS.
An information dialog can contain an icon, your choice of buttons, title and message.
- Renderer Process
+ Renderer Process (JavaScript)
document.getElementById("information-dialog").addEventListener("click", () => {
ipcRenderer.send("information-dialog");
});
@@ -112,7 +112,7 @@ ipcRenderer.on("information-dialog-reply", (sender, index) => {
document.getElementById("info-selection").innerText = message;
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("information-dialog", async (args) =>
{
var options = new MessageBoxOptions("This is an information dialog. Isn't it nice?")
@@ -143,7 +143,7 @@ ipcRenderer.on("information-dialog-reply", (sender, index) => {
In this demo, the ipcRenderer is used to send a message from the renderer process instructing the main process to launch the save dialog. It returns the path selected by the user which can be relayed back to the renderer process.
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
document.getElementById("save-dialog").addEventListener("click", () => {
@@ -154,7 +154,7 @@ ipcRenderer.on("save-dialog-reply", (sender, path) => {
if (!path) path = 'No path';
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`;
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("save-dialog", async (args) =>
{
var mainWindow = Electron.WindowManager.BrowserWindows.First();
diff --git a/ElectronNET.WebApp/Views/Home/Index.cshtml b/ElectronNET.WebApp/Views/Home/Index.cshtml
index e315b48..e8ef942 100644
--- a/ElectronNET.WebApp/Views/Home/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Home/Index.cshtml
@@ -22,6 +22,10 @@
+
+
+
+
@@ -74,7 +78,7 @@
Get app or user system information
Copy and paste from the clipboard
- Launch app from protocol handler
+
@@ -88,8 +92,8 @@
diff --git a/ElectronNET.WebApp/Views/Ipc/Index.cshtml b/ElectronNET.WebApp/Views/Ipc/Index.cshtml
index 51becaf..9e65c70 100644
--- a/ElectronNET.WebApp/Views/Ipc/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Ipc/Index.cshtml
@@ -24,10 +24,10 @@
Ping
- Using ipc to send messages between processes asynchronously is the preferred method since it will return when finished without blocking other operations in the same process.
+ Using ipcRenderer to send messages between processes asynchronously is the preferred method since it will return when finished without blocking other operations in the same process.
This example sends a "ping" from this process (renderer) to the main process. The main process then replies with "pong".
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
document.getElementById("async-msg").addEventListener("click", () => {
@@ -38,7 +38,7 @@ ipcRenderer.on('asynchronous-reply', (event, arg) => {
const message = `Asynchronous message reply: ${arg}`;
document.getElementById('async-reply').innerHTML = message;
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("async-msg", (args) =>
{
var mainWindow = Electron.WindowManager.BrowserWindows.First();
@@ -59,9 +59,9 @@ ipcRenderer.on('asynchronous-reply', (event, arg) => {
Ping
- You can use the ipc module to send synchronous messages between processes as well, but note that the synchronous nature of this method means that it will block other operations while completing its task.
+ You can use the ipcRenderer module to send synchronous messages between processes as well, but note that the synchronous nature of this method means that it will block other operations while completing its task.
This example sends a synchronous message, "ping", from this process (renderer) to the main process. The main process then replies with "pong".
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
document.getElementById("sync-msg").addEventListener("click", () => {
@@ -69,7 +69,7 @@ document.getElementById("sync-msg").addEventListener("click", () => {
const message = `Synchronous message reply: ${reply}`;
document.getElementById('sync-reply').innerHTML = message;
});
- Main Process
+ Main Process (C#)
Electron.IpcMain.OnSync("sync-msg", (args) =>
{
return "pong";
diff --git a/ElectronNET.WebApp/Views/Menus/Index.cshtml b/ElectronNET.WebApp/Views/Menus/Index.cshtml
index 7e48719..28a4e1e 100644
--- a/ElectronNET.WebApp/Views/Menus/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Menus/Index.cshtml
@@ -10,7 +10,7 @@
There are two kinds of menus: the application (top) menu and context (right-click) menu.
- You find the sample source code in Controllers\HomeController.cs.
+ You find the sample source code in Controllers\MenusController.cs.
@@ -24,7 +24,7 @@
The Electron.Menu and MenuItem allow you to customize your application menu. If you don't set any menu, Electron will generate a minimal menu for your app by default.
This app uses the code below to set the application menu. If you click the 'View' option in the application menu and then the 'App Menu Demo', you'll see an information box displayed.
- Main Process
+ Main Process (C#)
var menu = new MenuItem[] {
new MenuItem { Label = "Edit", Submenu = new MenuItem[] {
new MenuItem { Label = "Undo", Accelerator = "CmdOrCtrl+Z", Role = MenuRole.undo },
@@ -135,7 +135,7 @@ Electron.Menu.SetApplicationMenu(menu);
In this demo we use the ipcRenderer module to show the context menu when explicitly calling it from the renderer process.
See the full context-menu event documentation for all the available properties.
- Main Process
+ Main Process (C#)
var menu = new MenuItem[]
{
new MenuItem
@@ -153,7 +153,7 @@ Electron.Menu.SetContextMenu(mainWindow, menu);
Electron.IpcMain.On("show-context-menu", (args) => {
Electron.Menu.ContextMenuPopup(mainWindow);
});
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
window.addEventListener('contextmenu', (e) => {
diff --git a/ElectronNET.WebApp/Views/Notifications/Index.cshtml b/ElectronNET.WebApp/Views/Notifications/Index.cshtml
index 02f0fbe..81965fc 100644
--- a/ElectronNET.WebApp/Views/Notifications/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Notifications/Index.cshtml
@@ -26,7 +26,7 @@
View demo
This demo demonstrates a basic notification. Text only.
- Renderer Process
+ Main Process (C#)
var options = new NotificationOptions("Basic Notification", "Short message part")
{
OnClick = async () => await Electron.Dialog.ShowMessageBoxAsync("Notification clicked")
@@ -47,7 +47,7 @@ Electron.Notification.Show(options);
View demo
This demo demonstrates a basic notification. Both text and a image
- Renderer Process
+ Main Process (C#)
var options = new NotificationOptions("Notification with image", "Short message plus a custom image")
{
OnClick = async () => await Electron.Dialog.ShowMessageBoxAsync("Notification clicked"),
diff --git a/ElectronNET.WebApp/Views/Pdf/Index.cshtml b/ElectronNET.WebApp/Views/Pdf/Index.cshtml
new file mode 100644
index 0000000..071e73d
--- /dev/null
+++ b/ElectronNET.WebApp/Views/Pdf/Index.cshtml
@@ -0,0 +1,79 @@
+
+
+
\ No newline at end of file
diff --git a/ElectronNET.WebApp/Views/Shell/Index.cshtml b/ElectronNET.WebApp/Views/Shell/Index.cshtml
index 1cdadd7..2f647ba 100644
--- a/ElectronNET.WebApp/Views/Shell/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Shell/Index.cshtml
@@ -26,7 +26,7 @@
This demonstrates using the Electron.Shell to open the system file manager at a particular location.
Clicking the demo button will open your file manager at the root.
- Renderer Process
+ Main Process (C#)
string path = await Electron.App.GetPathAsync(PathName.home);
await Electron.Shell.ShowItemInFolderAsync(path);
@@ -45,7 +45,7 @@ await Electron.Shell.ShowItemInFolderAsync(path);
If you do not want your app to open website links within the app, you can use the Electron.Shell to open them externally. When clicked, the links will open outside of your app and in the user's default web browser.
When the demo button is clicked, the electron website will open in your browser.
-
Renderer Process
+ Main Process (C#)
await Electron.Shell.OpenExternalAsync("https://github.com/ElectronNET");
diff --git a/ElectronNET.WebApp/Views/Shortcuts/Index.cshtml b/ElectronNET.WebApp/Views/Shortcuts/Index.cshtml
index 45879d1..b4e9e91 100644
--- a/ElectronNET.WebApp/Views/Shortcuts/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Shortcuts/Index.cshtml
@@ -36,7 +36,7 @@
keyboard focus.
- Main Process
+ Main Process (C#)
Electron.GlobalShortcut.Register("CommandOrControl+Alt+K", async () => {
var options = new MessageBoxOptions("You pressed the registered global shortcut keybinding.")
{
diff --git a/ElectronNET.WebApp/Views/Tray/Index.cshtml b/ElectronNET.WebApp/Views/Tray/Index.cshtml
index 4899a85..967632a 100644
--- a/ElectronNET.WebApp/Views/Tray/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Tray/Index.cshtml
@@ -27,7 +27,7 @@
The demo button sends a message to the main process using the ipcRenderer. In the main process the app is told to place an icon, with a context menu, in the tray.
In this example the tray icon can be removed by clicking 'Remove' in the context menu or selecting the demo button again.
- Main Process
+ Main Process (C#)
Electron.IpcMain.On("put-in-tray", (args) => {
if (Electron.Tray.Items.Count == 0)
@@ -47,7 +47,7 @@
}
});
- Renderer Process
+ Renderer Process (JavaScript)
const { ipcRenderer } = require("electron");
let trayOn = false;
diff --git a/ElectronNET.WebApp/Views/Windows/Index.cshtml b/ElectronNET.WebApp/Views/Windows/Index.cshtml
index 7c227ea..9dc1573 100644
--- a/ElectronNET.WebApp/Views/Windows/Index.cshtml
+++ b/ElectronNET.WebApp/Views/Windows/Index.cshtml
@@ -27,7 +27,7 @@
The Electron.WindowManager gives you the ability to create new windows in your app. This main process can be used from the renderer process with the Electron.IpcMain, as is shown in this demo.
There are a lot of options when creating a new window. A few are in this demo, but visit the documentation(opens in new window) for the full list.
- Renderer Process
+ Main Process (C#)
await Electron.WindowManager.CreateWindowAsync();
@@ -64,7 +64,7 @@ public async void ElectronBootstrap()
In this demo we create a new window and listen for OnMove and OnResize events on it. Click the demo button, change the new window and see the dimensions and position update here, above.
There are a lot of methods for controlling the state of the window such as the size, location, and focus status as well as events to listen to for window changes. Visit the documentation(opens in new window) for the full list.
- Renderer Process
+ Main Process (C#)
public IActionResult Index()
{
Electron.IpcMain.On("manage-window", async (args) => {
@@ -103,7 +103,7 @@ private async void UpdateReply()
Focus on Demo
In this demo, we create a new window and listen for OnBlur event on it. Click the demo button to create a new modal window, and switch focus back to the parent window by clicking on it. You can click the Focus on Demo button to switch focus to the modal window again.
- Renderer Process
+ Main Process (C#)
var mainBrowserWindow = Electron.WindowManager.BrowserWindows.First();
var browserWindow = await Electron.WindowManager.CreateWindowAsync();
@@ -131,7 +131,7 @@ Electron.IpcMain.On("listen-to-window-set-focus", (x) => browserWindow.Focus());
Frame to false when creating the window.
- Renderer Process
+ Main Process
var options = new BrowserWindowOptions
{
Frame = false
diff --git a/ElectronNET.WebApp/wwwroot/assets/img/heart.jpg b/ElectronNET.WebApp/wwwroot/assets/img/heart.jpg
new file mode 100644
index 0000000..fb25a53
Binary files /dev/null and b/ElectronNET.WebApp/wwwroot/assets/img/heart.jpg differ
diff --git a/README.md b/README.md
index 96558ae..a742288 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
Master: [](https://ci.appveyor.com/project/robertmuehsig/electron-net/branch/master)
-Build cross platform desktop apps with .NET Core and ASP.NET NET Core.
+Build cross platform desktop apps with .NET Core 2.0 and ASP.NET NET Core.
# Usage:
@@ -117,33 +117,18 @@ The end result should be an electron app under your __/bin/desktop__ folder.
### Note
> An OS X App can only be built on a host OS X platform.
-## Dev Notes:
+# Contributing
+Feel free to submit a pull request if you find any bugs (to see a list of active issues, visit the [Issues section](https://github.com/ElectronNET/Electron.NET/issues).
+Please make sure all commits are properly documented.
-Currently there are two main projects and a "WebApp" that serves as a demo playground.
+# Authors
-* ElectronNET.API: Defines the Electron / .NET API bridge
-* ElectronNET.CLI: Responsible for the dotnet "electronize" tooling.
+* **Gregor Biswanger** - (Microsoft MVP, Intel Black Belt and Intel Software Innovator) is a freelance lecturer, consultant, trainer, author and speaker. He is a consultant for large and medium-sized companies, organizations and agencies for software architecture, web- and cross-platform development. You can find Gregor often on the road attending or speaking at international conferences. - [Cross-Platform-Blog](http://www.cross-platform-blog.com) - Twitter [@BFreakout](https://www.twitter.com/BFreakout)
+* **Robert Muehsig** - Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek. - [codeinside Blog](https://blog.codeinside.eu) - Twitter [@robert0muehsig](https://twitter.com/robert0muehsig)
+
+See also the list of [contributors](https://github.com/ElectronNET/Electron.NET/graphs/contributors) who participated in this project.
+
+# License
+MIT-licensed
-Both projects create their own nuget package. The resulting nuget packages are saved under "/artifacts".
-
-__Currently__ the packages are just build with version 1.0.0 on your machine. NuGet might pick the wrong version from its own cache, so please read the dev notes if you want to develop!
-
-__ElectronNET.WebApp:__
-
-The WebApp now has referenced the API NuGet package and via the .csproj reference the CLI:
-
-
-
-
-
-
-
-# Dev Notes: Dev Workflow
-
-(at least for the CLI extension)
-
-* Change something in the CLI project
-* rebuild the project (a nuget package should now appear in the /artifacts directory)
-* make sure there is no ElectronNET.CLI package in your %userprofile%\.nuget\packages cache with the same version
-* execute dotnet restore in the WebApp
-* execute dotnet electronize
+**Enjoy!**
\ No newline at end of file