diff --git a/ElectronNET.API/App.cs b/ElectronNET.API/App.cs index c08bb91..e4849ad 100644 --- a/ElectronNET.API/App.cs +++ b/ElectronNET.API/App.cs @@ -2,45 +2,1363 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; -using Quobject.SocketIoClientDotNet.Client; using System; +using System.Threading.Tasks; namespace ElectronNET.API { - public static class App + public sealed class App { - private static Socket _socket; - private static JsonSerializer _jsonSerializer; - - public static IpcMain IpcMain { get; private set; } - - public static void OpenWindow(int width, int height, bool show) + /// + /// Emitted when all windows have been closed. + /// + /// If you do not subscribe to this event and all windows are closed, + /// the default behavior is to quit the app; however, if you subscribe, + /// you control whether the app quits or not.If the user pressed Cmd + Q, + /// or the developer called app.quit(), Electron will first try to close + /// all the windows and then emit the will-quit event, and in this case the + /// window-all-closed event would not be emitted. + /// + public event Action WindowAllClosed { - _jsonSerializer = new JsonSerializer() + add { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; + if (_windowAllClosed == null) + { + BridgeConnector.Socket.On("app-window-all-closed", () => + { + _windowAllClosed(); + }); - _socket = IO.Socket("http://localhost:" + BridgeSettings.SocketPort); - _socket.On(Socket.EVENT_CONNECT, () => + BridgeConnector.Socket.Emit("register-app-window-all-closed-event"); + } + _windowAllClosed += value; + } + remove { - Console.WriteLine("Verbunden!"); + _windowAllClosed -= value; + } + } - var browserWindowOptions = new BrowserWindowOptions() { - Height = height, - Width = width, - Show = show - }; + private event Action _windowAllClosed; - _socket.Emit("createBrowserWindow", JObject.FromObject(browserWindowOptions, _jsonSerializer)); + /// + /// Emitted before the application starts closing its windows. + /// + /// Note: If application quit was initiated by autoUpdater.quitAndInstall() then before-quit is emitted after + /// emitting close event on all windows and closing them. + /// + public event Action BeforeQuit + { + add + { + if (_beforeQuit == null) + { + BridgeConnector.Socket.On("app-before-quit", () => + { + _beforeQuit(); + }); + + BridgeConnector.Socket.Emit("register-app-before-quit-event"); + } + _beforeQuit += value; + } + remove + { + _beforeQuit -= value; + } + } + + private event Action _beforeQuit; + + /// + /// Emitted when all windows have been closed and the application will quit. + /// + /// See the description of the window-all-closed event for the differences between the will-quit and + /// window-all-closed events. + /// + public event Action WillQuit + { + add + { + if (_willQuit == null) + { + BridgeConnector.Socket.On("app-will-quit", () => + { + _willQuit(); + }); + + BridgeConnector.Socket.Emit("register-app-will-quit-event"); + } + _willQuit += value; + } + remove + { + _willQuit -= value; + } + } + + private event Action _willQuit; + + /// + /// Emitted when the application is quitting. + /// + public event Action Quitting + { + add + { + if (_quitting == null) + { + BridgeConnector.Socket.On("app-quit", () => + { + _quitting(); + }); + + BridgeConnector.Socket.Emit("register-app-quit-event"); + } + _quitting += value; + } + remove + { + _quitting -= value; + } + } + + private event Action _quitting; + + /// + /// Emitted when a BrowserWindow gets blurred. + /// + public event Action BrowserWindowBlur + { + add + { + if (_browserWindowBlur == null) + { + BridgeConnector.Socket.On("app-browser-window-blur", () => + { + _browserWindowBlur(); + }); + + BridgeConnector.Socket.Emit("register-app-browser-window-blur-event"); + } + _browserWindowBlur += value; + } + remove + { + _browserWindowBlur -= value; + } + } + + private event Action _browserWindowBlur; + + /// + /// Emitted when a BrowserWindow gets focused. + /// + public event Action BrowserWindowFocus + { + add + { + if (_browserWindowFocus == null) + { + BridgeConnector.Socket.On("app-browser-window-focus", () => + { + _browserWindowFocus(); + }); + + BridgeConnector.Socket.Emit("register-app-browser-window-focus-event"); + } + _browserWindowFocus += value; + } + remove + { + _browserWindowFocus -= value; + } + } + + private event Action _browserWindowFocus; + + /// + /// Emitted when a new BrowserWindow is created. + /// + public event Action BrowserWindowCreated + { + add + { + if (_browserWindowCreated == null) + { + BridgeConnector.Socket.On("app-browser-window-created", () => + { + _browserWindowCreated(); + }); + + BridgeConnector.Socket.Emit("register-app-browser-window-created-event"); + } + _browserWindowCreated += value; + } + remove + { + _browserWindowCreated -= value; + } + } + + private event Action _browserWindowCreated; + + /// + /// Emitted when a new webContents is created. + /// + public event Action WebContentsCreated + { + add + { + if (_webContentsCreated == null) + { + BridgeConnector.Socket.On("app-web-contents-created", () => + { + _webContentsCreated(); + }); + + BridgeConnector.Socket.Emit("register-app-web-contents-created-event"); + } + _webContentsCreated += value; + } + remove + { + _webContentsCreated -= value; + } + } + + private event Action _webContentsCreated; + + /// + /// Emitted when Chrome’s accessibility support changes. + /// This event fires when assistive technologies, such as screen readers, are enabled or disabled. + /// See https://www.chromium.org/developers/design-documents/accessibility for more details. + /// + public event Action AccessibilitySupportChanged + { + add + { + if (_accessibilitySupportChanged == null) + { + BridgeConnector.Socket.On("app-accessibility-support-changed", (state) => + { + _accessibilitySupportChanged((bool)state); + }); + + BridgeConnector.Socket.Emit("register-app-accessibility-support-changed-event"); + } + _accessibilitySupportChanged += value; + } + remove + { + _accessibilitySupportChanged -= value; + } + } + + private event Action _accessibilitySupportChanged; + + internal App() { } + + internal static App Instance + { + get + { + if (_app == null) + { + _app = new App(); + } + + return _app; + } + } + + private static App _app; + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + + /// + /// Try to close all windows. The before-quit event will be emitted first. If all + /// windows are successfully closed, the will-quit event will be emitted and by + /// default the application will terminate. This method guarantees that all + /// beforeunload and unload event handlers are correctly executed. It is possible + /// that a window cancels the quitting by returning false in the beforeunload event + /// handler. + /// + public void Quit() + { + BridgeConnector.Socket.Emit("appQuit"); + } + + /// + /// All windows will be closed immediately without asking user and + /// the before-quit and will-quit events will not be emitted. + /// + /// Exits immediately with exitCode. exitCode defaults to 0. + public void Exit(int exitCode = 0) + { + BridgeConnector.Socket.Emit("appExit", exitCode); + } + + /// + /// Relaunches the app when current instance exits. By default the new instance will + /// use the same working directory and command line arguments with current instance. + /// When args is specified, the args will be passed as command line arguments + /// instead. When execPath is specified, the execPath will be executed for relaunch + /// instead of current app. Note that this method does not quit the app when + /// executed, you have to call app.quit or app.exit after calling app.relaunch to + /// make the app restart. When app.relaunch is called for multiple times, multiple + /// instances will be started after current instance exited. + /// + public void Relaunch() + { + BridgeConnector.Socket.Emit("appRelaunch"); + } + + /// + /// Relaunches the app when current instance exits. By default the new instance will + /// use the same working directory and command line arguments with current instance. + /// When args is specified, the args will be passed as command line arguments + /// instead. When execPath is specified, the execPath will be executed for relaunch + /// instead of current app. Note that this method does not quit the app when + /// executed, you have to call app.quit or app.exit after calling app.relaunch to + /// make the app restart. When app.relaunch is called for multiple times, multiple + /// instances will be started after current instance exited. + /// + /// + public void Relaunch(RelaunchOptions relaunchOptions) + { + BridgeConnector.Socket.Emit("appRelaunch", JObject.FromObject(relaunchOptions, _jsonSerializer)); + } + + /// + /// On Linux, focuses on the first visible window. On macOS, makes the application + /// the active app.On Windows, focuses on the application's first window. + /// + public void Focus() + { + BridgeConnector.Socket.Emit("appFocus"); + } + + /// + /// Hides all application windows without minimizing them. + /// + public void Hide() + { + BridgeConnector.Socket.Emit("appHide"); + } + + /// + /// Shows application windows after they were hidden. Does not automatically focus them. + /// + public void Show() + { + BridgeConnector.Socket.Emit("appShow"); + } + + /// + /// The current application directory. + /// + /// + public async Task GetAppPathAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetAppPathCompleted", (path) => + { + BridgeConnector.Socket.Off("appGetAppPathCompleted"); + taskCompletionSource.SetResult(path.ToString()); }); - IpcMain = new IpcMain(_socket); + BridgeConnector.Socket.Emit("appGetAppPath"); + + return await taskCompletionSource.Task; } - public static void CreateNotification(NotificationOptions notificationOptions) + /// + /// You can request the following paths by the name. + /// + /// + /// A path to a special directory or file associated with name. + public async Task GetPathAsync(PathName pathName) { - _socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer)); + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetPathCompleted", (path) => + { + BridgeConnector.Socket.Off("appGetPathCompleted"); + + taskCompletionSource.SetResult(path.ToString()); + }); + + BridgeConnector.Socket.Emit("appGetPath", pathName.ToString()); + + return await taskCompletionSource.Task; } + + // TODO: Fertig coden + /// + /// Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux + /// and macOS, icons depend on the application associated with file mime type. + /// + /// + /// + //public async static Task GetFileIconAsync(string filePath) + //{ + // var taskCompletionSource = new TaskCompletionSource(); + + // BridgeConnector.Socket.On("appGetFileIconCompleted", (results) => + // { + // BridgeConnector.Socket.Off("appGetFileIconCompleted"); + + // byte[] test = ((JArray)results).Last.ToObject(); + + + // //object[] result = results as object[]; + // //NativeImage nativeImage = (NativeImage)result[1]; + // //taskCompletionSource.SetResult(nativeImage); + // }); + // BridgeConnector.Socket.Emit("appGetFileIcon", filePath); + + // return await taskCompletionSource.Task; + //} + + // TODO: Fertig coden + + /// + /// Fetches a path's associated icon. On Windows, there a 2 kinds of icons: On Linux + /// and macOS, icons depend on the application associated with file mime type. + /// + /// + /// + /// + //public async static Task GetFileIconAsync(string filePath, FileIconOptions fileIconOptions) + //{ + // var taskCompletionSource = new TaskCompletionSource(); + + // BridgeConnector.Socket.On("appGetFileIconCompleted", (results) => + // { + // BridgeConnector.Socket.Off("appGetFileIconCompleted"); + + // object[] result = results as object[]; + // NativeImage nativeImage = (NativeImage)result[1]; + // taskCompletionSource.SetResult(nativeImage); + // }); + // BridgeConnector.Socket.Emit("appGetFileIcon", filePath, JObject.FromObject(fileIconOptions, _jsonSerializer)); + + // return await taskCompletionSource.Task; + //} + + /// + /// Overrides the path to a special directory or file associated with name. If the + /// path specifies a directory that does not exist, the directory will be created by + /// this method.On failure an Error is thrown.You can only override paths of a + /// name defined in app.getPath. By default, web pages' cookies and caches will be + /// stored under the userData directory.If you want to change this location, you + /// have to override the userData path before the ready event of the app module is emitted. + /// + /// + /// + public void SetPath(string name, string path) + { + BridgeConnector.Socket.Emit("appSetPath", name, path); + } + + /// + /// The version of the loaded application. + /// If no version is found in the application’s package.json file, + /// the version of the current bundle or executable is returned. + /// + /// + public async Task GetVersionAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetVersionCompleted", (version) => + { + BridgeConnector.Socket.Off("appGetVersionCompleted"); + taskCompletionSource.SetResult(version.ToString()); + }); + + BridgeConnector.Socket.Emit("appGetVersion"); + + return await taskCompletionSource.Task; + } + + /// + /// Usually the name field of package.json is a short lowercased name, according to + /// the npm modules spec. You should usually also specify a productName field, which + /// is your application's full capitalized name, and which will be preferred over + /// name by Electron. + /// + /// The current application’s name, which is the name in the application’s package.json file. + public async Task GetNameAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetNameCompleted", (name) => + { + BridgeConnector.Socket.Off("appGetNameCompleted"); + taskCompletionSource.SetResult(name.ToString()); + }); + + BridgeConnector.Socket.Emit("appGetName"); + + return await taskCompletionSource.Task; + } + + /// + /// Overrides the current application's name. + /// + /// Application's name + public void SetName(string name) + { + BridgeConnector.Socket.Emit("appSetName", name); + } + + /// + /// The current application locale. + /// Note: When distributing your packaged app, you have to also ship the locales + /// folder.Note: On Windows you have to call it after the ready events gets emitted. + /// + /// + public async Task GetLocaleAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetLocaleCompleted", (locale) => + { + BridgeConnector.Socket.Off("appGetLocaleCompleted"); + taskCompletionSource.SetResult(locale.ToString()); + }); + + BridgeConnector.Socket.Emit("appGetLocale"); + + return await taskCompletionSource.Task; + } + + /// + /// Adds path to the recent documents list. This list is managed by the OS. On + /// Windows you can visit the list from the task bar, and on macOS you can visit it + /// from dock menu. + /// + /// + public void AddRecentDocument(string path) + { + BridgeConnector.Socket.Emit("appAddRecentDocument", path); + } + + /// + /// Clears the recent documents list. + /// + public void ClearRecentDocuments() + { + BridgeConnector.Socket.Emit("appClearRecentDocuments"); + } + + /// + /// This method sets the current executable as the default handler for a protocol + /// (aka URI scheme). It allows you to integrate your app deeper into the operating + /// system.Once registered, all links with your-protocol:// will be opened with the + /// current executable. The whole link, including protocol, will be passed to your + /// application as a parameter. On Windows you can provide optional parameters path, + /// the path to your executable, and args, an array of arguments to be passed to + /// your executable when it launches.Note: On macOS, you can only register + /// protocols that have been added to your app's info.plist, which can not be + /// modified at runtime.You can however change the file with a simple text editor + /// or script during build time. Please refer to Apple's documentation for details. + /// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme + /// internally. + /// + /// The name of your protocol, without ://. + /// If you want your app to handle electron:// links, + /// call this method with electron as the parameter. + /// Whether the call succeeded. + public async Task SetAsDefaultProtocolClientAsync(string protocol) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appSetAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appSetAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appSetAsDefaultProtocolClient", protocol); + + return await taskCompletionSource.Task; + } + + /// + /// This method sets the current executable as the default handler for a protocol + /// (aka URI scheme). It allows you to integrate your app deeper into the operating + /// system.Once registered, all links with your-protocol:// will be opened with the + /// current executable. The whole link, including protocol, will be passed to your + /// application as a parameter. On Windows you can provide optional parameters path, + /// the path to your executable, and args, an array of arguments to be passed to + /// your executable when it launches.Note: On macOS, you can only register + /// protocols that have been added to your app's info.plist, which can not be + /// modified at runtime.You can however change the file with a simple text editor + /// or script during build time. Please refer to Apple's documentation for details. + /// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme + /// internally. + /// + /// The name of your protocol, without ://. + /// If you want your app to handle electron:// links, + /// call this method with electron as the parameter. + /// Defaults to process.execPath + /// Whether the call succeeded. + public async Task SetAsDefaultProtocolClientAsync(string protocol, string path) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appSetAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appSetAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appSetAsDefaultProtocolClient", protocol, path); + + return await taskCompletionSource.Task; + } + + /// + /// This method sets the current executable as the default handler for a protocol + /// (aka URI scheme). It allows you to integrate your app deeper into the operating + /// system.Once registered, all links with your-protocol:// will be opened with the + /// current executable. The whole link, including protocol, will be passed to your + /// application as a parameter. On Windows you can provide optional parameters path, + /// the path to your executable, and args, an array of arguments to be passed to + /// your executable when it launches.Note: On macOS, you can only register + /// protocols that have been added to your app's info.plist, which can not be + /// modified at runtime.You can however change the file with a simple text editor + /// or script during build time. Please refer to Apple's documentation for details. + /// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme + /// internally. + /// + /// The name of your protocol, without ://. + /// If you want your app to handle electron:// links, + /// call this method with electron as the parameter. + /// Defaults to process.execPath + /// Defaults to an empty array + /// Whether the call succeeded. + public async Task SetAsDefaultProtocolClientAsync(string protocol, string path, string[] args) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appSetAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appSetAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appSetAsDefaultProtocolClient", protocol, path, args); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable as the default handler for a + /// protocol(aka URI scheme). If so, it will remove the app as the default handler. + /// + /// The name of your protocol, without ://. + /// Whether the call succeeded. + public async Task RemoveAsDefaultProtocolClientAsync(string protocol) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appRemoveAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appRemoveAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appRemoveAsDefaultProtocolClient", protocol); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable as the default handler for a + /// protocol(aka URI scheme). If so, it will remove the app as the default handler. + /// + /// The name of your protocol, without ://. + /// Defaults to process.execPath. + /// Whether the call succeeded. + public async Task RemoveAsDefaultProtocolClientAsync(string protocol, string path) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appRemoveAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appRemoveAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appRemoveAsDefaultProtocolClient", protocol, path); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable as the default handler for a + /// protocol(aka URI scheme). If so, it will remove the app as the default handler. + /// + /// The name of your protocol, without ://. + /// Defaults to process.execPath. + /// Defaults to an empty array. + /// Whether the call succeeded. + public async Task RemoveAsDefaultProtocolClientAsync(string protocol, string path, string[] args) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appRemoveAsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appRemoveAsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appRemoveAsDefaultProtocolClient", protocol, path, args); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable is the default handler for a + /// protocol(aka URI scheme). If so, it will return true. Otherwise, it will return + /// false. Note: On macOS, you can use this method to check if the app has been + /// registered as the default protocol handler for a protocol.You can also verify + /// this by checking ~/Library/Preferences/com.apple.LaunchServices.plist on the + /// macOS machine.Please refer to Apple's documentation for details. The API uses + /// the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. + /// + /// The name of your protocol, without ://. + /// Returns Boolean + public async Task IsDefaultProtocolClientAsync(string protocol) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appIsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appIsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appIsDefaultProtocolClient", protocol); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable is the default handler for a + /// protocol(aka URI scheme). If so, it will return true. Otherwise, it will return + /// false. Note: On macOS, you can use this method to check if the app has been + /// registered as the default protocol handler for a protocol.You can also verify + /// this by checking ~/Library/Preferences/com.apple.LaunchServices.plist on the + /// macOS machine.Please refer to Apple's documentation for details. The API uses + /// the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. + /// + /// The name of your protocol, without ://. + /// Defaults to process.execPath. + /// Returns Boolean + public async Task IsDefaultProtocolClientAsync(string protocol, string path) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appIsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appIsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appIsDefaultProtocolClient", protocol, path); + + return await taskCompletionSource.Task; + } + + /// + /// This method checks if the current executable is the default handler for a + /// protocol(aka URI scheme). If so, it will return true. Otherwise, it will return + /// false. Note: On macOS, you can use this method to check if the app has been + /// registered as the default protocol handler for a protocol.You can also verify + /// this by checking ~/Library/Preferences/com.apple.LaunchServices.plist on the + /// macOS machine.Please refer to Apple's documentation for details. The API uses + /// the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. + /// + /// The name of your protocol, without ://. + /// Defaults to process.execPath. + /// Defaults to an empty array. + /// Returns Boolean + public async Task IsDefaultProtocolClientAsync(string protocol, string path, string[] args) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appIsDefaultProtocolClientCompleted", (success) => + { + BridgeConnector.Socket.Off("appIsDefaultProtocolClientCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appIsDefaultProtocolClient", protocol, path, args); + + return await taskCompletionSource.Task; + } + + /// + /// Adds tasks to the Tasks category of the JumpList on Windows. tasks is an array + /// of Task objects.Note: If you'd like to customize the Jump List even more use + /// app.setJumpList(categories) instead. + /// + /// Array of Task objects. + /// Whether the call succeeded. + public async Task SetUserTasksAsync(UserTask[] userTasks) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appSetUserTasksCompleted", (success) => + { + BridgeConnector.Socket.Off("appSetUserTasksCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appSetUserTasks", JObject.FromObject(userTasks, _jsonSerializer)); + + return await taskCompletionSource.Task; + } + + /// + /// Jump List settings for the application. + /// + /// + public async Task GetJumpListSettingsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetJumpListSettingsCompleted", (success) => + { + BridgeConnector.Socket.Off("appGetJumpListSettingsCompleted"); + taskCompletionSource.SetResult(JObject.Parse(success.ToString()).ToObject()); + }); + + BridgeConnector.Socket.Emit("appGetJumpListSettings"); + + return await taskCompletionSource.Task; + } + + /// + /// Sets or removes a custom Jump List for the application, and returns one of the + /// following strings: If categories is null the previously set custom Jump List(if + /// any) will be replaced by the standard Jump List for the app(managed by + /// Windows). Note: If a JumpListCategory object has neither the type nor the name + /// property set then its type is assumed to be tasks.If the name property is set + /// but the type property is omitted then the type is assumed to be custom. Note: + /// Users can remove items from custom categories, and Windows will not allow a + /// removed item to be added back into a custom category until after the next + /// successful call to app.setJumpList(categories). Any attempt to re-add a removed + /// item to a custom category earlier than that will result in the entire custom + /// category being omitted from the Jump List. The list of removed items can be + /// obtained using app.getJumpListSettings(). + /// + /// + public void SetJumpList(JumpListCategory[] jumpListCategories) + { + BridgeConnector.Socket.Emit("appSetJumpList", JObject.FromObject(jumpListCategories, _jsonSerializer)); + } + + /// + /// This method makes your application a Single Instance Application - instead of + /// allowing multiple instances of your app to run, this will ensure that only a + /// single instance of your app is running, and other instances signal this instance + /// and exit.callback will be called by the first instance with callback(argv, + /// workingDirectory) when a second instance has been executed.argv is an Array of + /// the second instance's command line arguments, and workingDirectory is its + /// current working directory.Usually applications respond to this by making their + /// primary window focused and non-minimized.The callback is guaranteed to be + /// executed after the ready event of app gets emitted.This method returns false if + /// your process is the primary instance of the application and your app should + /// continue loading.And returns true if your process has sent its parameters to + /// another instance, and you should immediately quit.On macOS the system enforces + /// single instance automatically when users try to open a second instance of your + /// app in Finder, and the open-file and open-url events will be emitted for that. + /// However when users start your app in command line the system's single instance + /// mechanism will be bypassed and you have to use this method to ensure single + /// instance. + /// + /// Lambda with an array of the second instance’s command line arguments. + /// The second parameter is the working directory path. + /// This method returns false if your process is the primary instance of + /// the application and your app should continue loading. And returns true if your + /// process has sent its parameters to another instance, and you should immediately quit. + public async Task MakeSingleInstanceAsync(Action newInstanceOpened) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appMakeSingleInstanceCompleted", (success) => + { + BridgeConnector.Socket.Off("appMakeSingleInstanceCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Off("newInstanceOpened"); + BridgeConnector.Socket.On("newInstanceOpened", (result) => + { + JArray results = (JArray)result; + string[] args = results.First.ToObject(); + string workdirectory = results.Last.ToObject(); + + newInstanceOpened(args, workdirectory); + }); + + BridgeConnector.Socket.Emit("appMakeSingleInstance"); + + return await taskCompletionSource.Task; + } + + /// + /// Releases all locks that were created by makeSingleInstance. This will allow + /// multiple instances of the application to once again run side by side. + /// + public void ReleaseSingleInstance() + { + BridgeConnector.Socket.Emit("appReleaseSingleInstance"); + } + + /// + /// Creates an NSUserActivity and sets it as the current activity. The activity is + /// eligible for Handoff to another device afterward. + /// + /// Uniquely identifies the activity. Maps to NSUserActivity.activityType. + /// App-specific state to store for use by another device. + public void SetUserActivity(string type, object userInfo) + { + BridgeConnector.Socket.Emit("appSetUserActivity", type, userInfo); + } + + /// + /// Creates an NSUserActivity and sets it as the current activity. The activity is + /// eligible for Handoff to another device afterward. + /// + /// Uniquely identifies the activity. Maps to NSUserActivity.activityType. + /// App-specific state to store for use by another device. + /// The webpage to load in a browser if no suitable app is installed on the resuming device. The scheme must be http or https. + public void SetUserActivity(string type, object userInfo, string webpageURL) + { + BridgeConnector.Socket.Emit("appSetUserActivity", type, userInfo, webpageURL); + } + + /// + /// The type of the currently running activity. + /// + /// + public async Task GetCurrentActivityTypeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetCurrentActivityTypeCompleted", (activityType) => + { + BridgeConnector.Socket.Off("appGetCurrentActivityTypeCompleted"); + taskCompletionSource.SetResult(activityType.ToString()); + }); + + BridgeConnector.Socket.Emit("appGetCurrentActivityType"); + + return await taskCompletionSource.Task; + } + + /// + /// Changes the Application User Model ID to id. + /// + /// + public void SetAppUserModelId(string id) + { + BridgeConnector.Socket.Emit("appSetAppUserModelId", id); + } + + /// + /// Imports the certificate in pkcs12 format into the platform certificate store. + /// callback is called with the result of import operation, a value of 0 indicates + /// success while any other value indicates failure according to chromium net_error_list. + /// + /// + /// Result of import. Value of 0 indicates success. + public async Task ImportCertificateAsync(ImportCertificateOptions options) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appImportCertificateCompleted", (result) => + { + BridgeConnector.Socket.Off("appImportCertificateCompleted"); + taskCompletionSource.SetResult((int)result); + }); + + BridgeConnector.Socket.Emit("appImportCertificate", JObject.FromObject(options, _jsonSerializer)); + + return await taskCompletionSource.Task; + } + + /// + /// Memory and cpu usage statistics of all the processes associated with the app. + /// + /// + public async Task GetAppMetricsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetAppMetricsCompleted", (result) => + { + BridgeConnector.Socket.Off("appGetAppMetricsCompleted"); + var processMetrics = ((JArray)result).ToObject(); + + taskCompletionSource.SetResult(processMetrics); + }); + + BridgeConnector.Socket.Emit("appGetAppMetrics"); + + return await taskCompletionSource.Task; + } + + /// + /// The Graphics Feature Status from chrome://gpu/. + /// + /// + public async Task GetGpuFeatureStatusAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetGpuFeatureStatusCompleted", (result) => + { + BridgeConnector.Socket.Off("appGetGpuFeatureStatusCompleted"); + var gpuFeatureStatus = ((JObject)result).ToObject(); + + taskCompletionSource.SetResult(gpuFeatureStatus); + }); + + BridgeConnector.Socket.Emit("appGetGpuFeatureStatus"); + + return await taskCompletionSource.Task; + } + + /// + /// Sets the counter badge for current app. Setting the count to 0 will hide the + /// badge. On macOS it shows on the dock icon. On Linux it only works for Unity + /// launcher, Note: Unity launcher requires the existence of a.desktop file to + /// work, for more information please read Desktop Environment Integration. + /// + /// + /// Whether the call succeeded. + public async Task SetBadgeCountAsync(int count) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appSetBadgeCountCompleted", (success) => + { + BridgeConnector.Socket.Off("appSetBadgeCountCompleted"); + taskCompletionSource.SetResult((bool)success); + }); + + BridgeConnector.Socket.Emit("appSetBadgeCount", count); + + return await taskCompletionSource.Task; + } + + /// + /// The current value displayed in the counter badge. + /// + /// + public async Task GetBadgeCountAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetBadgeCountCompleted", (count) => + { + BridgeConnector.Socket.Off("appGetBadgeCountCompleted"); + taskCompletionSource.SetResult((int)count); + }); + + BridgeConnector.Socket.Emit("appGetBadgeCount"); + + return await taskCompletionSource.Task; + } + + /// + /// Whether the current desktop environment is Unity launcher. + /// + /// + public async Task IsUnityRunningAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appIsUnityRunningCompleted", (isUnityRunning) => + { + BridgeConnector.Socket.Off("appIsUnityRunningCompleted"); + taskCompletionSource.SetResult((bool)isUnityRunning); + }); + + BridgeConnector.Socket.Emit("appIsUnityRunning"); + + return await taskCompletionSource.Task; + } + + /// + /// If you provided path and args options to app.setLoginItemSettings then you need + /// to pass the same arguments here for openAtLogin to be set correctly. Note: This + /// API has no effect on MAS builds. + /// + /// + public async Task GetLoginItemSettingsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetLoginItemSettingsCompleted", (loginItemSettings) => + { + BridgeConnector.Socket.Off("appGetLoginItemSettingsCompleted"); + taskCompletionSource.SetResult((LoginItemSettings)loginItemSettings); + }); + + BridgeConnector.Socket.Emit("appGetLoginItemSettings"); + + return await taskCompletionSource.Task; + } + + /// + /// If you provided path and args options to app.setLoginItemSettings then you need + /// to pass the same arguments here for openAtLogin to be set correctly. Note: This + /// API has no effect on MAS builds. + /// + /// + /// + public async Task GetLoginItemSettingsAsync(LoginItemSettingsOptions options) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appGetLoginItemSettingsCompleted", (loginItemSettings) => + { + BridgeConnector.Socket.Off("appGetLoginItemSettingsCompleted"); + taskCompletionSource.SetResult((LoginItemSettings)loginItemSettings); + }); + + BridgeConnector.Socket.Emit("appGetLoginItemSettings", JObject.FromObject(options, _jsonSerializer)); + + return await taskCompletionSource.Task; + } + + /// + /// Set the app's login item settings. To work with Electron's autoUpdater on + /// Windows, which uses Squirrel, you'll want to set the launch path to Update.exe, + /// and pass arguments that specify your application name. + /// + /// + public void SetLoginItemSettings(LoginSettings loginSettings) + { + BridgeConnector.Socket.Emit("appSetLoginItemSettings", JObject.FromObject(loginSettings, _jsonSerializer)); + } + + /// + /// This API will return true if the use of assistive technologies, + /// such as screen readers, has been detected. + /// See https://www.chromium.org/developers/design-documents/accessibility for more details. + /// + /// true if Chrome’s accessibility support is enabled, false otherwise. + public async Task IsAccessibilitySupportEnabledAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appIsAccessibilitySupportEnabledCompleted", (isAccessibilitySupportEnabled) => + { + BridgeConnector.Socket.Off("appIsAccessibilitySupportEnabledCompleted"); + taskCompletionSource.SetResult((bool)isAccessibilitySupportEnabled); + }); + + BridgeConnector.Socket.Emit("appIsAccessibilitySupportEnabled"); + + return await taskCompletionSource.Task; + } + + /// + /// Set the about panel options. This will override the values defined in the app's + /// .plist file. See the Apple docs for more details. + /// + /// + public void SetAboutPanelOptions(AboutPanelOptions options) + { + BridgeConnector.Socket.Emit("appSetAboutPanelOptions", JObject.FromObject(options, _jsonSerializer)); + } + + /// + /// Append a switch (with optional value) to Chromium's command line. Note: This + /// will not affect process.argv, and is mainly used by developers to control some + /// low-level Chromium behaviors. + /// + /// A command-line switch. + public void CommandLineAppendSwitch(string theSwtich) + { + BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", theSwtich); + } + + /// + /// Append a switch (with optional value) to Chromium's command line. Note: This + /// will not affect process.argv, and is mainly used by developers to control some + /// low-level Chromium behaviors. + /// + /// A command-line switch. + /// A value for the given switch. + public void CommandLineAppendSwitch(string theSwtich, string value) + { + BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", theSwtich, value); + } + + /// + /// Append an argument to Chromium's command line. The argument will be quoted + /// correctly.Note: This will not affect process.argv. + /// + /// The argument to append to the command line. + public void CommandLineAppendArgument(string value) + { + BridgeConnector.Socket.Emit("appCommandLineAppendArgument", value); + } + + /// + /// Enables mixed sandbox mode on the app. This method can only be called before app is ready. + /// + public void EnableMixedSandbox() + { + BridgeConnector.Socket.Emit("appEnableMixedSandbox"); + } + + /// + /// When critical is passed, the dock icon will bounce until either the application + /// becomes active or the request is canceled.When informational is passed, the + /// dock icon will bounce for one second.However, the request remains active until + /// either the application becomes active or the request is canceled. + /// + /// + /// + public async Task DockBounceAsync(DockBounceType type) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appDockBounceCompleted", (id) => + { + BridgeConnector.Socket.Off("appDockBounceCompleted"); + taskCompletionSource.SetResult((int)id); + }); + + BridgeConnector.Socket.Emit("appDockBounce", type.ToString()); + + return await taskCompletionSource.Task; + } + + /// + /// Cancel the bounce of id. + /// + /// + public void DockCancelBounce(int id) + { + BridgeConnector.Socket.Emit("appDockCancelBounce", id); + } + + /// + /// Bounces the Downloads stack if the filePath is inside the Downloads folder. + /// + /// + public void DockDownloadFinished(string filePath) + { + BridgeConnector.Socket.Emit("appDockDownloadFinished", filePath); + } + + /// + /// Sets the string to be displayed in the dock’s badging area. + /// + /// + public void DockSetBadge(string text) + { + BridgeConnector.Socket.Emit("appDockSetBadge", text); + } + + /// + /// Gets the string to be displayed in the dock’s badging area. + /// + /// + public async Task DockGetBadgeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appDockGetBadgeCompleted", (text) => + { + BridgeConnector.Socket.Off("appDockGetBadgeCompleted"); + taskCompletionSource.SetResult((string)text); + }); + + BridgeConnector.Socket.Emit("appDockGetBadge"); + + return await taskCompletionSource.Task; + } + + /// + /// Hides the dock icon. + /// + public void DockHide() + { + BridgeConnector.Socket.Emit("appDockHide"); + } + + /// + /// Shows the dock icon. + /// + public void DockShow() + { + BridgeConnector.Socket.Emit("appDockShow"); + } + + /// + /// Whether the dock icon is visible. The app.dock.show() call is asynchronous + /// so this method might not return true immediately after that call. + /// + /// + public async Task DockIsVisibleAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("appDockIsVisibleCompleted", (isVisible) => + { + BridgeConnector.Socket.Off("appDockIsVisibleCompleted"); + taskCompletionSource.SetResult((bool)isVisible); + }); + + BridgeConnector.Socket.Emit("appDockIsVisible"); + + return await taskCompletionSource.Task; + } + + // TODO: Menu lösung muss gemacht werden und imeplementiert + /// + /// Sets the application's dock menu. + /// + public void DockSetMenu() + { + BridgeConnector.Socket.Emit("appDockSetMenu"); + } + + /// + /// Sets the image associated with this dock icon. + /// + /// + public void DockSetIcon(string image) + { + BridgeConnector.Socket.Emit("appDockSetIcon", image); + } + + /// + /// Sets the image associated with this dock icon. + /// + /// + //public static void DockSetIcon(NativeImage image) + //{ + // BridgeConnector.Socket.Emit("appDockSetIcon", JObject.FromObject(image, _jsonSerializer)); + //} } } diff --git a/ElectronNET.API/BridgeConnector.cs b/ElectronNET.API/BridgeConnector.cs new file mode 100644 index 0000000..bac492d --- /dev/null +++ b/ElectronNET.API/BridgeConnector.cs @@ -0,0 +1,19 @@ +using Quobject.SocketIoClientDotNet.Client; +using System; + +namespace ElectronNET.API +{ + internal static class BridgeConnector + { + public static Socket Socket; + + public static void StartConnection() + { + Socket = IO.Socket("http://localhost:" + BridgeSettings.SocketPort); + Socket.On(Socket.EVENT_CONNECT, () => + { + Console.WriteLine("BridgeConnector connected!"); + }); + } + } +} diff --git a/ElectronNET.API/BrowserWindow.cs b/ElectronNET.API/BrowserWindow.cs new file mode 100644 index 0000000..790f0f0 --- /dev/null +++ b/ElectronNET.API/BrowserWindow.cs @@ -0,0 +1,612 @@ +using ElectronNET.API.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System.Threading.Tasks; + +namespace ElectronNET.API +{ + public class BrowserWindow + { + public int Id { get; private set; } + + internal BrowserWindow(int id) { + Id = id; + } + + /// + /// Force closing the window, the unload and beforeunload event won’t be + /// emitted for the web page, and close event will also not be emitted + /// for this window, but it guarantees the closed event will be emitted. + /// + public void Destroy() + { + BridgeConnector.Socket.Emit("browserWindow-destroy", Id); + } + + /// + /// Try to close the window. This has the same effect as a user manually + /// clicking the close button of the window. The web page may cancel the close though. + /// + public void Close() + { + BridgeConnector.Socket.Emit("browserWindow-close", Id); + } + + /// + /// Focuses on the window. + /// + public void Focus() + { + BridgeConnector.Socket.Emit("browserWindow-focus", Id); + } + + /// + /// Removes focus from the window. + /// + public void Blur() + { + BridgeConnector.Socket.Emit("browserWindow-blur", Id); + } + + /// + /// Whether the window is focused. + /// + /// + public Task IsFocusedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isFocused-completed", (isFocused) => { + BridgeConnector.Socket.Off("browserWindow-isFocused-completed"); + + taskCompletionSource.SetResult((bool)isFocused); + }); + + BridgeConnector.Socket.Emit("browserWindow-isFocused", Id); + + return taskCompletionSource.Task; + } + + /// + /// Whether the window is destroyed. + /// + /// + public Task IsDestroyedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isDestroyed-completed", (isDestroyed) => { + BridgeConnector.Socket.Off("browserWindow-isDestroyed-completed"); + + taskCompletionSource.SetResult((bool)isDestroyed); + }); + + BridgeConnector.Socket.Emit("browserWindow-isDestroyed", Id); + + return taskCompletionSource.Task; + } + + /// + /// Shows and gives focus to the window. + /// + public void Show() + { + BridgeConnector.Socket.Emit("browserWindow-show", Id); + } + + /// + /// Shows the window but doesn’t focus on it. + /// + public void ShowInactive() + { + BridgeConnector.Socket.Emit("browserWindow-showInactive", Id); + } + + /// + /// Hides the window. + /// + public void Hide() + { + BridgeConnector.Socket.Emit("browserWindow-hide", Id); + } + + /// + /// Whether the window is visible to the user. + /// + /// + public Task IsVisibleAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isVisible-completed", (isVisible) => { + BridgeConnector.Socket.Off("browserWindow-isVisible-completed"); + + taskCompletionSource.SetResult((bool)isVisible); + }); + + BridgeConnector.Socket.Emit("browserWindow-isVisible", Id); + + return taskCompletionSource.Task; + } + + /// + /// Whether current window is a modal window. + /// + /// + public Task IsModalAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isModal-completed", (isModal) => { + BridgeConnector.Socket.Off("browserWindow-isModal-completed"); + + taskCompletionSource.SetResult((bool)isModal); + }); + + BridgeConnector.Socket.Emit("browserWindow-isModal", Id); + + return taskCompletionSource.Task; + } + + /// + /// Maximizes the window. This will also show (but not focus) the window if it isn’t being displayed already. + /// + public void Maximize() + { + BridgeConnector.Socket.Emit("browserWindow-maximize", Id); + } + + /// + /// Unmaximizes the window. + /// + public void Unmaximize() + { + BridgeConnector.Socket.Emit("browserWindow-unmaximize", Id); + } + + /// + /// Whether the window is maximized. + /// + /// + public Task IsMaximizedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMaximized-completed", (isMaximized) => { + BridgeConnector.Socket.Off("browserWindow-isMaximized-completed"); + + taskCompletionSource.SetResult((bool)isMaximized); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMaximized", Id); + + return taskCompletionSource.Task; + } + + /// + /// Minimizes the window. On some platforms the minimized window will be shown in the Dock. + /// + public void Minimize() + { + BridgeConnector.Socket.Emit("browserWindow-minimize", Id); + } + + /// + /// Restores the window from minimized state to its previous state. + /// + public void Restore() + { + BridgeConnector.Socket.Emit("browserWindow-restore", Id); + } + + /// + /// Whether the window is minimized. + /// + /// + public Task IsMinimizedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMinimized-completed", (isMinimized) => { + BridgeConnector.Socket.Off("browserWindow-isMinimized-completed"); + + taskCompletionSource.SetResult((bool)isMinimized); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMinimized", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window should be in fullscreen mode. + /// + public void SetFullScreen(bool flag) + { + BridgeConnector.Socket.Emit("browserWindow-setFullScreen", Id, flag); + } + + /// + /// Whether the window is in fullscreen mode. + /// + /// + public Task IsFullScreenAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isFullScreen-completed", (isFullScreen) => { + BridgeConnector.Socket.Off("browserWindow-isFullScreen-completed"); + + taskCompletionSource.SetResult((bool)isFullScreen); + }); + + BridgeConnector.Socket.Emit("browserWindow-isFullScreen", Id); + + return taskCompletionSource.Task; + } + + /// + /// This will make a window maintain an aspect ratio. The extra size allows a developer to have space, + /// specified in pixels, not included within the aspect ratio calculations. This API already takes into + /// account the difference between a window’s size and its content size. + /// + /// Consider a normal window with an HD video player and associated controls.Perhaps there are 15 pixels + /// of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below + /// the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within + /// the player itself we would call this function with arguments of 16/9 and[40, 50]. The second argument + /// doesn’t care where the extra width and height are within the content view–only that they exist. Just + /// sum any extra width and height areas you have within the overall content view. + /// + /// The aspect ratio to maintain for some portion of the content view. + /// The extra size not to be included while maintaining the aspect ratio. + public void SetAspectRatio(int aspectRatio, Size extraSize) + { + BridgeConnector.Socket.Emit("browserWindow-setAspectRatio", Id, aspectRatio, JObject.FromObject(extraSize, _jsonSerializer)); + } + + /// + /// Uses Quick Look to preview a file at a given path. + /// + /// The absolute path to the file to preview with QuickLook. This is important as + /// Quick Look uses the file name and file extension on the path to determine the content type of the + /// file to open. + public void PreviewFile(string path) + { + BridgeConnector.Socket.Emit("browserWindow-previewFile", Id, path); + } + + /// + /// Uses Quick Look to preview a file at a given path. + /// + /// The absolute path to the file to preview with QuickLook. This is important as + /// Quick Look uses the file name and file extension on the path to determine the content type of the + /// file to open. + /// The name of the file to display on the Quick Look modal view. This is + /// purely visual and does not affect the content type of the file. Defaults to path. + public void PreviewFile(string path, string displayname) + { + BridgeConnector.Socket.Emit("browserWindow-previewFile", Id, path, displayname); + } + + /// + /// Closes the currently open Quick Look panel. + /// + public void CloseFilePreview() + { + BridgeConnector.Socket.Emit("browserWindow-closeFilePreview", Id); + } + + /// + /// Resizes and moves the window to the supplied bounds + /// + /// + public void SetBounds(Rectangle bounds) + { + BridgeConnector.Socket.Emit("browserWindow-setBounds", Id, JObject.FromObject(bounds, _jsonSerializer)); + } + + /// + /// Resizes and moves the window to the supplied bounds + /// + /// + /// + public void SetBounds(Rectangle bounds, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate); + } + + public Task GetBoundsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getBounds-completed", (getBounds) => { + BridgeConnector.Socket.Off("browserWindow-getBounds-completed"); + + taskCompletionSource.SetResult(((JObject)getBounds).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getBounds", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes and moves the window’s client area (e.g. the web page) to the supplied bounds. + /// + /// + public void SetContentBounds(Rectangle bounds) + { + BridgeConnector.Socket.Emit("browserWindow-setContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer)); + } + + /// + /// Resizes and moves the window’s client area (e.g. the web page) to the supplied bounds. + /// + /// + /// + public void SetContentBounds(Rectangle bounds, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate); + } + + public Task GetContentBoundsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getContentBounds-completed", (getContentBounds) => { + BridgeConnector.Socket.Off("browserWindow-getContentBounds-completed"); + + taskCompletionSource.SetResult(((JObject)getContentBounds).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getContentBounds", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes the window to width and height. + /// + /// + /// + /// + public void SetSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setSize", Id, width, height); + } + + /// + /// Resizes the window to width and height. + /// + /// + /// + /// + public void SetSize(int width, int height, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setSize", Id, width, height, animate); + } + + /// + /// Contains the window’s width and height. + /// + /// + public Task GetSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes the window’s client area (e.g. the web page) to width and height. + /// + /// + /// + /// + public void SetContentSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setContentSize", Id, width, height); + } + + /// + /// Resizes the window’s client area (e.g. the web page) to width and height. + /// + /// + /// + /// + public void SetContentSize(int width, int height, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setContentSize", Id, width, height, animate); + } + + /// + /// Contains the window’s client area’s width and height. + /// + /// + public Task GetContentSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getContentSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getContentSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getContentSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets the minimum size of window to width and height. + /// + /// + /// + public void SetMinimumSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setMinimumSize", Id, width, height); + } + + /// + /// Contains the window’s minimum width and height. + /// + /// + public Task GetMinimumSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getMinimumSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getMinimumSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getMinimumSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets the maximum size of window to width and height. + /// + /// + /// + public void SetMaximumSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setMaximumSize", Id, width, height); + } + + /// + /// Contains the window’s maximum width and height. + /// + /// + public Task GetMaximumSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getMaximumSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getMaximumSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getMaximumSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually resized by user. + /// + /// + public void SetResizable(bool resizable) + { + BridgeConnector.Socket.Emit("browserWindow-setResizable", Id, resizable); + } + + /// + /// Whether the window can be manually resized by user. + /// + /// + public Task IsResizableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isResizable-completed", (resizable) => { + BridgeConnector.Socket.Off("browserWindow-isResizable-completed"); + + taskCompletionSource.SetResult((bool)resizable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isResizable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be moved by user. On Linux does nothing. + /// + /// + public void SetMovable(bool movable) + { + BridgeConnector.Socket.Emit("browserWindow-setMovable", Id, movable); + } + + /// + /// Whether the window can be moved by user. + /// + /// On Linux always returns true. + /// + /// On Linux always returns true. + public Task IsMovableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMovable-completed", (movable) => { + BridgeConnector.Socket.Off("browserWindow-isMovable-completed"); + + taskCompletionSource.SetResult((bool)movable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMovable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually minimized by user. On Linux does nothing. + /// + /// + public void SetMinimizable(bool minimizable) + { + BridgeConnector.Socket.Emit("browserWindow-setMinimizable", Id, minimizable); + } + + /// + /// Whether the window can be manually minimized by user. + /// + /// On Linux always returns true. + /// + /// On Linux always returns true. + public Task IsMinimizableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMinimizable-completed", (minimizable) => { + BridgeConnector.Socket.Off("browserWindow-isMinimizable-completed"); + + taskCompletionSource.SetResult((bool)minimizable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMinimizable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually maximized by user. On Linux does nothing. + /// + /// + public void SetMaximizable(bool maximizable) + { + BridgeConnector.Socket.Emit("browserWindow-setMaximizable", Id, maximizable); + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.API/Dialog.cs b/ElectronNET.API/Dialog.cs new file mode 100644 index 0000000..f47afac --- /dev/null +++ b/ElectronNET.API/Dialog.cs @@ -0,0 +1,89 @@ +using ElectronNET.API.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System; +using System.Threading.Tasks; + +namespace ElectronNET.API +{ + public sealed class Dialog + { + private static Dialog _dialog; + + internal Dialog() { } + + internal static Dialog Instance + { + get + { + if (_dialog == null) + { + _dialog = new Dialog(); + } + + return _dialog; + } + } + + /// + /// Shows a message box, it will block the process until the message box is closed. + /// It returns the index of the clicked button. The browserWindow argument allows + /// the dialog to attach itself to a parent window, making it modal. If a callback + /// is passed, the dialog will not block the process.The API call will be + /// asynchronous and the result will be passed via callback(response). + /// + /// + /// The API call will be asynchronous and the result will be passed via MessageBoxResult. + public async Task ShowMessageBoxAsync(MessageBoxOptions messageBoxOptions) + { + return await ShowMessageBoxAsync(null, messageBoxOptions); + } + + /// + /// Shows a message box, it will block the process until the message box is closed. + /// It returns the index of the clicked button. If a callback + /// is passed, the dialog will not block the process. + /// + /// The browserWindow argument allows the dialog to attach itself to a parent window, making it modal. + /// + /// The API call will be asynchronous and the result will be passed via MessageBoxResult. + public Task ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions) + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("showMessageBoxComplete", (args) => + { + BridgeConnector.Socket.Off("showMessageBoxComplete"); + + var result = ((JArray)args); + + taskCompletionSource.SetResult(new MessageBoxResult + { + Response = (int)result.First, + CheckboxChecked = (bool)result.Last + }); + + }); + + if (browserWindow == null) + { + BridgeConnector.Socket.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer)); + } else + { + BridgeConnector.Socket.Emit("showMessageBox", + JObject.FromObject(browserWindow, _jsonSerializer), + JObject.FromObject(messageBoxOptions, _jsonSerializer)); + } + + return taskCompletionSource.Task; + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.API/Electron.cs b/ElectronNET.API/Electron.cs new file mode 100644 index 0000000..6002677 --- /dev/null +++ b/ElectronNET.API/Electron.cs @@ -0,0 +1,40 @@ +namespace ElectronNET.API +{ + public static class Electron + { + /// + /// Communicate asynchronously from the main process to renderer processes. + /// + public static IpcMain IpcMain { get { return IpcMain.Instance; } } + + /// + /// Control your application's event lifecycle. + /// + public static App App { get { return App.Instance; } } + + /// + /// Control your windows. + /// + public static WindowManager WindowManager { get { return WindowManager.Instance; } } + + /// + /// Create native application menus and context menus. + /// + public static Menu Menu { get { return Menu.Instance; } } + + /// + /// Display native system dialogs for opening and saving files, alerting, etc. + /// + public static Dialog Dialog { get { return Dialog.Instance; } } + + /// + /// Create OS desktop notifications + /// + public static Notification Notification { get { return Notification.Instance; } } + + /// + /// Add icons and context menus to the system’s notification area. + /// + public static Tray Tray { get { return Tray.Instance; } } + } +} diff --git a/ElectronNET.API/Entities/AboutPanelOptions.cs b/ElectronNET.API/Entities/AboutPanelOptions.cs new file mode 100644 index 0000000..db47d7e --- /dev/null +++ b/ElectronNET.API/Entities/AboutPanelOptions.cs @@ -0,0 +1,30 @@ +namespace ElectronNET.API.Entities +{ + public class AboutPanelOptions + { + /// + /// The app's name. + /// + public string ApplicationName { get; set; } + + /// + /// The app's version. + /// + public string ApplicationVersion { get; set; } + + /// + /// Copyright information. + /// + public string Copyright { get; set; } + + /// + /// Credit information. + /// + public string Credits { get; set; } + + /// + /// The app's build version number. + /// + public string Version { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/BrowserWindowOptions.cs b/ElectronNET.API/Entities/BrowserWindowOptions.cs index 8a817e7..9e6ed33 100644 --- a/ElectronNET.API/Entities/BrowserWindowOptions.cs +++ b/ElectronNET.API/Entities/BrowserWindowOptions.cs @@ -2,8 +2,243 @@ { public class BrowserWindowOptions { + /// + /// Window's width in pixels. Default is 800. + /// public int Width { get; set; } + + /// + /// Window's height in pixels. Default is 600. + /// public int Height { get; set; } + + /// + /// ( if y is used) Window's left offset from screen. Default is to center the + /// window. + /// + public int X { get; set; } + + /// + /// ( if x is used) Window's top offset from screen. Default is to center the + /// window. + /// + public int Y { get; set; } + + /// + /// The width and height would be used as web page's size, which means the actual + /// window's size will include window frame's size and be slightly larger.Default + /// is false. + /// + public bool UseContentSize { get; set; } + + /// + /// Show window in the center of the screen. + /// + public bool Center { get; set; } + + /// + /// Window's minimum width. Default is 0. + /// + public int MinWidth { get; set; } + + /// + /// Window's minimum height. Default is 0. + /// + public int MinHeight { get; set; } + + /// + /// Window's maximum width. Default is no limit. + /// + public int MaxWidth { get; set; } + + /// + /// Window's maximum height. Default is no limit. + /// + public int MaxHeight { get; set; } + + /// + /// Whether window is resizable. Default is true. + /// + public bool Resizable { get; set; } + + /// + /// Whether window is movable. This is not implemented on Linux. Default is true. + /// + public bool Movable { get; set; } + + /// + /// Whether window is minimizable. This is not implemented on Linux. Default is true. + /// + public bool Minimizable { get; set; } + + /// + /// Whether window is maximizable. This is not implemented on Linux. Default is true. + /// + public bool Maximizable { get; set; } + + /// + /// Whether window is closable. This is not implemented on Linux. Default is true. + /// + public bool Closable { get; set; } + + /// + /// Whether the window can be focused. Default is true. On Windows setting + /// focusable: false also implies setting skipTaskbar: true. On Linux setting + /// focusable: false makes the window stop interacting with wm, so the window will + /// always stay on top in all workspaces. + /// + public bool Focusable { get; set; } + + /// + /// Whether the window should always stay on top of other windows. Default is false. + /// + public bool AlwaysOnTop { get; set; } + + /// + /// Whether the window should show in fullscreen. When explicitly set to false the + /// fullscreen button will be hidden or disabled on macOS.Default is false. + /// + public bool Fullscreen { get; set; } + + /// + /// Whether the window can be put into fullscreen mode. On macOS, also whether the + /// maximize/zoom button should toggle full screen mode or maximize window.Default + /// is true. + /// + public bool Fullscreenable { get; set; } + + /// + /// Whether to show the window in taskbar. Default is false. + /// + public bool SkipTaskbar { get; set; } + + /// + /// The kiosk mode. Default is false. + /// + public bool Kiosk { get; set; } + + /// + /// Default window title. Default is "Electron.NET". + /// + public string Title { get; set; } = "Electron.NET"; + + /// + /// The window icon. On Windows it is recommended to use ICO icons to get best + /// visual effects, you can also leave it undefined so the executable's icon will be used. + /// + public string Icon { get; set; } + + /// + /// Whether window should be shown when created. Default is true. + /// public bool Show { get; set; } + + /// + /// Specify false to create a . Default is true. + /// + public bool Frame { get; set; } + + /// + /// Whether this is a modal window. This only works when the window is a child + /// window.Default is false. + /// + public bool Modal { get; set; } + + /// + /// Whether the web view accepts a single mouse-down event that simultaneously + /// activates the window.Default is false. + /// + public bool AcceptFirstMouse { get; set; } + + /// + /// Whether to hide cursor when typing. Default is false. + /// + public bool DisableAutoHideCursor { get; set; } + + /// + /// Auto hide the menu bar unless the Alt key is pressed. Default is false. + /// + public bool AutoHideMenuBar { get; set; } + + /// + /// Enable the window to be resized larger than screen. Default is false. + /// + public bool EnableLargerThanScreen { get; set; } + + /// + /// Window's background color as Hexadecimal value, like #66CD00 or #FFF or + /// #80FFFFFF (alpha is supported). Default is #FFF (white). + /// + public string BackgroundColor { get; set; } + + /// + /// Whether window should have a shadow. This is only implemented on macOS. Default + /// is true. + /// + public bool HasShadow { get; set; } + + /// + /// Forces using dark theme for the window, only works on some GTK+3 desktop + /// environments.Default is false. + /// + public bool DarkTheme { get; set; } + + /// + /// Makes the window . Default is false. + /// + public bool Transparent { get; set; } + + /// + /// The type of window, default is normal window. + /// + public string Type { get; set; } + + /// + /// The style of window title bar. Default is default. Possible values are: + /// 'default' | 'hidden' | 'hidden-inset' | 'hiddenInset' | 'customButtonsOnHover' + /// + public string TitleBarStyle { get; set; } + + /// + /// Shows the title in the tile bar in full screen mode on macOS for all + /// titleBarStyle options.Default is false. + /// + public bool FullscreenWindowTitle { get; set; } + + /// + /// Use WS_THICKFRAME style for frameless windows on Windows, which adds standard + /// window frame.Setting it to false will remove window shadow and window + /// animations.Default is true. + /// + public bool ThickFrame { get; set; } + + /// + /// Add a type of vibrancy effect to the window, only on macOS. Can be + /// appearance-based, light, dark, titlebar, selection, menu, popover, sidebar, + /// medium-light or ultra-dark. + /// + public string Vibrancy { get; set; } + + /// + /// Controls the behavior on macOS when option-clicking the green stoplight button + /// on the toolbar or by clicking the Window > Zoom menu item.If true, the window + /// will grow to the preferred width of the web page when zoomed, false will cause + /// it to zoom to the width of the screen.This will also affect the behavior when + /// calling maximize() directly.Default is false. + /// + public bool ZoomToPageWidth { get; set; } + + /// + /// Tab group name, allows opening the window as a native tab on macOS 10.12+. + /// Windows with the same tabbing identifier will be grouped together.This also + /// adds a native new tab button to your window's tab bar and allows your app and + /// window to receive the new-window-for-tab event. + /// + public string TabbingIdentifier { get; set; } + + /// + /// Settings of web page's features. + /// + public WebPreferences WebPreferences { get; set; } } } diff --git a/ElectronNET.API/Entities/CPUUsage.cs b/ElectronNET.API/Entities/CPUUsage.cs new file mode 100644 index 0000000..0fb461a --- /dev/null +++ b/ElectronNET.API/Entities/CPUUsage.cs @@ -0,0 +1,16 @@ +namespace ElectronNET.API.Entities +{ + public class CPUUsage + { + /// + /// The number of average idle cpu wakeups per second since the last call to + /// getCPUUsage.First call returns 0. + /// + public int IdleWakeupsPerSecond { get; set; } + + /// + /// Percentage of CPU used since the last call to getCPUUsage. First call returns 0. + /// + public int PercentCPUUsage { get; set; } + } +} diff --git a/ElectronNET.API/Entities/DockBounceType.cs b/ElectronNET.API/Entities/DockBounceType.cs new file mode 100644 index 0000000..5af53ed --- /dev/null +++ b/ElectronNET.API/Entities/DockBounceType.cs @@ -0,0 +1,8 @@ +namespace ElectronNET.API +{ + public enum DockBounceType + { + critical, + informational + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/FileIconOptions.cs b/ElectronNET.API/Entities/FileIconOptions.cs new file mode 100644 index 0000000..4293a0a --- /dev/null +++ b/ElectronNET.API/Entities/FileIconOptions.cs @@ -0,0 +1,12 @@ +namespace ElectronNET.API.Entities +{ + public class FileIconOptions + { + public string Size { get; private set; } + + public FileIconOptions(FileIconSize fileIconSize) + { + Size = fileIconSize.ToString(); + } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/FileIconSize.cs b/ElectronNET.API/Entities/FileIconSize.cs new file mode 100644 index 0000000..7841ee8 --- /dev/null +++ b/ElectronNET.API/Entities/FileIconSize.cs @@ -0,0 +1,9 @@ +namespace ElectronNET.API.Entities +{ + public enum FileIconSize + { + small, + normal, + large + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/GPUFeatureStatus.cs b/ElectronNET.API/Entities/GPUFeatureStatus.cs new file mode 100644 index 0000000..a21aac5 --- /dev/null +++ b/ElectronNET.API/Entities/GPUFeatureStatus.cs @@ -0,0 +1,82 @@ +using Newtonsoft.Json; + +namespace ElectronNET.API.Entities +{ + public class GPUFeatureStatus + { + /// + /// Canvas + /// + [JsonProperty("2d_canvas")] + public string Canvas { get; set; } + + /// + /// Flash + /// + [JsonProperty("flash_3d")] + public string Flash3D { get; set; } + + /// + /// Flash Stage3D + /// + [JsonProperty("flash_stage3d")] + public string FlashStage3D { get; set; } + + /// + /// Flash Stage3D Baseline profile + /// + [JsonProperty("flash_stage3d_baseline")] + public string FlashStage3dBaseline { get; set; } + + /// + /// Compositing + /// + [JsonProperty("gpu_compositing")] + public string GpuCompositing { get; set; } + + /// + /// Multiple Raster Threads + /// + [JsonProperty("multiple_raster_threads")] + public string MultipleRasterThreads { get; set; } + + /// + /// Native GpuMemoryBuffers + /// + [JsonProperty("native_gpu_memory_buffers")] + public string NativeGpuMemoryBuffers { get; set; } + + /// + /// Rasterization + /// + public string Rasterization { get; set; } + + /// + /// Video Decode + /// + [JsonProperty("video_decode")] + public string VideoDecode { get; set; } + + /// + /// Video Encode + /// + [JsonProperty("video_encode")] + public string VideoEncode { get; set; } + + /// + /// VPx Video Decode + /// + [JsonProperty("vpx_decode")] + public string VpxDecode { get; set; } + + /// + /// WebGL + /// + public string Webgl { get; set; } + + /// + /// WebGL2 + /// + public string Webgl2 { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/ImportCertificateOptions.cs b/ElectronNET.API/Entities/ImportCertificateOptions.cs new file mode 100644 index 0000000..779992c --- /dev/null +++ b/ElectronNET.API/Entities/ImportCertificateOptions.cs @@ -0,0 +1,15 @@ +namespace ElectronNET.API.Entities +{ + public class ImportCertificateOptions + { + /// + /// Path for the pkcs12 file. + /// + public string Certificate { get; set; } + + /// + /// Passphrase for the certificate. + /// + public string Password {get; set; } + } +} diff --git a/ElectronNET.API/Entities/JumpListCategory.cs b/ElectronNET.API/Entities/JumpListCategory.cs new file mode 100644 index 0000000..e7ca486 --- /dev/null +++ b/ElectronNET.API/Entities/JumpListCategory.cs @@ -0,0 +1,22 @@ +using ElectronNET.API.Entities; + +namespace ElectronNET.API +{ + public class JumpListCategory + { + /// + /// Must be set if type is custom, otherwise it should be omitted. + /// + public string Name { get; set; } = string.Empty; + + /// + /// Array of objects if type is tasks or custom, otherwise it should be omitted. + /// + public JumpListItem[] Items { get; set; } = new JumpListItem[0]; + + /// + /// One of the following: "tasks" | "frequent" | "recent" | "custom" + /// + public string Type { get; set; } = "tasks"; + } +} diff --git a/ElectronNET.API/Entities/JumpListItem.cs b/ElectronNET.API/Entities/JumpListItem.cs new file mode 100644 index 0000000..8d1ac63 --- /dev/null +++ b/ElectronNET.API/Entities/JumpListItem.cs @@ -0,0 +1,51 @@ +namespace ElectronNET.API.Entities +{ + public class JumpListItem + { + /// + /// The command line arguments when program is executed. Should only be set if type is task. + /// + public string Args { get; set; } = string.Empty; + + /// + /// Description of the task (displayed in a tooltip). Should only be set if type is task. + /// + public string Description { get; set; } = string.Empty; + + /// + /// The index of the icon in the resource file. If a resource file contains multiple + /// icons this value can be used to specify the zero-based index of the icon that + /// should be displayed for this task.If a resource file contains only one icon, + /// this property should be set to zero. + /// + public int IconIndex { get; set; } = 0; + + /// + /// The absolute path to an icon to be displayed in a Jump List, which can be an + /// arbitrary resource file that contains an icon(e.g. .ico, .exe, .dll). You can + /// usually specify process.execPath to show the program icon. + /// + public string IconPath { get; set; } = string.Empty; + + /// + /// Path of the file to open, should only be set if type is file. + /// + public string Path { get; set; } = string.Empty; + + /// + /// Path of the program to execute, usually you should specify process.execPath + /// which opens the current program.Should only be set if type is task. + /// + public string Program { get; set; } = string.Empty; + + /// + /// The text to be displayed for the item in the Jump List. Should only be set if type is task. + /// + public string Title { get; set; } = string.Empty; + + /// + /// One of the following: "task" | "separator" | "file" + /// + public string Type {get; set; } = string.Empty; + } +} diff --git a/ElectronNET.API/Entities/JumpListSettings.cs b/ElectronNET.API/Entities/JumpListSettings.cs new file mode 100644 index 0000000..b7964cd --- /dev/null +++ b/ElectronNET.API/Entities/JumpListSettings.cs @@ -0,0 +1,15 @@ +namespace ElectronNET.API.Entities +{ + public class JumpListSettings + { + /// + /// The minimum number of items that will be shown in the Jump List (for a more detailed description of this value see the MSDN docs). + /// + public int MinItems { get; set; } = 0; + + /// + /// Array of JumpListItem objects that correspond to items that the user has explicitly removed from custom categories in the Jump List. These items must not be re-added to the Jump List in the next call to app.setJumpList(), Windows will not display any custom category that contains any of the removed items. + /// + public JumpListItem[] RemovedItems { get; set; } = new JumpListItem[0]; + } +} diff --git a/ElectronNET.API/Entities/LoginItemSettings.cs b/ElectronNET.API/Entities/LoginItemSettings.cs new file mode 100644 index 0000000..67e9535 --- /dev/null +++ b/ElectronNET.API/Entities/LoginItemSettings.cs @@ -0,0 +1,36 @@ +namespace ElectronNET.API.Entities +{ + public class LoginItemSettings + { + /// + /// true if the app is set to open at login. + /// + public bool OpenAtLogin { get; set; } + + /// + /// true if the app is set to open as hidden at login. This setting is only + /// supported on macOS. + /// + public bool OpenAsHidden { get; set; } + + /// + /// true if the app was opened at login automatically. This setting is only + /// supported on macOS. + /// + public bool WasOpenedAtLogin { get; set; } + + /// + /// true if the app was opened as a hidden login item. This indicates that the app + /// should not open any windows at startup.This setting is only supported on macOS. + /// + public bool WasOpenedAsHidden { get; set; } + + /// + /// true if the app was opened as a login item that should restore the state from + /// the previous session.This indicates that the app should restore the windows + /// that were open the last time the app was closed.This setting is only supported + /// on macOS. + /// + public bool RestoreState { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/LoginItemSettingsOptions.cs b/ElectronNET.API/Entities/LoginItemSettingsOptions.cs new file mode 100644 index 0000000..aee888d --- /dev/null +++ b/ElectronNET.API/Entities/LoginItemSettingsOptions.cs @@ -0,0 +1,15 @@ +namespace ElectronNET.API.Entities +{ + public class LoginItemSettingsOptions + { + /// + /// The executable path to compare against. Defaults to process.execPath. + /// + public string Path { get; set; } + + /// + /// The command-line arguments to compare against. Defaults to an empty array. + /// + public string[] Args { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/LoginSettings.cs b/ElectronNET.API/Entities/LoginSettings.cs new file mode 100644 index 0000000..aec8203 --- /dev/null +++ b/ElectronNET.API/Entities/LoginSettings.cs @@ -0,0 +1,30 @@ +namespace ElectronNET.API.Entities +{ + public class LoginSettings + { + /// + /// true to open the app at login, false to remove the app as a login item. Defaults + /// to false. + /// + public bool OpenAtLogin { get; set; } + + /// + /// true to open the app as hidden. Defaults to false. The user can edit this + /// setting from the System Preferences so + /// app.getLoginItemStatus().wasOpenedAsHidden should be checked when the app is + /// opened to know the current value.This setting is only supported on macOS. + /// + public bool OpenAsHidden { get; set; } + + /// + /// The executable to launch at login. Defaults to process.execPath. + /// + public string Path { get; set; } + + /// + /// The command-line arguments to pass to the executable. Defaults to an empty + /// array.Take care to wrap paths in quotes. + /// + public string[] Args { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/MemoryInfo.cs b/ElectronNET.API/Entities/MemoryInfo.cs new file mode 100644 index 0000000..f31423b --- /dev/null +++ b/ElectronNET.API/Entities/MemoryInfo.cs @@ -0,0 +1,33 @@ +namespace ElectronNET.API.Entities +{ + public class MemoryInfo + { + /// + /// The maximum amount of memory that has ever been pinned to actual physical RAM. + /// On macOS its value will always be 0. + /// + public int PeakWorkingSetSize { get; set; } + + /// + /// Process id of the process. + /// + public int Pid { get; set; } + + /// + /// The amount of memory not shared by other processes, such as JS heap or HTML + /// content. + /// + public int PrivateBytes { get; set; } + + /// + /// The amount of memory shared between processes, typically memory consumed by the + /// Electron code itself + /// + public int SharedBytes { get; set; } + + /// + /// The amount of memory currently pinned to actual physical RAM. + /// + public int WorkingSetSize {get; set; } + } +} diff --git a/ElectronNET.API/Entities/MenuItem.cs b/ElectronNET.API/Entities/MenuItem.cs new file mode 100644 index 0000000..667993b --- /dev/null +++ b/ElectronNET.API/Entities/MenuItem.cs @@ -0,0 +1,72 @@ +using Newtonsoft.Json; +using System; + +namespace ElectronNET.API.Entities +{ + public class MenuItem + { + /// + /// Will be called with click(menuItem, browserWindow, event) when the menu item is + /// clicked. + /// + [JsonIgnore] + public Action Click { get; set; } + + /// + /// Define the action of the menu item, when specified the click property will be + /// ignored. + /// + public string Role { get; set; } + + /// + /// Can be normal, separator, submenu, checkbox or radio. + /// + public string Type { get; set; } + + + public string Label { get; set; } + + + public string Sublabel { get; set; } + + + public string Accelerator { get; set; } + + + public string Icon { get; set; } + + /// + /// If false, the menu item will be greyed out and unclickable. + /// + public bool Enabled { get; set; } + + /// + /// If false, the menu item will be entirely hidden. + /// + public bool Visible { get; set; } + + /// + /// Should only be specified for checkbox or radio type menu items. + /// + public bool Checked { get; set; } + + /// + /// Should be specified for submenu type menu items. If submenu is specified, the + /// type: 'submenu' can be omitted.If the value is not a Menu then it will be + /// automatically converted to one using Menu.buildFromTemplate. + /// + public MenuItem[] Submenu { get; set; } + + /// + /// Unique within a single menu. If defined then it can be used as a reference to + /// this item by the position attribute. + /// + public string Id { get; internal set; } + + /// + /// This field allows fine-grained definition of the specific location within a + /// given menu. + /// + public string Position { get; set; } + } +} diff --git a/ElectronNET.API/Entities/MessageBoxOptions.cs b/ElectronNET.API/Entities/MessageBoxOptions.cs new file mode 100644 index 0000000..960471c --- /dev/null +++ b/ElectronNET.API/Entities/MessageBoxOptions.cs @@ -0,0 +1,84 @@ +namespace ElectronNET.API.Entities +{ + public class MessageBoxOptions + { + /// + /// Can be "none", "info", "error", "question" or "warning". On Windows, "question" + /// displays the same icon as "info", unless you set an icon using the "icon" + /// option.On macOS, both "warning" and "error" display the same warning icon. + /// + public string Type { get; set; } + + /// + /// Array of texts for buttons. On Windows, an empty array will result in one button + /// labeled "OK". + /// + public string[] Buttons { get; set; } + + /// + /// Index of the button in the buttons array which will be selected by default when + /// the message box opens. + /// + public int DefaultId { get; set; } + + /// + /// Title of the message box, some platforms will not show it. + /// + public string Title { get; set; } + + /// + /// Content of the message box. + /// + public string Message { get; set; } + + /// + /// Extra information of the message. + /// + public string Detail { get; set; } + + /// + /// If provided, the message box will include a checkbox with the given label. The + /// checkbox state can be inspected only when using callback. + /// + public string CheckboxLabel { get; set; } + + /// + /// Initial checked state of the checkbox. false by default. + /// + public bool CheckboxChecked { get; set; } + + public string Icon { get; set; } + + /// + /// The index of the button to be used to cancel the dialog, via the Esc key. By + /// default this is assigned to the first button with "cancel" or "no" as the label. + /// If no such labeled buttons exist and this option is not set, 0 will be used as + /// the return value or callback response. This option is ignored on Windows. + /// + public int CancelId { get; set; } + + /// + /// On Windows Electron will try to figure out which one of the buttons are common + /// buttons(like "Cancel" or "Yes"), and show the others as command links in the + /// dialog.This can make the dialog appear in the style of modern Windows apps. If + /// you don't like this behavior, you can set noLink to true. + /// + public bool NoLink { get; set; } + + /// + /// Normalize the keyboard access keys across platforms. Default is false. Enabling + /// this assumes & is used in the button labels for the placement of the keyboard + /// shortcut access key and labels will be converted so they work correctly on each + /// platform, & characters are removed on macOS, converted to _ on Linux, and left + /// untouched on Windows.For example, a button label of Vie&w will be converted to + /// Vie_w on Linux and View on macOS and can be selected via Alt-W on Windows and + /// Linux. + /// + public bool NormalizeAccessKeys { get; set; } + + public MessageBoxOptions(string message) + { + Message = message; + } + } +} diff --git a/ElectronNET.API/Entities/MessageBoxResult.cs b/ElectronNET.API/Entities/MessageBoxResult.cs new file mode 100644 index 0000000..20a19b6 --- /dev/null +++ b/ElectronNET.API/Entities/MessageBoxResult.cs @@ -0,0 +1,9 @@ +namespace ElectronNET.API.Entities +{ + public class MessageBoxResult + { + public int Response { get; set; } + + public bool CheckboxChecked { get; set; } + } +} diff --git a/ElectronNET.API/Entities/NativeImage.cs b/ElectronNET.API/Entities/NativeImage.cs new file mode 100644 index 0000000..deb6210 --- /dev/null +++ b/ElectronNET.API/Entities/NativeImage.cs @@ -0,0 +1,106 @@ +namespace ElectronNET.API.Entities +{ + // TODO: Fertig coden + public class NativeImage + { + // public static NativeImage CreateEmpty() + // { + // throw new NotImplementedException(); + // } + + // public static NativeImage CreateFromBuffer(byte[] buffer) + // { + // throw new NotImplementedException(); + // } + + // public static NativeImage CreateFromBuffer(byte[] buffer, CreateFromBufferOptions options) + // { + // throw new NotImplementedException(); + // } + + // public static NativeImage CreateFromDataURL(string dataURL) + // { + // throw new NotImplementedException(); + // } + + // public static NativeImage CreateFromPath(string path) + // { + // throw new NotImplementedException(); + // } + + // public void AddRepresentation(AddRepresentationOptions options) + // { + // throw new NotImplementedException(); + // } + + // public NativeImage Crop(Rectangle rect) + // { + // throw new NotImplementedException(); + // } + + // public int GetAspectRatio() + // { + // throw new NotImplementedException(); + // } + + // public byte[] GetBitmap() + // { + // throw new NotImplementedException(); + // } + + // public byte[] GetBitmap(BitmapOptions options) + // { + // throw new NotImplementedException(); + // } + + // public byte[] GetNativeHandle() + // { + // throw new NotImplementedException(); + // } + + // public Size GetSize() + // { + // throw new NotImplementedException(); + // } + + // public bool IsEmpty() + // { + // throw new NotImplementedException(); + // } + + // public bool IsTemplateImage() + // { + // throw new NotImplementedException(); + // } + + // public NativeImage Resize(ResizeOptions options) + // { + // throw new NotImplementedException(); + // } + + // public void SetTemplateImage(bool option) + // { + // throw new NotImplementedException(); + // } + + // public byte[] ToBitmap(ToBitmapOptions options) + // { + // throw new NotImplementedException(); + // } + + // public string ToDataURL(ToDataURLOptions options) + // { + // throw new NotImplementedException(); + // } + + // public byte[] ToJPEG(int quality) + // { + // throw new NotImplementedException(); + // } + + // public byte[] ToPNG(ToPNGOptions options) + // { + // throw new NotImplementedException(); + // } + } +} diff --git a/ElectronNET.API/Entities/NotificationOptions.cs b/ElectronNET.API/Entities/NotificationOptions.cs index b58e954..efa127f 100644 --- a/ElectronNET.API/Entities/NotificationOptions.cs +++ b/ElectronNET.API/Entities/NotificationOptions.cs @@ -2,7 +2,52 @@ { public class NotificationOptions { + /// + /// A title for the notification, which will be shown at the top of the notification + /// window when it is shown + /// public string Title { get; set; } + + /// + /// The body text of the notification, which will be displayed below the title or + /// subtitle + /// public string Body { get; set; } + + /// + /// A subtitle for the notification, which will be displayed below the title. + /// + public string Subtitle { get; set; } + + /// + /// Whether or not to emit an OS notification noise when showing the notification + /// + public bool Silent { get; set; } + + /// + /// An icon to use in the notification + /// + public string Icon { get; set; } + + /// + /// Whether or not to add an inline reply option to the notification. + /// + public bool HasReply { get; set; } + + /// + /// The placeholder to write in the inline reply input field. + /// + public string ReplyPlaceholder { get; set; } + + /// + /// The name of the sound file to play when the notification is shown. + /// + public string Sound { get; set; } + + public NotificationOptions(string title, string body) + { + Title = title; + Body = body; + } } } diff --git a/ElectronNET.API/Entities/PathName.cs b/ElectronNET.API/Entities/PathName.cs new file mode 100644 index 0000000..0435b4c --- /dev/null +++ b/ElectronNET.API/Entities/PathName.cs @@ -0,0 +1,76 @@ +namespace ElectronNET.API.Entities +{ + public enum PathName + { + /// + /// User’s home directory. + /// + home, + + /// + /// Per-user application data directory. + /// + appData, + + /// + /// The directory for storing your app’s configuration files, + /// which by default it is the appData directory appended with your app’s name. + /// + userData, + + /// + /// Temporary directory. + /// + temp, + + /// + /// The current executable file. + /// + exe, + + /// + /// The libchromiumcontent library. + /// + module, + + /// + /// The current user’s Desktop directory. + /// + desktop, + + /// + /// Directory for a user’s “My Documents”. + /// + documents, + + /// + /// Directory for a user’s downloads. + /// + downloads, + + /// + /// Directory for a user’s music. + /// + music, + + /// + /// Directory for a user’s pictures. + /// + pictures, + + /// + /// Directory for a user’s videos. + /// + videos, + + /// + /// + /// + logs, + + /// + /// Full path to the system version of the Pepper Flash plugin. + /// + pepperFlashSystemPlugin + } +} diff --git a/ElectronNET.API/Entities/ProcessMetric.cs b/ElectronNET.API/Entities/ProcessMetric.cs new file mode 100644 index 0000000..79cab89 --- /dev/null +++ b/ElectronNET.API/Entities/ProcessMetric.cs @@ -0,0 +1,25 @@ +namespace ElectronNET.API.Entities +{ + public class ProcessMetric + { + /// + /// CPU usage of the process. + /// + public CPUUsage Cpu { get; set; } + + /// + /// Memory information for the process. + /// + public MemoryInfo Memory {get; set;} + + /// + /// Process id of the process. + /// + public int Pid { get; set; } + + /// + /// Process type (Browser or Tab or GPU etc). + /// + public string Type { get; set; } + } +} diff --git a/ElectronNET.API/Entities/Rectangle.cs b/ElectronNET.API/Entities/Rectangle.cs new file mode 100644 index 0000000..7e1a8eb --- /dev/null +++ b/ElectronNET.API/Entities/Rectangle.cs @@ -0,0 +1,10 @@ +namespace ElectronNET.API.Entities +{ + public class Rectangle + { + public int X { get; set; } + public int Y { get; set; } + public int Width { get; set; } + public int Height { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/RelaunchOptions.cs b/ElectronNET.API/Entities/RelaunchOptions.cs new file mode 100644 index 0000000..55ff88e --- /dev/null +++ b/ElectronNET.API/Entities/RelaunchOptions.cs @@ -0,0 +1,8 @@ +namespace ElectronNET.API.Entities +{ + public class RelaunchOptions + { + public string[] Args { get; set; } + public string ExecPath { get; set; } + } +} diff --git a/ElectronNET.API/Entities/Size.cs b/ElectronNET.API/Entities/Size.cs new file mode 100644 index 0000000..459428a --- /dev/null +++ b/ElectronNET.API/Entities/Size.cs @@ -0,0 +1,9 @@ +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/Entities/UserTask.cs b/ElectronNET.API/Entities/UserTask.cs new file mode 100644 index 0000000..1b37d67 --- /dev/null +++ b/ElectronNET.API/Entities/UserTask.cs @@ -0,0 +1,12 @@ +namespace ElectronNET.API.Entities +{ + public class UserTask + { + public string Arguments { get; set; } + public string Description { get; set; } + public int IconIndex { get; set; } + public string IconPath { get; set; } + public string Program { get; set; } + public string Title { get; set; } + } +} diff --git a/ElectronNET.API/Entities/WebPreferences.cs b/ElectronNET.API/Entities/WebPreferences.cs new file mode 100644 index 0000000..8f4e738 --- /dev/null +++ b/ElectronNET.API/Entities/WebPreferences.cs @@ -0,0 +1,186 @@ +namespace ElectronNET.API.Entities +{ + public class WebPreferences + { + /// + /// Whether to enable DevTools. If it is set to false, can not use + /// BrowserWindow.webContents.openDevTools() to open DevTools.Default is true. + /// + public bool DevTools { get; set; } + + /// + /// Whether node integration is enabled. Default is true. + /// + public bool NodeIntegration { get; set; } + + /// + /// Whether node integration is enabled in web workers. Default is false. + /// + public bool NodeIntegrationInWorker { get; set; } + + /// + /// Specifies a script that will be loaded before other scripts run in the page. + /// This script will always have access to node APIs no matter whether node + /// integration is turned on or off.The value should be the absolute file path to + /// the script. When node integration is turned off, the preload script can + /// reintroduce Node global symbols back to the global scope. + /// + public string Preload { get; set; } + + /// + /// If set, this will sandbox the renderer associated with the window, making it + /// compatible with the Chromium OS-level sandbox and disabling the Node.js engine. + /// This is not the same as the nodeIntegration option and the APIs available to the + /// preload script are more limited. Read more about the option.This option is + /// currently experimental and may change or be removed in future Electron releases. + /// + public bool Sandbox { get; set; } + + /// + /// Sets the session used by the page according to the session's partition string. + /// If partition starts with persist:, the page will use a persistent session + /// available to all pages in the app with the same partition.If there is no + /// persist: prefix, the page will use an in-memory session. By assigning the same + /// partition, multiple pages can share the same session.Default is the default + /// session. + /// + public string Partition { get; set; } + + /// + /// The default zoom factor of the page, 3.0 represents 300%. Default is 1.0. + /// + public int ZoomFactor { get; set; } + + /// + /// Enables JavaScript support. Default is true. + /// + public bool Javascript { get; set; } + + /// + /// When false, it will disable the same-origin policy (usually using testing + /// websites by people), and set allowRunningInsecureContent to true if this options + /// has not been set by user.Default is true. + /// + public bool WebSecurity { get; set; } + + /// + /// Allow an https page to run JavaScript, CSS or plugins from http URLs. Default is + /// false. + /// + public bool AllowRunningInsecureContent { get; set; } + + /// + /// Enables image support. Default is true. + /// + public bool Images { get; set; } + + /// + /// Make TextArea elements resizable. Default is true. + /// + public bool TextAreasAreResizable { get; set; } + + /// + /// Enables WebGL support. Default is true. + /// + public bool Webgl { get; set; } + + /// + /// Enables WebAudio support. Default is true. + /// + public bool Webaudio { get; set; } + + /// + /// Whether plugins should be enabled. Default is false. + /// + public bool Plugins { get; set; } + + /// + /// Enables Chromium's experimental features. Default is false. + /// + public bool ExperimentalFeatures { get; set; } + + /// + /// Enables Chromium's experimental canvas features. Default is false. + /// + public bool ExperimentalCanvasFeatures { get; set; } + + /// + /// Enables scroll bounce (rubber banding) effect on macOS. Default is false. + /// + public bool ScrollBounce { get; set; } + + /// + /// A list of feature strings separated by ,, like CSSVariables,KeyboardEventKey to + /// enable.The full list of supported feature strings can be found in the file. + /// + public string BlinkFeatures { get; set; } + + /// + /// A list of feature strings separated by ,, like CSSVariables,KeyboardEventKey to + /// disable.The full list of supported feature strings can be found in the file. + /// + public string DisableBlinkFeatures { get; set; } + + /// + /// Defaults to 16. + /// + public int DefaultFontSize { get; set; } + + /// + /// Defaults to 13. + /// + public int DefaultMonospaceFontSize { get; set; } + + /// + /// Defaults to 0. + /// + public int MinimumFontSize { get; set; } + + /// + /// Defaults to ISO-8859-1. + /// + public string DefaultEncoding { get; set; } + + /// + /// Whether to throttle animations and timers when the page becomes background. This + /// also affects the[Page Visibility API][#page-visibility]. Defaults to true. + /// + public bool BackgroundThrottling { get; set; } + + /// + /// Whether to enable offscreen rendering for the browser window. Defaults to false. + /// + public bool Offscreen { get; set; } + + /// + /// Whether to run Electron APIs and the specified preload script in a separate + /// JavaScript context.Defaults to false. The context that the preload script runs + /// in will still have full access to the document and window globals but it will + /// use its own set of JavaScript builtins (Array, Object, JSON, etc.) and will be + /// isolated from any changes made to the global environment by the loaded page.The + /// Electron API will only be available in the preload script and not the loaded + /// page. This option should be used when loading potentially untrusted remote + /// content to ensure the loaded content cannot tamper with the preload script and + /// any Electron APIs being used. This option uses the same technique used by . You + /// can access this context in the dev tools by selecting the 'Electron Isolated + /// Context' entry in the combo box at the top of the Console tab. This option is + /// currently experimental and may change or be removed in future Electron releases. + /// + public bool ContextIsolation { get; set; } + + /// + /// Whether to use native window.open(). Defaults to false. This option is currently experimental. + /// + public bool NativeWindowOpen { get; set; } + + /// + /// Whether to enable the . Defaults to the value of the nodeIntegration option. The + /// preload script configured for the will have node integration enabled + /// when it is executed so you should ensure remote/untrusted content is not able to + /// create a tag with a possibly malicious preload script.You can use the + /// will-attach-webview event on to strip away the preload script and to validate or + /// alter the's initial settings. + /// + public bool WebviewTag { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Extensions/MenuItemExtensions.cs b/ElectronNET.API/Extensions/MenuItemExtensions.cs new file mode 100644 index 0000000..ba5f8b5 --- /dev/null +++ b/ElectronNET.API/Extensions/MenuItemExtensions.cs @@ -0,0 +1,53 @@ +using ElectronNET.API.Entities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ElectronNET.API.Extensions +{ + internal static class MenuItemExtensions + { + public static MenuItem[] AddMenuItemsId(this MenuItem[] menuItems) + { + for (int index = 0; index < menuItems.Length; index++) + { + var menuItem = menuItems[index]; + if (menuItem?.Submenu?.Length > 0) + { + AddMenuItemsId(menuItem.Submenu); + } + + if (string.IsNullOrEmpty(menuItem.Role) && + string.IsNullOrEmpty(menuItem.Id)) + { + menuItem.Id = Guid.NewGuid().ToString(); + } + } + + return menuItems; + } + + public static MenuItem GetMenuItem(this List menuItems, string id) + { + MenuItem result = new MenuItem(); + + foreach (var item in menuItems) + { + if (item.Id == id) + { + result = item; + } + else if (item?.Submenu?.Length > 0) + { + var menuItem = GetMenuItem(item.Submenu.ToList(), id); + if (menuItem.Id == id) + { + result = menuItem; + } + } + } + + return result; + } + } +} diff --git a/ElectronNET.API/IpcMain.cs b/ElectronNET.API/IpcMain.cs index db3bdfc..b0f56f9 100644 --- a/ElectronNET.API/IpcMain.cs +++ b/ElectronNET.API/IpcMain.cs @@ -1,20 +1,32 @@ -using System; -using Quobject.SocketIoClientDotNet.Client; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System; namespace ElectronNET.API { - // - // Summary: - // Communicate asynchronously from the main process to renderer processes. - public class IpcMain + /// + /// Communicate asynchronously from the main process to renderer processes. + /// + public sealed class IpcMain { - private Socket _socket; + private static IpcMain _ipcMain; - public IpcMain(Socket socket) + internal IpcMain() { } + + internal static IpcMain Instance { - _socket = socket; + get + { + if(_ipcMain == null) + { + _ipcMain = new IpcMain(); + } + + return _ipcMain; + } } - + /// /// Listens to channel, when a new message arrives listener would be called with /// listener(event, args...). @@ -23,57 +35,50 @@ namespace ElectronNET.API /// Callback Method. public void On(string channel, Action listener) { - _socket.Emit("registerIpcMainChannel", channel); - _socket.On(channel, listener); + BridgeConnector.Socket.Emit("registerIpcMainChannel", channel); + BridgeConnector.Socket.On(channel, listener); } - // 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. - // - // Parameters: - // channel: - // Channelname. - // - // listener: - // Callback Method. - // + /// + /// 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. + /// + /// Channelname. + /// Callback Method. public void Once(string channel, Action listener) { - _socket.Emit("registerOnceIpcMainChannel", channel); - _socket.On(channel, listener); + BridgeConnector.Socket.Emit("registerOnceIpcMainChannel", channel); + BridgeConnector.Socket.On(channel, listener); } - // - // Summary: - // Removes listeners of the specified channel. - // - // Parameters: - // channel: - // Channelname. - // + /// + /// Removes listeners of the specified channel. + /// + /// Channelname. public void RemoveAllListeners(string channel) { - _socket.Emit("removeAllListenersIpcMainChannel", channel); + BridgeConnector.Socket.Emit("removeAllListenersIpcMainChannel", channel); } - // - // Summary: - // Send a message to the renderer process asynchronously via channel, you can also send - // arbitrary arguments. Arguments will be serialized in JSON internally and hence - // no functions or prototype chain will be included. The renderer process handles it by - // listening for channel with ipcRenderer module. - // - // Parameters: - // channel: - // Channelname. - // - // data: - // Arguments data. - // - public void Send(string channel, params object[] data) + /// + /// Send a message to the renderer process asynchronously via channel, you can also send + /// arbitrary arguments. Arguments will be serialized in JSON internally and hence + /// no functions or prototype chain will be included. The renderer process handles it by + /// listening for channel with ipcRenderer module. + /// + /// BrowserWindow with channel. + /// Channelname. + /// Arguments data. + public void Send(BrowserWindow browserWindow, string channel, params object[] data) { - _socket.Emit("sendToIpcRenderer", channel, data); + BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data); } + + 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/Menu.cs b/ElectronNET.API/Menu.cs new file mode 100644 index 0000000..cfd1af5 --- /dev/null +++ b/ElectronNET.API/Menu.cs @@ -0,0 +1,53 @@ +using ElectronNET.API.Entities; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System.Collections.Generic; +using System; +using System.Linq; +using ElectronNET.API.Extensions; + +namespace ElectronNET.API +{ + public sealed class Menu + { + private static Menu _menu; + + internal Menu() { } + + internal static Menu Instance + { + get + { + if (_menu == null) + { + _menu = new Menu(); + } + + return _menu; + } + } + + public IReadOnlyCollection Items { get { return _items.AsReadOnly(); } } + private List _items = new List(); + + public void SetApplicationMenu(MenuItem[] menuItems) + { + menuItems.AddMenuItemsId(); + BridgeConnector.Socket.Emit("menu-setApplicationMenu", JArray.FromObject(menuItems, _jsonSerializer)); + _items.AddRange(menuItems); + + BridgeConnector.Socket.On("menuItemClicked", (id) => { + MenuItem menuItem = _items.GetMenuItem(id.ToString()); + menuItem?.Click(); + }); + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.API/Notification.cs b/ElectronNET.API/Notification.cs new file mode 100644 index 0000000..ad396d0 --- /dev/null +++ b/ElectronNET.API/Notification.cs @@ -0,0 +1,39 @@ +using ElectronNET.API.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace ElectronNET.API +{ + public sealed class Notification + { + private static Notification _notification; + + internal Notification() { } + + internal static Notification Instance + { + get + { + if (_notification == null) + { + _notification = new Notification(); + } + + return _notification; + } + } + + public void Show(NotificationOptions notificationOptions) + { + BridgeConnector.Socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer)); + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.API/Tray.cs b/ElectronNET.API/Tray.cs new file mode 100644 index 0000000..01599d9 --- /dev/null +++ b/ElectronNET.API/Tray.cs @@ -0,0 +1,51 @@ +using ElectronNET.API.Entities; +using ElectronNET.API.Extensions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System.Collections.Generic; + +namespace ElectronNET.API +{ + public sealed class Tray + { + private static Tray _tray; + + internal Tray() { } + + internal static Tray Instance + { + get + { + if (_tray == null) + { + _tray = new Tray(); + } + + return _tray; + } + } + + public IReadOnlyCollection Items { get { return _items.AsReadOnly(); } } + private List _items = new List(); + + public void Show(string image, MenuItem[] menuItems) + { + menuItems.AddMenuItemsId(); + BridgeConnector.Socket.Emit("create-tray", image, JArray.FromObject(menuItems, _jsonSerializer)); + _items.AddRange(menuItems); + + BridgeConnector.Socket.On("trayMenuItemClicked", (id) => { + MenuItem menuItem = _items.GetMenuItem(id.ToString()); + menuItem?.Click(); + }); + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.API/WebHostBuilderExtensions.cs b/ElectronNET.API/WebHostBuilderExtensions.cs index f939a54..0409f6b 100644 --- a/ElectronNET.API/WebHostBuilderExtensions.cs +++ b/ElectronNET.API/WebHostBuilderExtensions.cs @@ -23,6 +23,8 @@ namespace ElectronNET.API { builder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) .UseUrls("http://0.0.0.0:" + BridgeSettings.WebPort); + + BridgeConnector.StartConnection(); } return builder; diff --git a/ElectronNET.API/WindowManager.cs b/ElectronNET.API/WindowManager.cs new file mode 100644 index 0000000..2103041 --- /dev/null +++ b/ElectronNET.API/WindowManager.cs @@ -0,0 +1,69 @@ +using ElectronNET.API.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ElectronNET.API +{ + public sealed class WindowManager + { + private static WindowManager _windowManager; + + internal WindowManager() { } + + internal static WindowManager Instance + { + get + { + if (_windowManager == null) + { + _windowManager = new WindowManager(); + } + + return _windowManager; + } + } + + public IReadOnlyCollection BrowserWindows { get { return _browserWindows.AsReadOnly(); } } + private List _browserWindows = new List(); + + public async Task CreateWindowAsync(string loadUrl = "http://localhost") + { + return await CreateWindowAsync(new BrowserWindowOptions(), loadUrl); + } + + public Task CreateWindowAsync(BrowserWindowOptions options, string loadUrl = "http://localhost") + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("BrowserWindowCreated", (id) => + { + BridgeConnector.Socket.Off("BrowserWindowCreated"); + + string windowId = id.ToString(); + BrowserWindow browserWindow = new BrowserWindow(int.Parse(windowId)); + _browserWindows.Add(browserWindow); + + taskCompletionSource.SetResult(browserWindow); + }); + + if (loadUrl.ToUpper() == "HTTP://LOCALHOST") + { + loadUrl = $"{loadUrl}:{BridgeSettings.WebPort}"; + } + + BridgeConnector.Socket.Emit("createBrowserWindow", JObject.FromObject(options, _jsonSerializer), loadUrl); + + return taskCompletionSource.Task; + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; + } +} diff --git a/ElectronNET.CLI/Commands/BuildCommand.cs b/ElectronNET.CLI/Commands/BuildCommand.cs index 329a1a3..682e07a 100644 --- a/ElectronNET.CLI/Commands/BuildCommand.cs +++ b/ElectronNET.CLI/Commands/BuildCommand.cs @@ -60,7 +60,13 @@ namespace ElectronNET.CLI.Commands { Directory.CreateDirectory(hostApiFolder); } - EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "ElectronHost.api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "tray.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 541d832..1bf7231 100644 --- a/ElectronNET.CLI/Commands/StartElectronCommand.cs +++ b/ElectronNET.CLI/Commands/StartElectronCommand.cs @@ -58,7 +58,13 @@ namespace ElectronNET.CLI.Commands { Directory.CreateDirectory(hostApiFolder); } - EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "ElectronHost.api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "tray.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 1078d20..ed3a5a0 100644 --- a/ElectronNET.CLI/ElectronNET.CLI.csproj +++ b/ElectronNET.CLI/ElectronNET.CLI.csproj @@ -36,6 +36,17 @@ + + + + + + + + + + + diff --git a/ElectronNET.Host/api/app.js b/ElectronNET.Host/api/app.js new file mode 100644 index 0000000..94ea0d5 --- /dev/null +++ b/ElectronNET.Host/api/app.js @@ -0,0 +1,248 @@ +"use strict"; +exports.__esModule = true; +module.exports = function (socket, app) { + socket.on('register-app-window-all-closed-event', function () { + app.on('window-all-closed', function () { + socket.emit('app-window-all-closed'); + }); + }); + socket.on('register-app-before-quit-event', function () { + app.on('before-quit', function () { + socket.emit('app-before-quit'); + }); + }); + socket.on('register-app-will-quit-event', function () { + app.on('will-quit', function () { + socket.emit('app-will-quit'); + }); + }); + socket.on('register-app-quit-event', function () { + app.on('quit', function () { + socket.emit('app-quit'); + }); + }); + socket.on('register-app-browser-window-blur-event', function () { + app.on('browser-window-blur', function () { + socket.emit('app-browser-window-blur'); + }); + }); + socket.on('register-app-browser-window-focus-event', function () { + app.on('browser-window-focus', function () { + socket.emit('app-browser-window-focus'); + }); + }); + socket.on('register-app-browser-window-created-event', function () { + app.on('browser-window-created', function () { + socket.emit('app-browser-window-created'); + }); + }); + socket.on('register-app-web-contents-created-event', function () { + app.on('web-contents-created', function () { + socket.emit('app-web-contents-created'); + }); + }); + socket.on('register-app-accessibility-support-changed-event', function () { + app.on('accessibility-support-changed', function (event, accessibilitySupportEnabled) { + socket.emit('app-accessibility-support-changed', accessibilitySupportEnabled); + }); + }); + socket.on('appQuit', function () { + app.quit(); + }); + socket.on('appExit', function (exitCode) { + if (exitCode === void 0) { exitCode = 0; } + app.exit(exitCode); + }); + socket.on('appRelaunch', function (options) { + app.relaunch(options); + }); + socket.on('appFocus', function () { + app.focus(); + }); + socket.on('appHide', function () { + app.hide(); + }); + socket.on('appShow', function () { + app.show(); + }); + socket.on('appGetAppPath', function () { + var path = app.getAppPath(); + socket.emit('appGetAppPathCompleted', path); + }); + socket.on('appGetPath', function (name) { + var path = app.getPath(name); + socket.emit('appGetPathCompleted', path); + }); + // const nativeImages = {}; + // function addNativeImage(nativeImage: Electron.NativeImage) { + // if(Object.keys(nativeImages).length === 0) { + // nativeImage['1'] = nativeImage; + // } else { + // let indexCount = Object.keys(nativeImages).length + 1; + // nativeImage[indexCount] = nativeImage; + // } + // } + socket.on('appGetFileIcon', function (path, options) { + if (options) { + app.getFileIcon(path, options, function (error, nativeImage) { + socket.emit('appGetFileIconCompleted', [error, nativeImage]); + }); + } + else { + app.getFileIcon(path, function (error, nativeImage) { + socket.emit('appGetFileIconCompleted', [error, nativeImage]); + }); + } + }); + socket.on('appSetPath', function (name, path) { + app.setPath(name, path); + }); + socket.on('appGetVersion', function () { + var version = app.getVersion(); + socket.emit('appGetVersionCompleted', version); + }); + socket.on('appGetName', function () { + var name = app.getName(); + socket.emit('appGetNameCompleted', name); + }); + socket.on('appSetName', function (name) { + app.setName(name); + }); + socket.on('appGetLocale', function () { + var locale = app.getLocale(); + socket.emit('appGetLocaleCompleted', locale); + }); + socket.on('appAddRecentDocument', function (path) { + app.addRecentDocument(path); + }); + socket.on('appClearRecentDocuments', function () { + app.clearRecentDocuments(); + }); + socket.on('appSetAsDefaultProtocolClient', function (protocol, path, args) { + var success = app.setAsDefaultProtocolClient(protocol, path, args); + socket.emit('appSetAsDefaultProtocolClientCompleted', success); + }); + socket.on('appRemoveAsDefaultProtocolClient', function (protocol, path, args) { + var success = app.removeAsDefaultProtocolClient(protocol, path, args); + socket.emit('appRemoveAsDefaultProtocolClientCompleted', success); + }); + socket.on('appIsDefaultProtocolClient', function (protocol, path, args) { + var success = app.isDefaultProtocolClient(protocol, path, args); + socket.emit('appIsDefaultProtocolClientCompleted', success); + }); + socket.on('appSetUserTasks', function (tasks) { + var success = app.setUserTasks(tasks); + socket.emit('appSetUserTasksCompleted', success); + }); + socket.on('appGetJumpListSettings', function () { + var jumpListSettings = app.getJumpListSettings(); + socket.emit('appGetJumpListSettingsCompleted', jumpListSettings); + }); + socket.on('appSetJumpList', function (categories) { + app.setJumpList(categories); + }); + socket.on('appMakeSingleInstance', function () { + var success = app.makeSingleInstance(function (args, workingDirectory) { + socket.emit('newInstanceOpened', [args, workingDirectory]); + }); + socket.emit('appMakeSingleInstanceCompleted', success); + }); + socket.on('appReleaseSingleInstance', function () { + app.releaseSingleInstance(); + }); + socket.on('appSetUserActivity', function (type, userInfo, webpageURL) { + app.setUserActivity(type, userInfo, webpageURL); + }); + socket.on('appGetCurrentActivityType', function () { + var activityType = app.getCurrentActivityType(); + socket.emit('appGetCurrentActivityTypeCompleted', activityType); + }); + socket.on('appSetAppUserModelId', function (id) { + app.setAppUserModelId(id); + }); + socket.on('appImportCertificate', function (options) { + app.importCertificate(options, function (result) { + socket.emit('appImportCertificateCompleted', result); + }); + }); + socket.on('appGetAppMetrics', function () { + var processMetrics = app.getAppMetrics(); + socket.emit('appGetAppMetricsCompleted', processMetrics); + }); + socket.on('appGetGpuFeatureStatus', function () { + // TS Workaround - TS say getGpuFeatureStatus - but it is getGPUFeatureStatus + var x = app; + var gpuFeatureStatus = x.getGPUFeatureStatus(); + socket.emit('appGetGpuFeatureStatusCompleted', gpuFeatureStatus); + }); + socket.on('appSetBadgeCount', function (count) { + var success = app.setBadgeCount(count); + socket.emit('appSetBadgeCountCompleted', success); + }); + socket.on('appGetBadgeCount', function () { + var count = app.getBadgeCount(); + socket.emit('appGetBadgeCountCompleted', count); + }); + socket.on('appIsUnityRunning', function () { + var isUnityRunning = app.isUnityRunning(); + socket.emit('appIsUnityRunningCompleted', isUnityRunning); + }); + socket.on('appGetLoginItemSettings', function (options) { + var loginItemSettings = app.getLoginItemSettings(options); + socket.emit('appGetLoginItemSettingsCompleted', loginItemSettings); + }); + socket.on('appSetLoginItemSettings', function (settings) { + app.setLoginItemSettings(settings); + }); + socket.on('appIsAccessibilitySupportEnabled', function () { + var isAccessibilitySupportEnabled = app.isAccessibilitySupportEnabled(); + socket.emit('appIsAccessibilitySupportEnabledCompleted', isAccessibilitySupportEnabled); + }); + socket.on('appSetAboutPanelOptions', function (options) { + app.setAboutPanelOptions(options); + }); + socket.on('appCommandLineAppendSwitch', function (theSwitch, value) { + app.commandLine.appendSwitch(theSwitch, value); + }); + socket.on('appCommandLineAppendArgument', function (value) { + app.commandLine.appendArgument(value); + }); + socket.on('appEnableMixedSandbox', function () { + app.enableMixedSandbox(); + }); + socket.on('appDockBounce', function (type) { + var id = app.dock.bounce(type); + socket.emit('appDockBounceCompleted', id); + }); + socket.on('appDockCancelBounce', function (id) { + app.dock.cancelBounce(id); + }); + socket.on('appDockDownloadFinished', function (filePath) { + app.dock.downloadFinished(filePath); + }); + socket.on('appDockSetBadge', function (text) { + app.dock.setBadge(text); + }); + socket.on('appDockGetBadge', function () { + var text = app.dock.getBadge(); + socket.emit('appDockGetBadgeCompleted', text); + }); + socket.on('appDockHide', function () { + app.dock.hide(); + }); + socket.on('appDockShow', function () { + app.dock.show(); + }); + socket.on('appDockIsVisible', function () { + var isVisible = app.dock.isVisible(); + socket.emit('appDockIsVisibleCompleted', isVisible); + }); + // TODO: Menü Lösung muss noch implementiert werden + socket.on('appDockSetMenu', function (menu) { + app.dock.setMenu(menu); + }); + socket.on('appDockSetIcon', function (image) { + app.dock.setIcon(image); + }); +}; +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/app.js.map b/ElectronNET.Host/api/app.js.map new file mode 100644 index 0000000..103379b --- /dev/null +++ b/ElectronNET.Host/api/app.js.map @@ -0,0 +1 @@ +{"version":3,"file":"app.js","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/ElectronNET.Host/api/app.ts b/ElectronNET.Host/api/app.ts new file mode 100644 index 0000000..99fd2b6 --- /dev/null +++ b/ElectronNET.Host/api/app.ts @@ -0,0 +1,307 @@ +import { nativeImage as NativeImage } from 'electron'; + +module.exports = (socket: SocketIO.Server, app: Electron.App) => { + + socket.on('register-app-window-all-closed-event', () => { + app.on('window-all-closed', () => { + socket.emit('app-window-all-closed'); + }); + }); + + socket.on('register-app-before-quit-event', () => { + app.on('before-quit', () => { + socket.emit('app-before-quit'); + }); + }); + + socket.on('register-app-will-quit-event', () => { + app.on('will-quit', () => { + socket.emit('app-will-quit'); + }); + }); + + socket.on('register-app-quit-event', () => { + app.on('quit', () => { + socket.emit('app-quit'); + }); + }); + + socket.on('register-app-browser-window-blur-event', () => { + app.on('browser-window-blur', () => { + socket.emit('app-browser-window-blur'); + }); + }); + + socket.on('register-app-browser-window-focus-event', () => { + app.on('browser-window-focus', () => { + socket.emit('app-browser-window-focus'); + }); + }); + + socket.on('register-app-browser-window-created-event', () => { + app.on('browser-window-created', () => { + socket.emit('app-browser-window-created'); + }); + }); + + socket.on('register-app-web-contents-created-event', () => { + app.on('web-contents-created', () => { + socket.emit('app-web-contents-created'); + }); + }); + + socket.on('register-app-accessibility-support-changed-event', () => { + app.on('accessibility-support-changed', (event, accessibilitySupportEnabled) => { + socket.emit('app-accessibility-support-changed', accessibilitySupportEnabled); + }); + }); + + socket.on('appQuit', () => { + app.quit(); + }); + + socket.on('appExit', (exitCode = 0) => { + app.exit(exitCode); + }); + + socket.on('appRelaunch', (options) => { + app.relaunch(options); + }); + + socket.on('appFocus', () => { + app.focus(); + }); + + socket.on('appHide', () => { + app.hide(); + }); + + socket.on('appShow', () => { + app.show(); + }); + + socket.on('appGetAppPath', () => { + const path = app.getAppPath(); + socket.emit('appGetAppPathCompleted', path); + }); + + socket.on('appGetPath', (name) => { + const path = app.getPath(name); + socket.emit('appGetPathCompleted', path); + }); + + // const nativeImages = {}; + + // function addNativeImage(nativeImage: Electron.NativeImage) { + + // if(Object.keys(nativeImages).length === 0) { + // nativeImage['1'] = nativeImage; + // } else { + // let indexCount = Object.keys(nativeImages).length + 1; + // nativeImage[indexCount] = nativeImage; + // } + // } + + socket.on('appGetFileIcon', (path, options) => { + if(options) { + app.getFileIcon(path, options, (error, nativeImage) => { + socket.emit('appGetFileIconCompleted', [error, nativeImage]); + }); + } else { + app.getFileIcon(path, (error, nativeImage) => { + socket.emit('appGetFileIconCompleted', [error, nativeImage]); + }); + } + }); + + socket.on('appSetPath', (name, path) => { + app.setPath(name, path); + }); + + socket.on('appGetVersion', () => { + const version = app.getVersion(); + socket.emit('appGetVersionCompleted', version); + }); + + socket.on('appGetName', () => { + const name = app.getName(); + socket.emit('appGetNameCompleted', name); + }); + + socket.on('appSetName', (name) => { + app.setName(name); + }); + + socket.on('appGetLocale', () => { + const locale = app.getLocale(); + socket.emit('appGetLocaleCompleted', locale); + }); + + socket.on('appAddRecentDocument', (path) => { + app.addRecentDocument(path); + }); + + socket.on('appClearRecentDocuments', () => { + app.clearRecentDocuments(); + }); + + socket.on('appSetAsDefaultProtocolClient', (protocol, path, args) => { + const success = app.setAsDefaultProtocolClient(protocol, path, args); + socket.emit('appSetAsDefaultProtocolClientCompleted', success); + }); + + socket.on('appRemoveAsDefaultProtocolClient', (protocol, path, args) => { + const success = app.removeAsDefaultProtocolClient(protocol, path, args); + socket.emit('appRemoveAsDefaultProtocolClientCompleted', success); + }); + + socket.on('appIsDefaultProtocolClient', (protocol, path, args) => { + const success = app.isDefaultProtocolClient(protocol, path, args); + socket.emit('appIsDefaultProtocolClientCompleted', success); + }); + + socket.on('appSetUserTasks', (tasks) => { + const success = app.setUserTasks(tasks); + socket.emit('appSetUserTasksCompleted', success); + }); + + socket.on('appGetJumpListSettings', () => { + const jumpListSettings = app.getJumpListSettings(); + socket.emit('appGetJumpListSettingsCompleted', jumpListSettings); + }); + + socket.on('appSetJumpList', (categories) => { + app.setJumpList(categories); + }); + + socket.on('appMakeSingleInstance', () => { + const success = app.makeSingleInstance((args, workingDirectory) => { + socket.emit('newInstanceOpened', [args, workingDirectory]); + }); + socket.emit('appMakeSingleInstanceCompleted', success); + }); + + socket.on('appReleaseSingleInstance', () => { + app.releaseSingleInstance(); + }); + + socket.on('appSetUserActivity', (type, userInfo, webpageURL) => { + app.setUserActivity(type, userInfo, webpageURL); + }); + + socket.on('appGetCurrentActivityType', () => { + const activityType = app.getCurrentActivityType(); + socket.emit('appGetCurrentActivityTypeCompleted', activityType); + }); + + socket.on('appSetAppUserModelId', (id) => { + app.setAppUserModelId(id); + }); + + socket.on('appImportCertificate', (options) => { + app.importCertificate(options, (result) => { + socket.emit('appImportCertificateCompleted', result); + }); + }); + + socket.on('appGetAppMetrics', () => { + const processMetrics = app.getAppMetrics(); + socket.emit('appGetAppMetricsCompleted', processMetrics); + }); + + socket.on('appGetGpuFeatureStatus', () => { + // TS Workaround - TS say getGpuFeatureStatus - but it is getGPUFeatureStatus + let x = app; + const gpuFeatureStatus = x.getGPUFeatureStatus(); + socket.emit('appGetGpuFeatureStatusCompleted', gpuFeatureStatus); + }); + + socket.on('appSetBadgeCount', (count) => { + const success = app.setBadgeCount(count); + socket.emit('appSetBadgeCountCompleted', success); + }); + + socket.on('appGetBadgeCount', () => { + const count = app.getBadgeCount(); + socket.emit('appGetBadgeCountCompleted', count); + }); + + socket.on('appIsUnityRunning', () => { + const isUnityRunning = app.isUnityRunning(); + socket.emit('appIsUnityRunningCompleted', isUnityRunning); + }); + + socket.on('appGetLoginItemSettings', (options) => { + const loginItemSettings = app.getLoginItemSettings(options); + socket.emit('appGetLoginItemSettingsCompleted', loginItemSettings); + }); + + socket.on('appSetLoginItemSettings', (settings) => { + app.setLoginItemSettings(settings); + }); + + socket.on('appIsAccessibilitySupportEnabled', () => { + const isAccessibilitySupportEnabled = app.isAccessibilitySupportEnabled(); + socket.emit('appIsAccessibilitySupportEnabledCompleted', isAccessibilitySupportEnabled); + }); + + socket.on('appSetAboutPanelOptions', (options) => { + app.setAboutPanelOptions(options); + }); + + socket.on('appCommandLineAppendSwitch', (theSwitch, value) => { + app.commandLine.appendSwitch(theSwitch, value); + }); + + socket.on('appCommandLineAppendArgument', (value) => { + app.commandLine.appendArgument(value); + }); + + socket.on('appEnableMixedSandbox', () => { + app.enableMixedSandbox(); + }); + + socket.on('appDockBounce', (type) => { + const id = app.dock.bounce(type); + socket.emit('appDockBounceCompleted', id); + }); + + socket.on('appDockCancelBounce', (id) => { + app.dock.cancelBounce(id); + }); + + socket.on('appDockDownloadFinished', (filePath) => { + app.dock.downloadFinished(filePath); + }); + + socket.on('appDockSetBadge', (text) => { + app.dock.setBadge(text); + }); + + socket.on('appDockGetBadge', () => { + const text = app.dock.getBadge(); + socket.emit('appDockGetBadgeCompleted', text); + }); + + socket.on('appDockHide', () => { + app.dock.hide(); + }); + + socket.on('appDockShow', () => { + app.dock.show(); + }); + + socket.on('appDockIsVisible', () => { + const isVisible = app.dock.isVisible(); + socket.emit('appDockIsVisibleCompleted', isVisible); + }); + + // TODO: Menü Lösung muss noch implementiert werden + socket.on('appDockSetMenu', (menu) => { + app.dock.setMenu(menu); + }); + + socket.on('appDockSetIcon', (image) => { + app.dock.setIcon(image); + }); +} \ No newline at end of file diff --git a/ElectronNET.Host/api/browserWindows.js b/ElectronNET.Host/api/browserWindows.js new file mode 100644 index 0000000..9ff87d5 --- /dev/null +++ b/ElectronNET.Host/api/browserWindows.js @@ -0,0 +1,100 @@ +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +var windows = []; +module.exports = function (socket) { + socket.on('createBrowserWindow', function (options, loadUrl) { + var window = new electron_1.BrowserWindow(options); + window.on('closed', function (sender) { + for (var index = 0; index < windows.length; index++) { + var windowItem = windows[index]; + try { + windowItem.id; + } + catch (error) { + if (error.message === 'Object has been destroyed') { + windows.splice(index, 1); + } + } + } + }); + if (loadUrl) { + window.loadURL(loadUrl); + } + windows.push(window); + socket.emit('BrowserWindowCreated', window.id); + }); + socket.on('browserWindow-destroy', function (id) { + getWindowById(id).destroy(); + }); + socket.on('browserWindow-close', function (id) { + getWindowById(id).close(); + }); + socket.on('browserWindow-focus', function (id) { + getWindowById(id).focus(); + }); + socket.on('browserWindow-blur', function (id) { + getWindowById(id).blur(); + }); + socket.on('browserWindow-isFocused', function (id) { + var isFocused = getWindowById(id).isFocused(); + socket.emit('browserWindow-isFocused-completed', isFocused); + }); + socket.on('browserWindow-isDestroyed', function (id) { + var isDestroyed = getWindowById(id).isDestroyed(); + socket.emit('browserWindow-isDestroyed-completed', isDestroyed); + }); + socket.on('browserWindow-show', function (id) { + getWindowById(id).show(); + }); + socket.on('browserWindow-showInactive', function (id) { + getWindowById(id).showInactive(); + }); + socket.on('browserWindow-hide', function (id) { + getWindowById(id).hide(); + }); + socket.on('browserWindow-isVisible', function (id) { + var isVisible = getWindowById(id).isVisible(); + socket.emit('browserWindow-isVisible-completed', isVisible); + }); + socket.on('browserWindow-isModal', function (id) { + var isModal = getWindowById(id).isModal(); + socket.emit('browserWindow-isModal-completed', isModal); + }); + socket.on('browserWindow-maximize', function (id) { + getWindowById(id).maximize(); + }); + socket.on('browserWindow-unmaximize', function (id) { + getWindowById(id).unmaximize(); + }); + socket.on('browserWindow-isMaximized', function (id) { + var isMaximized = getWindowById(id).isMaximized(); + socket.emit('browserWindow-isMaximized-completed', isMaximized); + }); + socket.on('browserWindow-minimize', function (id) { + getWindowById(id).minimize(); + }); + socket.on('browserWindow-restore', function (id) { + getWindowById(id).restore(); + }); + socket.on('browserWindow-isMinimized', function (id) { + var isMinimized = getWindowById(id).isMinimized(); + socket.emit('browserWindow-isMinimized-completed', isMinimized); + }); + socket.on('browserWindow-setFullScreen', function (id, fullscreen) { + getWindowById(id).setFullScreen(fullscreen); + }); + socket.on('browserWindow-isFullScreen', function (id) { + var isFullScreen = getWindowById(id).isFullScreen(); + socket.emit('browserWindow-isFullScreen-completed', isFullScreen); + }); + function getWindowById(id) { + for (var index = 0; index < windows.length; index++) { + var element = windows[index]; + if (element.id == id) { + return element; + } + } + } +}; +//# sourceMappingURL=browserWindows.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/browserWindows.js.map b/ElectronNET.Host/api/browserWindows.js.map new file mode 100644 index 0000000..b819a5b --- /dev/null +++ b/ElectronNET.Host/api/browserWindows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"browserWindows.js","sourceRoot":"","sources":["browserWindows.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/ElectronNET.Host/api/browserWindows.ts b/ElectronNET.Host/api/browserWindows.ts new file mode 100644 index 0000000..0614241 --- /dev/null +++ b/ElectronNET.Host/api/browserWindows.ts @@ -0,0 +1,233 @@ +import { BrowserWindow } from "electron"; +const windows: Electron.BrowserWindow[] = [] + +module.exports = (socket: SocketIO.Server) => { + socket.on('createBrowserWindow', (options, loadUrl) => { + let window = new BrowserWindow(options); + + window.on('closed', (sender) => { + for (var index = 0; index < windows.length; index++) { + var windowItem = windows[index]; + try { + windowItem.id; + } catch (error) { + if (error.message === 'Object has been destroyed') { + windows.splice(index, 1); + } + } + } + }); + + if (loadUrl) { + window.loadURL(loadUrl); + } + + windows.push(window); + socket.emit('BrowserWindowCreated', window.id); + }); + + socket.on('browserWindow-destroy', (id) => { + getWindowById(id).destroy(); + }); + + socket.on('browserWindow-close', (id) => { + getWindowById(id).close(); + }); + + socket.on('browserWindow-focus', (id) => { + getWindowById(id).focus(); + }); + + socket.on('browserWindow-blur', (id) => { + getWindowById(id).blur(); + }); + + socket.on('browserWindow-isFocused', (id) => { + const isFocused = getWindowById(id).isFocused(); + + socket.emit('browserWindow-isFocused-completed', isFocused); + }); + + socket.on('browserWindow-isDestroyed', (id) => { + const isDestroyed = getWindowById(id).isDestroyed(); + + socket.emit('browserWindow-isDestroyed-completed', isDestroyed); + }); + + socket.on('browserWindow-show', (id) => { + getWindowById(id).show(); + }); + + socket.on('browserWindow-showInactive', (id) => { + getWindowById(id).showInactive(); + }); + + socket.on('browserWindow-hide', (id) => { + getWindowById(id).hide(); + }); + + socket.on('browserWindow-isVisible', (id) => { + const isVisible = getWindowById(id).isVisible(); + + socket.emit('browserWindow-isVisible-completed', isVisible); + }); + + socket.on('browserWindow-isModal', (id) => { + const isModal = getWindowById(id).isModal(); + + socket.emit('browserWindow-isModal-completed', isModal); + }); + + socket.on('browserWindow-maximize', (id) => { + getWindowById(id).maximize(); + }); + + socket.on('browserWindow-unmaximize', (id) => { + getWindowById(id).unmaximize(); + }); + + socket.on('browserWindow-isMaximized', (id) => { + const isMaximized = getWindowById(id).isMaximized(); + + socket.emit('browserWindow-isMaximized-completed', isMaximized); + }); + + socket.on('browserWindow-minimize', (id) => { + getWindowById(id).minimize(); + }); + + socket.on('browserWindow-restore', (id) => { + getWindowById(id).restore(); + }); + + socket.on('browserWindow-isMinimized', (id) => { + const isMinimized = getWindowById(id).isMinimized(); + + socket.emit('browserWindow-isMinimized-completed', isMinimized); + }); + + socket.on('browserWindow-setFullScreen', (id, fullscreen) => { + getWindowById(id).setFullScreen(fullscreen); + }); + + socket.on('browserWindow-isFullScreen', (id) => { + const isFullScreen = getWindowById(id).isFullScreen(); + + socket.emit('browserWindow-isFullScreen-completed', isFullScreen); + }); + + socket.on('browserWindow-setAspectRatio', (id, aspectRatio, extraSize) => { + getWindowById(id).setAspectRatio(aspectRatio, extraSize); + }); + + socket.on('browserWindow-previewFile', (id, path, displayname) => { + getWindowById(id).previewFile(path, displayname); + }); + + socket.on('browserWindow-closeFilePreview', (id) => { + getWindowById(id).closeFilePreview(); + }); + + socket.on('browserWindow-setBounds', (id, bounds, animate) => { + getWindowById(id).setBounds(bounds, animate); + }); + + socket.on('browserWindow-getBounds', (id) => { + const rectangle = getWindowById(id).getBounds(); + + socket.emit('browserWindow-getBounds-completed', rectangle); + }); + + socket.on('browserWindow-setContentBounds', (id, bounds, animate) => { + getWindowById(id).setContentBounds(bounds, animate); + }); + + socket.on('browserWindow-getContentBounds', (id) => { + const rectangle = getWindowById(id).getContentBounds(); + + socket.emit('browserWindow-getContentBounds-completed', rectangle); + }); + + socket.on('browserWindow-setSize', (id, width, height, animate) => { + getWindowById(id).setSize(width, height, animate); + }); + + socket.on('browserWindow-getSize', (id) => { + const size = getWindowById(id).getSize(); + + socket.emit('browserWindow-getSize-completed', size); + }); + + socket.on('browserWindow-setContentSize', (id, width, height, animate) => { + getWindowById(id).setContentSize(width, height, animate); + }); + + socket.on('browserWindow-getContentSize', (id) => { + const size = getWindowById(id).getContentSize(); + + socket.emit('browserWindow-getContentSize-completed', size); + }); + + socket.on('browserWindow-setMinimumSize', (id, width, height) => { + getWindowById(id).setMinimumSize(width, height); + }); + + socket.on('browserWindow-getMinimumSize', (id) => { + const size = getWindowById(id).getMinimumSize(); + + socket.emit('browserWindow-getMinimumSize-completed', size); + }); + + socket.on('browserWindow-setMaximumSize', (id, width, height) => { + getWindowById(id).setMaximumSize(width, height); + }); + + socket.on('browserWindow-getMaximumSize', (id) => { + const size = getWindowById(id).getMaximumSize(); + + socket.emit('browserWindow-getMaximumSize-completed', size); + }); + + socket.on('browserWindow-setResizable', (id, resizable) => { + getWindowById(id).setResizable(resizable); + }); + + socket.on('browserWindow-isResizable', (id) => { + const resizable = getWindowById(id).isResizable(); + + socket.emit('browserWindow-isResizable-completed', resizable); + }); + + socket.on('browserWindow-setMovable', (id, movable) => { + getWindowById(id).setMovable(movable); + }); + + socket.on('browserWindow-isMovable', (id) => { + const movable = getWindowById(id).isMovable(); + + socket.emit('browserWindow-isMovable-completed', movable); + }); + + socket.on('browserWindow-setMinimizable', (id, minimizable) => { + getWindowById(id).setMinimizable(minimizable); + }); + + socket.on('browserWindow-isMinimizable', (id) => { + const minimizable = getWindowById(id).isMinimizable(); + + socket.emit('browserWindow-isMinimizable-completed', minimizable); + }); + + socket.on('browserWindow-setMaximizable', (id, maximizable) => { + getWindowById(id).setMaximizable(maximizable); + }); + + function getWindowById(id: number): Electron.BrowserWindow { + for (var index = 0; index < windows.length; index++) { + var element = windows[index]; + if (element.id == id) { + return element; + } + } + } +} \ No newline at end of file diff --git a/ElectronNET.Host/api/dialog.js b/ElectronNET.Host/api/dialog.js new file mode 100644 index 0000000..7d0a88a --- /dev/null +++ b/ElectronNET.Host/api/dialog.js @@ -0,0 +1,19 @@ +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +module.exports = function (socket) { + socket.on('showMessageBox', function (browserWindow, options) { + if ("id" in browserWindow) { + var window = electron_1.BrowserWindow.fromId(browserWindow.id); + electron_1.dialog.showMessageBox(window, options, function (response, checkboxChecked) { + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); + }); + } + else { + electron_1.dialog.showMessageBox(browserWindow, function (response, checkboxChecked) { + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); + }); + } + }); +}; +//# sourceMappingURL=dialog.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/dialog.js.map b/ElectronNET.Host/api/dialog.js.map new file mode 100644 index 0000000..672e716 --- /dev/null +++ b/ElectronNET.Host/api/dialog.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAA,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACvB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/dialog.ts b/ElectronNET.Host/api/dialog.ts new file mode 100644 index 0000000..24a03c2 --- /dev/null +++ b/ElectronNET.Host/api/dialog.ts @@ -0,0 +1,17 @@ +import { BrowserWindow, dialog } from "electron"; + +module.exports = (socket: SocketIO.Server) => { + socket.on('showMessageBox', (browserWindow, options) => { + if("id" in browserWindow) { + var window = BrowserWindow.fromId(browserWindow.id); + + dialog.showMessageBox(window, options, (response, checkboxChecked) => { + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); + }); + } else { + dialog.showMessageBox(browserWindow, (response, checkboxChecked) => { + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); + }); + } + }); +} \ No newline at end of file diff --git a/ElectronNET.Host/api/ipc.js b/ElectronNET.Host/api/ipc.js index 80535a6..81d465d 100644 --- a/ElectronNET.Host/api/ipc.js +++ b/ElectronNET.Host/api/ipc.js @@ -1,23 +1,26 @@ -var ipcMain = require('electron').ipcMain; -module.exports = function (socket, window) { +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +module.exports = function (socket) { socket.on('registerIpcMainChannel', function (channel) { - ipcMain.on(channel, function (event, args) { + electron_1.ipcMain.on(channel, function (event, args) { socket.emit(channel, [event.preventDefault(), args]); }); }); socket.on('registerOnceIpcMainChannel', function (channel) { - ipcMain.once(channel, function (event, args) { + electron_1.ipcMain.once(channel, function (event, args) { socket.emit(channel, [event.preventDefault(), args]); }); }); socket.on('removeAllListenersIpcMainChannel', function (channel) { - ipcMain.removeAllListeners(channel); + electron_1.ipcMain.removeAllListeners(channel); }); - socket.on('sendToIpcRenderer', function (channel) { + socket.on('sendToIpcRenderer', function (browserWindow, channel) { var data = []; - for (var _i = 1; _i < arguments.length; _i++) { - data[_i - 1] = arguments[_i]; + for (var _i = 2; _i < arguments.length; _i++) { + data[_i - 2] = arguments[_i]; } + var window = electron_1.BrowserWindow.fromId(browserWindow.id); if (window) { window.webContents.send(channel, data); } diff --git a/ElectronNET.Host/api/ipc.js.map b/ElectronNET.Host/api/ipc.js.map index 36547f4..dea2f4c 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":"AAAQ,IAAA,qCAAO,CAAyB;AAExC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB,EAAE,MAAM;IAC7C,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,OAAO;QACxC,OAAO,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,OAAO,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,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,OAAO;QAAE,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,6BAAO;;QAC5C,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,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 diff --git a/ElectronNET.Host/api/ipc.ts b/ElectronNET.Host/api/ipc.ts index 7f65581..b3a7b2b 100644 --- a/ElectronNET.Host/api/ipc.ts +++ b/ElectronNET.Host/api/ipc.ts @@ -1,6 +1,6 @@ -const { ipcMain } = require('electron'); +import { ipcMain, BrowserWindow } from 'electron'; -module.exports = (socket: SocketIO.Server, window) => { +module.exports = (socket: SocketIO.Server) => { socket.on('registerIpcMainChannel', (channel) => { ipcMain.on(channel, (event, args) => { socket.emit(channel, [event.preventDefault(), args]); @@ -17,7 +17,9 @@ module.exports = (socket: SocketIO.Server, window) => { ipcMain.removeAllListeners(channel); }); - socket.on('sendToIpcRenderer', (channel, ...data) => { + socket.on('sendToIpcRenderer', (browserWindow, channel, ...data) => { + const window = BrowserWindow.fromId(browserWindow.id); + if (window) { window.webContents.send(channel, data); } diff --git a/ElectronNET.Host/api/menu.js b/ElectronNET.Host/api/menu.js new file mode 100644 index 0000000..4eb7eb3 --- /dev/null +++ b/ElectronNET.Host/api/menu.js @@ -0,0 +1,23 @@ +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +module.exports = function (socket) { + socket.on('menu-setApplicationMenu', function (menuItems) { + var menu = electron_1.Menu.buildFromTemplate(menuItems); + addMenuItemClickConnector(menu.items, function (id) { + socket.emit("menuItemClicked", id); + }); + electron_1.Menu.setApplicationMenu(menu); + }); + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach(function (item) { + if (item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + if ("id" in item && item.id) { + item.click = function () { callback(item.id); }; + } + }); + } +}; +//# sourceMappingURL=menu.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/menu.js.map b/ElectronNET.Host/api/menu.js.map new file mode 100644 index 0000000..94adcce --- /dev/null +++ b/ElectronNET.Host/api/menu.js.map @@ -0,0 +1 @@ +{"version":3,"file":"menu.js","sourceRoot":"","sources":["menu.ts"],"names":[],"mappings":";;AAAA,qCAAgC;AAEhC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAC,SAAS;QAC3C,IAAM,IAAI,GAAG,eAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/C,yBAAyB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAC,EAAE;YACrC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,eAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,mCAAmC,SAAS,EAAE,QAAQ;QAClD,SAAS,CAAC,OAAO,CAAC,UAAC,IAAI;YACnB,EAAE,CAAA,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/C,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5D,CAAC;YAED,EAAE,CAAA,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,cAAQ,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/menu.ts b/ElectronNET.Host/api/menu.ts new file mode 100644 index 0000000..1d96344 --- /dev/null +++ b/ElectronNET.Host/api/menu.ts @@ -0,0 +1,25 @@ +import { Menu } from "electron"; + +module.exports = (socket: SocketIO.Server) => { + socket.on('menu-setApplicationMenu', (menuItems) => { + const menu = Menu.buildFromTemplate(menuItems); + + addMenuItemClickConnector(menu.items, (id) => { + socket.emit("menuItemClicked", id); + }); + + Menu.setApplicationMenu(menu); + }); + + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach((item) => { + if(item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + + if("id" in item && item.id) { + item.click = () => { callback(item.id); }; + } + }); + } +} \ No newline at end of file diff --git a/ElectronNET.Host/api/notification.js b/ElectronNET.Host/api/notification.js new file mode 100644 index 0000000..8ce83a7 --- /dev/null +++ b/ElectronNET.Host/api/notification.js @@ -0,0 +1,10 @@ +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +module.exports = function (socket) { + socket.on('createNotification', function (options) { + var notification = new electron_1.Notification(options); + notification.show(); + }); +}; +//# sourceMappingURL=notification.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/notification.js.map b/ElectronNET.Host/api/notification.js.map new file mode 100644 index 0000000..b7d3ab1 --- /dev/null +++ b/ElectronNET.Host/api/notification.js.map @@ -0,0 +1 @@ +{"version":3,"file":"notification.js","sourceRoot":"","sources":["notification.ts"],"names":[],"mappings":";;AAAA,qCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,UAAC,OAAO;QACpC,IAAM,YAAY,GAAG,IAAI,uBAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,YAAY,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/notification.ts b/ElectronNET.Host/api/notification.ts new file mode 100644 index 0000000..2264373 --- /dev/null +++ b/ElectronNET.Host/api/notification.ts @@ -0,0 +1,8 @@ +import { Notification } from "electron"; + +module.exports = (socket: SocketIO.Server) => { + socket.on('createNotification', (options) => { + const notification = new Notification(options); + notification.show(); + }); +} \ No newline at end of file diff --git a/ElectronNET.Host/api/tray.js b/ElectronNET.Host/api/tray.js new file mode 100644 index 0000000..1a9a53f --- /dev/null +++ b/ElectronNET.Host/api/tray.js @@ -0,0 +1,27 @@ +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +var path = require('path'); +var tray; +module.exports = function (socket) { + socket.on('create-tray', function (image, menuItems) { + var menu = electron_1.Menu.buildFromTemplate(menuItems); + addMenuItemClickConnector(menu.items, function (id) { + socket.emit("trayMenuItemClicked", id); + }); + var imagePath = path.join(__dirname.replace('api', ''), 'bin', image); + tray = new electron_1.Tray(imagePath); + tray.setContextMenu(menu); + }); + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach(function (item) { + if (item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + if ("id" in item && item.id) { + item.click = function () { callback(item.id); }; + } + }); + } +}; +//# sourceMappingURL=tray.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/tray.js.map b/ElectronNET.Host/api/tray.js.map new file mode 100644 index 0000000..e28487a --- /dev/null +++ b/ElectronNET.Host/api/tray.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tray.js","sourceRoot":"","sources":["tray.ts"],"names":[],"mappings":";;AAAA,qCAAsC;AACtC,IAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,IAAI,CAAC;AAET,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,UAAC,KAAK,EAAE,SAAS;QACtC,IAAM,IAAI,GAAG,eAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/C,yBAAyB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAC,EAAE;YACrC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,IAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,GAAG,IAAI,eAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,mCAAmC,SAAS,EAAE,QAAQ;QAClD,SAAS,CAAC,OAAO,CAAC,UAAC,IAAI;YACnB,EAAE,CAAA,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/C,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5D,CAAC;YAED,EAAE,CAAA,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,cAAQ,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/tray.ts b/ElectronNET.Host/api/tray.ts new file mode 100644 index 0000000..01b8150 --- /dev/null +++ b/ElectronNET.Host/api/tray.ts @@ -0,0 +1,30 @@ +import { Menu, Tray } from "electron"; +const path = require('path'); +let tray; + +module.exports = (socket: SocketIO.Server) => { + socket.on('create-tray', (image, menuItems) => { + const menu = Menu.buildFromTemplate(menuItems); + + addMenuItemClickConnector(menu.items, (id) => { + socket.emit("trayMenuItemClicked", id); + }); + + const imagePath = path.join(__dirname.replace('api', ''), 'bin', image); + + tray = new Tray(imagePath); + tray.setContextMenu(menu); + }); + + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach((item) => { + if(item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + + if("id" in item && item.id) { + item.click = () => { callback(item.id); }; + } + }); + } +} \ No newline at end of file diff --git a/ElectronNET.Host/main.js b/ElectronNET.Host/main.js index 5b2e0c1..b189e66 100644 --- a/ElectronNET.Host/main.js +++ b/ElectronNET.Host/main.js @@ -1,8 +1,9 @@ -const { app, BrowserWindow, Notification } = require('electron'); +const { app } = require('electron'); +const fs = require('fs'); const path = require('path'); const process = require('child_process').spawn; const portfinder = require('detect-port'); -let io, window, apiProcess, loadURL, ipc; +let io, browserWindows, ipc, apiProcess, loadURL, appApi, menu, dialog, notification, tray; app.on('ready', () => { portfinder(8000, (error, port) => { @@ -16,27 +17,14 @@ function startSocketApiBridge(port) { io.on('connection', (socket) => { console.log('ASP.NET Core Application connected...'); - - socket.on('createBrowserWindow', (options) => { - console.log(options); - options.show = true; - - window = new BrowserWindow(options); - window.loadURL(loadURL); - - window.on('closed', function () { - mainWindow = null; - apiProcess = null; - }); - - ipc = require('./api/ipc')(socket, window); - }); - - socket.on('createNotification', (options) => { - const notification = new Notification(options); - notification.show(); - }); - + + appApi = require('./api/app')(socket, app); + browserWindows = require('./api/browserWindows')(socket); + ipc = require('./api/ipc')(socket); + menu = require('./api/menu')(socket); + dialog = require('./api/dialog')(socket); + notification = require('./api/notification')(socket); + tray = require('./api/tray')(socket); }); } diff --git a/ElectronNET.Host/package-lock.json b/ElectronNET.Host/package-lock.json index 53050d4..8803dfc 100644 --- a/ElectronNET.Host/package-lock.json +++ b/ElectronNET.Host/package-lock.json @@ -4,6 +4,15 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/electron": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@types/electron/-/electron-1.6.10.tgz", + "integrity": "sha512-MOCVyzIwkBEloreoCVrTV108vSf8fFIJPsGruLCoAoBZdxtnJUqKA4lNonf/2u1twSjAspPEfmEheC+TLm/cMw==", + "dev": true, + "requires": { + "electron": "1.7.8" + } + }, "@types/node": { "version": "7.0.43", "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz", diff --git a/ElectronNET.Host/package.json b/ElectronNET.Host/package.json index f219282..d9f8a56 100644 --- a/ElectronNET.Host/package.json +++ b/ElectronNET.Host/package.json @@ -15,6 +15,7 @@ "socket.io": "^2.0.3" }, "devDependencies": { + "@types/electron": "^1.6.10", "@types/socket.io": "^1.4.31" } } diff --git a/ElectronNET.WebApp/Assets/electron.ico b/ElectronNET.WebApp/Assets/electron.ico new file mode 100644 index 0000000..3a10449 Binary files /dev/null and b/ElectronNET.WebApp/Assets/electron.ico differ diff --git a/ElectronNET.WebApp/Assets/electron_32x32.png b/ElectronNET.WebApp/Assets/electron_32x32.png new file mode 100644 index 0000000..125dde6 Binary files /dev/null and b/ElectronNET.WebApp/Assets/electron_32x32.png differ diff --git a/ElectronNET.WebApp/Controllers/HomeController.cs b/ElectronNET.WebApp/Controllers/HomeController.cs index 8868da4..2690c75 100644 --- a/ElectronNET.WebApp/Controllers/HomeController.cs +++ b/ElectronNET.WebApp/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using ElectronNET.API; using ElectronNET.API.Entities; +using System.Linq; namespace ElectronNET.WebApp.Controllers { @@ -8,16 +9,27 @@ namespace ElectronNET.WebApp.Controllers { public IActionResult Index() { - App.IpcMain.On("SayHello", (args) => { - App.CreateNotification(new NotificationOptions - { - Title = "Hallo Robert", - Body = "Nachricht von ASP.NET Core App" - }); + Electron.IpcMain.On("SayHello", (args) => { + Electron.Notification.Show(new NotificationOptions("Hallo Robert","Nachricht von ASP.NET Core App")); - App.IpcMain.Send("Goodbye", "Elephant!"); + Electron.IpcMain.Send(Electron.WindowManager.BrowserWindows.First(), "Goodbye", "Elephant!"); }); + Electron.IpcMain.On("GetPath", async (args) => + { + var currentBrowserWindow = Electron.WindowManager.BrowserWindows.First(); + + string pathName = await Electron.App.GetPathAsync(PathName.pictures); + Electron.IpcMain.Send(currentBrowserWindow, "GetPathComplete", pathName); + + currentBrowserWindow.Minimize(); + await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { + Title = "My second Window", + AutoHideMenuBar = true + },"http://www.google.de"); + }); + + return View(); } } diff --git a/ElectronNET.WebApp/ElectronNET.WebApp.csproj b/ElectronNET.WebApp/ElectronNET.WebApp.csproj index 5143f4d..a1ae41d 100644 --- a/ElectronNET.WebApp/ElectronNET.WebApp.csproj +++ b/ElectronNET.WebApp/ElectronNET.WebApp.csproj @@ -5,6 +5,7 @@ win10-x64 + @@ -21,9 +22,18 @@ + + + + PreserveNewest + + + PreserveNewest + + PreserveNewest - \ No newline at end of file + diff --git a/ElectronNET.WebApp/Startup.cs b/ElectronNET.WebApp/Startup.cs index 63b3d10..c7c3b49 100644 --- a/ElectronNET.WebApp/Startup.cs +++ b/ElectronNET.WebApp/Startup.cs @@ -1,9 +1,12 @@ using ElectronNET.API; +using ElectronNET.API.Entities; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using System.Linq; +using System.Threading; namespace ElectronNET.WebApp { @@ -35,7 +38,40 @@ namespace ElectronNET.WebApp template: "{controller=Home}/{action=Index}/{id?}"); }); - App.OpenWindow(800, 600, true); + Bootstrap(); + } + + public async void Bootstrap() + { + var menuItems = new MenuItem[] { + new MenuItem { + Label = "File", + Submenu = new MenuItem[] { + new MenuItem { + Label = "Exit", + Click = () => + { + Electron.App.Exit(); + } + } + } + }, + new MenuItem + { + Label = "About", + Click = async () => { + await Electron.Dialog.ShowMessageBoxAsync(new MessageBoxOptions("(c) 2017 Gregor Biswanger & Robert Muehsig") { + Title = "About us...", + Type = "info" + }); + } + } + }; + + Electron.Menu.SetApplicationMenu(menuItems); + Electron.Tray.Show("/Assets/electron_32x32.png", menuItems); + + var browserWindow = await Electron.WindowManager.CreateWindowAsync(); } } } diff --git a/ElectronNET.WebApp/Views/Home/Index.cshtml b/ElectronNET.WebApp/Views/Home/Index.cshtml index 2bcac87..75b5ee5 100644 --- a/ElectronNET.WebApp/Views/Home/Index.cshtml +++ b/ElectronNET.WebApp/Views/Home/Index.cshtml @@ -3,7 +3,6 @@ - Home

Hello from ASP.NET Core MVC!

@@ -17,6 +16,11 @@

+
+

+ +
+