mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-02-06 21:28:53 +00:00
Compare commits
292 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68ee626d07 | ||
|
|
fd5801ffdc | ||
|
|
b6417d0718 | ||
|
|
6f1f7cbc5e | ||
|
|
aec0da6075 | ||
|
|
c9f0c43bc9 | ||
|
|
b87d7f9899 | ||
|
|
fa51cdd72c | ||
|
|
9b270755d0 | ||
|
|
c5db735773 | ||
|
|
88f5995f40 | ||
|
|
042cd7e6cb | ||
|
|
cb096212f9 | ||
|
|
0363dc8924 | ||
|
|
8cf5053512 | ||
|
|
32046adfb5 | ||
|
|
003a9d0d35 | ||
|
|
db6bed43dc | ||
|
|
80d160a71c | ||
|
|
01d938fb1a | ||
|
|
00eb9869dc | ||
|
|
2987e3143d | ||
|
|
20ca72b794 | ||
|
|
a0e0cc3bbc | ||
|
|
e295558258 | ||
|
|
e67f6c500b | ||
|
|
23015a9f3d | ||
|
|
7daac2d04e | ||
|
|
71955b9181 | ||
|
|
a619b6e5c9 | ||
|
|
3ba3fa6414 | ||
|
|
11fbd6b259 | ||
|
|
073eb0e00d | ||
|
|
c0bf257b55 | ||
|
|
62b37d059f | ||
|
|
ca8f4c454c | ||
|
|
d660dff871 | ||
|
|
c17720a4d7 | ||
|
|
274552f52b | ||
|
|
1e3fe6183c | ||
|
|
88b04377a7 | ||
|
|
92356d3587 | ||
|
|
a3c452eea5 | ||
|
|
68288d9d73 | ||
|
|
022221307c | ||
|
|
ffc6353bf2 | ||
|
|
f4d8144a8b | ||
|
|
30d49ff6e8 | ||
|
|
db9d3b1484 | ||
|
|
a788d71530 | ||
|
|
f5e2abfdb4 | ||
|
|
42f09de7b5 | ||
|
|
72d1f4b2b9 | ||
|
|
d2b3c28f91 | ||
|
|
94c4cd82b0 | ||
|
|
600bc1a41b | ||
|
|
4e8e771293 | ||
|
|
4014ef7a4d | ||
|
|
364db7dc25 | ||
|
|
3dda18ac9a | ||
|
|
7f92ffa20e | ||
|
|
b69d4d23bf | ||
|
|
eb4144053d | ||
|
|
239d914747 | ||
|
|
5af8e489b9 | ||
|
|
b6fb1cb0bf | ||
|
|
aa98b85f18 | ||
|
|
af74d24f50 | ||
|
|
2240ffca82 | ||
|
|
f64b780a27 | ||
|
|
fbc5b93513 | ||
|
|
14d02706c0 | ||
|
|
2c14693430 | ||
|
|
54ff11acf5 | ||
|
|
b7e7ace6f3 | ||
|
|
1f7908a0f1 | ||
|
|
cafffde339 | ||
|
|
6fbba52edd | ||
|
|
8dd5d1561a | ||
|
|
25f35e34fe | ||
|
|
f1eaffb203 | ||
|
|
69ca5d6f9e | ||
|
|
5cd11a8110 | ||
|
|
c343b19a60 | ||
|
|
b3bb3ceb97 | ||
|
|
e25b89ff6a | ||
|
|
28be0dd209 | ||
|
|
8bf10c370c | ||
|
|
a32b50f86f | ||
|
|
a781234d05 | ||
|
|
8b66bdd7cb | ||
|
|
ba64639c1d | ||
|
|
5157561dc6 | ||
|
|
bbecd86cce | ||
|
|
bd99da560b | ||
|
|
9278402d65 | ||
|
|
9bc1b46810 | ||
|
|
d2956e6f2f | ||
|
|
da4e930478 | ||
|
|
8e9f7b016a | ||
|
|
10e95afa5c | ||
|
|
68505f8feb | ||
|
|
c91884a520 | ||
|
|
ccf0a4c73b | ||
|
|
660663d9c1 | ||
|
|
36ee9c4dd7 | ||
|
|
9f7c99db53 | ||
|
|
b9ba162a88 | ||
|
|
ad399f50ee | ||
|
|
428e53e265 | ||
|
|
0a02b7140b | ||
|
|
f6ea0dd8dc | ||
|
|
dc8987de5a | ||
|
|
dc73be0c81 | ||
|
|
4dc8f189f9 | ||
|
|
5ec179af5d | ||
|
|
802b1acf68 | ||
|
|
07a0bc9c7d | ||
|
|
43028afc02 | ||
|
|
d3d73611b7 | ||
|
|
6d31c41479 | ||
|
|
98a549560f | ||
|
|
8a3b9951fa | ||
|
|
552b4331b2 | ||
|
|
38785f9b18 | ||
|
|
886b4b81a5 | ||
|
|
e6b6f990d7 | ||
|
|
a2ada57292 | ||
|
|
0cede6131e | ||
|
|
ce52988aac | ||
|
|
3a52680a54 | ||
|
|
6d28e57f04 | ||
|
|
a2cdabf8cb | ||
|
|
25ab81ca8f | ||
|
|
5ba54ab40b | ||
|
|
cca8110c38 | ||
|
|
06f43032b4 | ||
|
|
0709d61120 | ||
|
|
aa09af8ad6 | ||
|
|
e90ef9e48d | ||
|
|
6d076fb99a | ||
|
|
131d1d9dd1 | ||
|
|
e5132e8198 | ||
|
|
6a7c60fdb5 | ||
|
|
8605fab9a7 | ||
|
|
c03d6e8976 | ||
|
|
5e0ef7edb5 | ||
|
|
5300609360 | ||
|
|
ed6ebe90b1 | ||
|
|
4e95322468 | ||
|
|
412f628422 | ||
|
|
3cb92169dd | ||
|
|
aea2c7aff5 | ||
|
|
ba16c4e032 | ||
|
|
8b5bb636f3 | ||
|
|
0fac6ae1cd | ||
|
|
24d1f6f844 | ||
|
|
73f7e5a7b2 | ||
|
|
01d1397a60 | ||
|
|
77e7280b1f | ||
|
|
8d6a5a757e | ||
|
|
f2e0808ede | ||
|
|
aa7efbad4b | ||
|
|
d0c52a1364 | ||
|
|
4235aa4677 | ||
|
|
8a3c86abc0 | ||
|
|
eda9b08cac | ||
|
|
a5cee6e6d5 | ||
|
|
4db0ac0ebb | ||
|
|
2a9c0e1d60 | ||
|
|
7dc3072b5f | ||
|
|
6642f9d505 | ||
|
|
078ac99098 | ||
|
|
f7cc2a995f | ||
|
|
c0ee3b8859 | ||
|
|
597df77508 | ||
|
|
f709f65f9e | ||
|
|
71d2b88b02 | ||
|
|
f4631c99f7 | ||
|
|
04968d088b | ||
|
|
5d446b23fa | ||
|
|
2b3eabf75a | ||
|
|
27a5057bb0 | ||
|
|
28f0ffaf62 | ||
|
|
0f085fdb1d | ||
|
|
7d8301af54 | ||
|
|
132b20b4ae | ||
|
|
cca5f7f40d | ||
|
|
63c2bcdf7c | ||
|
|
cad371c221 | ||
|
|
f4efad299a | ||
|
|
17e4646d11 | ||
|
|
977f389e2f | ||
|
|
b6ec73cb84 | ||
|
|
15499e38bf | ||
|
|
538bc02b54 | ||
|
|
2fb3062d4b | ||
|
|
8426c9cac2 | ||
|
|
da4a8dfa9d | ||
|
|
a2efdb3670 | ||
|
|
1ae940613c | ||
|
|
117fd6e7f4 | ||
|
|
f5434a086d | ||
|
|
dc3eec37bb | ||
|
|
8c171ba948 | ||
|
|
c1bd48b58d | ||
|
|
c10e5b74bd | ||
|
|
0c024448b7 | ||
|
|
ac9d346955 | ||
|
|
524e6c8dff | ||
|
|
17399f3f6c | ||
|
|
d50984a465 | ||
|
|
1b7dc7c0c4 | ||
|
|
c9d53d2fc1 | ||
|
|
e305029563 | ||
|
|
da643149bc | ||
|
|
c2d4821882 | ||
|
|
344c5b7c13 | ||
|
|
dcd637ae0f | ||
|
|
f832143135 | ||
|
|
dc40a0ed9a | ||
|
|
3d65136337 | ||
|
|
b53442be89 | ||
|
|
a708ccfc22 | ||
|
|
65399c23fd | ||
|
|
85127be49e | ||
|
|
86aae5ee18 | ||
|
|
fcbefa62ca | ||
|
|
e7a9ee07e0 | ||
|
|
8e38c1f79d | ||
|
|
a874243c9d | ||
|
|
354b4f09e6 | ||
|
|
ff12da19f1 | ||
|
|
1bf274a73c | ||
|
|
949741d992 | ||
|
|
e3eee0c32f | ||
|
|
ef1f0ab330 | ||
|
|
5a676cb76a | ||
|
|
44797e054c | ||
|
|
11641c9424 | ||
|
|
c8254e2d84 | ||
|
|
0997291484 | ||
|
|
959def9c86 | ||
|
|
e20dafbb66 | ||
|
|
2e87bb3955 | ||
|
|
c4c0bbadea | ||
|
|
12b46a9a48 | ||
|
|
20e2220a8c | ||
|
|
041e2942ff | ||
|
|
98e9bcdcd7 | ||
|
|
eee2a3e34d | ||
|
|
3137d58ba8 | ||
|
|
293980c0d1 | ||
|
|
8420d282bb | ||
|
|
cbb7a5bc4a | ||
|
|
2aba2a498e | ||
|
|
a2ab76d18d | ||
|
|
d01d82ffec | ||
|
|
92087bc3c8 | ||
|
|
a1aaabd588 | ||
|
|
ad20230b20 | ||
|
|
3ba46a3565 | ||
|
|
53c591f7b7 | ||
|
|
e4d03eed39 | ||
|
|
e1fa8990ef | ||
|
|
331ebb3d7f | ||
|
|
c8aec57f31 | ||
|
|
27e57f7fa1 | ||
|
|
25182f98bf | ||
|
|
2461bcbd72 | ||
|
|
8315153064 | ||
|
|
fc5250468e | ||
|
|
f059ba80b4 | ||
|
|
200f511940 | ||
|
|
1f83a8d7ab | ||
|
|
5c14e585cf | ||
|
|
d1b42fa007 | ||
|
|
861477c24d | ||
|
|
8c91c17656 | ||
|
|
652cc60f6b | ||
|
|
4ba247d77c | ||
|
|
220b4b290d | ||
|
|
4bccbdf61d | ||
|
|
e9e723eeae | ||
|
|
e6cb429ecb | ||
|
|
5316e1e2b8 | ||
|
|
189c4df46e | ||
|
|
11fd7a74a4 | ||
|
|
8bbc951ed1 | ||
|
|
ca382bf605 | ||
|
|
531446f38d | ||
|
|
fdb026c7bd |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://donorbox.org/electron-net
|
||||
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
<!-- Which version of Electron.NET CLI and API are you using? -->
|
||||
<!-- Please always try to use latest version before report. -->
|
||||
* **Version**:
|
||||
|
||||
<!-- Which version of .NET Core and Node.js are you using (if applicable)? -->
|
||||
|
||||
<!-- What target are you building for? -->
|
||||
* **Target**:
|
||||
|
||||
<!-- Enter your issue details below this comment. -->
|
||||
<!-- If you want, you can donate to increase issue priority (https://donorbox.org/electron-net) -->
|
||||
|
||||
Steps to Reproduce:
|
||||
|
||||
1.
|
||||
2.
|
||||
13
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: Feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Please search existing feature request to avoid creating duplicates. -->
|
||||
|
||||
<!-- If you want, you can donate to increase feature request priority (https://donorbox.org/electron-net) -->
|
||||
<!-- Describe the feature you'd like. -->
|
||||
13
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: Question
|
||||
about: The issue tracker is not for questions. Please ask questions on https://stackoverflow.com/questions/tagged/electron.net
|
||||
or via chat in https://gitter.im/ElectronNET/community.
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
🚨 The issue tracker is not for questions 🚨
|
||||
|
||||
The issue tracker is not for questions. Please ask questions on https://stackoverflow.com/questions/tagged/electron.net or via chat in https://gitter.im/ElectronNET/community.
|
||||
@@ -1,7 +1,8 @@
|
||||
language: csharp
|
||||
mono: none
|
||||
dotnet: 2.0.0
|
||||
dist: xenial
|
||||
dotnet: 3.1
|
||||
before_script:
|
||||
- npm install electron-packager --global
|
||||
- export PATH="$PATH:/home/travis/.dotnet/tools"
|
||||
script:
|
||||
- ./buildAll.sh
|
||||
- ./buildAll.sh
|
||||
|
||||
185
Changelog.md
185
Changelog.md
@@ -1,4 +1,185 @@
|
||||
# not release
|
||||
# Not released
|
||||
|
||||
# 8.31.2
|
||||
|
||||
ElectronNET.CLI:
|
||||
* New Feature: Deactivate PublishReadyToRun for build or start [\#395](https://github.com/ElectronNET/Electron.NET/issues/395)
|
||||
|
||||
`electronize build /target win /PublishReadyToRun false`
|
||||
`electronize start /PublishReadyToRun false`
|
||||
* Fixed bug: Application window doesn't open after packaging [\#387](https://github.com/ElectronNET/Electron.NET/issues/387)
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* New Feature: NativeImage Support (thanks [ThrDev](https://github.com/ThrDev)) [\#394](https://github.com/ElectronNET/Electron.NET/pull/394)
|
||||
* New Feature: Update menu items for context menu and system tray on-the-fly. [\#270](https://github.com/ElectronNET/Electron.NET/pull/270)
|
||||
|
||||
|
||||
# Released
|
||||
|
||||
# 8.31.1
|
||||
|
||||
ElectronNET.CLI:
|
||||
* New Feature: Set a name and author of the app in `electron.manifest.json` [\#348](https://github.com/ElectronNET/Electron.NET/issues/348#issuecomment-615977950) [\#310](https://github.com/ElectronNET/Electron.NET/issues/310#issuecomment-617361086)
|
||||
* New Feature: Live reload (thanks [syedadeel2](https://github.com/syedadeel2)) [\#390](https://github.com/ElectronNET/Electron.NET/pull/390)
|
||||
`electronize start /watch`
|
||||
* New Feature: Every new window will created with an clear cache [\#273](https://github.com/ElectronNET/Electron.NET/issues/273)
|
||||
`electronize start /clear-cache`
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* New Feature: Native Electron 8.2.3 support, but not all new features (we search contributors)
|
||||
* New Feature: We incease the startup time for ~25-36% [\#356](https://github.com/ElectronNET/Electron.NET/issues/356)
|
||||
* New Feature: Added print capability (thanks [x-xx-o](https://github.com/x-xx-o)) [\#355](https://github.com/ElectronNET/Electron.NET/pull/355)
|
||||
* New Feature: BrowserView API [\#371](https://github.com/ElectronNET/Electron.NET/issues/371)
|
||||
* Changed App.GetNameAsync and App.SetNameAsync to the App.Name Property [\#350](https://github.com/ElectronNET/Electron.NET/issues/350)
|
||||
* Fixed bug: Splash Screen disappearing on click [\#357](https://github.com/ElectronNET/Electron.NET/issues/357)
|
||||
* Fixed bug: Start MenuRole enum at 1 (thanks [jjuback](https://github.com/jjuback)) [\#369](https://github.com/ElectronNET/Electron.NET/pull/369)
|
||||
* Fixed bug: BridgeConnector not connected (spam console) [\#347](https://github.com/ElectronNET/Electron.NET/issues/347)
|
||||
* Fixed bug: BrowserWindowOptions is not setting Width and Height properly [\#373](https://github.com/ElectronNET/Electron.NET/issues/373)
|
||||
* Fixed bug: IpcMain.Once(string) is not one time use, is not removing listener [\#366](https://github.com/ElectronNET/Electron.NET/issues/366)
|
||||
* Fixed bug: IpcMain.RemoveAllListeners(string) is not removing the listeners [\#365](https://github.com/ElectronNET/Electron.NET/issues/365)
|
||||
* Fixed bug: GetLoginItemSettingsAsync does not work [\#352](https://github.com/ElectronNET/Electron.NET/issues/352)
|
||||
* Fixed bug: Using OnReadyToShow to display the main window in Blazor does not seem to work with Show set to false [\#361](https://github.com/ElectronNET/Electron.NET/issues/361)
|
||||
* Fixed bug: Unable to disable WebSecurity along with NodeIntegration enabled [\#389](https://github.com/ElectronNET/Electron.NET/issues/389)
|
||||
|
||||
# 7.30.2
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* New Feature: Different manifest file support [\#340](https://github.com/ElectronNET/Electron.NET/issues/340)
|
||||
* Create a additional manifest file: `electronize init /manifest test`
|
||||
* Start the app with your additional manifest file: `electronize start /manifest electron.manifest.test.json`
|
||||
* Build the app with your additional manifest file: `electronize build /target win /manifest electron.manifest.test.json`.
|
||||
|
||||
* New Feature: Command Line support [\#337](https://github.com/ElectronNET/Electron.NET/issues/337)
|
||||
* You can start the app with: `electronize start /args --dog=woof --test=true`
|
||||
* Or as binary: `myapp.exe /args --dog=woof --test=true`
|
||||
* Fixed bug: Start process with listen port 8000 error. [\#308](https://github.com/ElectronNET/Electron.NET/issues/308) (thanks [thecodejedi](https://github.com/thecodejedi))
|
||||
* Fixed bug: `electronize build` with no arguments would throw a `KeyNotFoundException`. (thanks [jamiebrynes7](https://github.com/jamiebrynes7))
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* New Feature: Electron 7.1.2 support, but not all new features (we search contributors) [\#341](https://github.com/ElectronNET/Electron.NET/issues/341)
|
||||
* New Feature: Electron.App.CommandLine API [\#337](https://github.com/ElectronNET/Electron.NET/issues/337)
|
||||
* New Feature: Support of BrowserWindow.AddExtension, BrowserWindow.RemoveExtension, BrowserWindow.GetExtensions (thanks [Daddoon](https://github.com/Daddoon))
|
||||
|
||||
Thank you for donation [robertmclaws](https://github.com/robertmclaws) ❤
|
||||
|
||||
# 5.30.1
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* Move to .NET Core 3.0
|
||||
* Use npm npx instead of global installations (thanks [jimbuck](https://github.com/jimbuck))
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* Move to .NET Core 3.0
|
||||
* New Feature: Add BrowserWindow.RemoveMenu() (thanks [hack2root](https://github.com/hack2root))
|
||||
|
||||
Thanks to [MaherJendoubi](https://github.com/MaherJendoubi), [kant2002](https://github.com/kant2002), [raz-canva](https://github.com/raz-canva) and [Daddoon](https://github.com/Daddoon) to give .NET Core 3.0 feedback!
|
||||
# 5.22.14
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* Fixed bug: Build fails with latest electron-builder version [\#288](https://github.com/ElectronNET/Electron.NET/issues/288)
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* New Feature: Full support for Auto Updater [(Based on electron-updater - Version 4.0.6)](https://www.electron.build/auto-update)
|
||||
* New Feature: Support for set a custom static Port to ASP.NET Backend [\#155](https://github.com/ElectronNET/Electron.NET/issues/155)
|
||||
* Fixed bug: Electron tray icon TypeError ([Electron original issue](https://github.com/electron/electron/issues/7657)) (thanks [Tum4ik](https://github.com/Tum4ik))
|
||||
* Fixed bug: Wrong tray icon path in the application built via `electronize build` command (thanks [Tum4ik](https://github.com/Tum4ik))
|
||||
* Fixed bug: fix async issue where same port is considered open [\#261](https://github.com/ElectronNET/Electron.NET/issues/261) (thanks [netpoetica](https://github.com/netpoetica))
|
||||
|
||||
ElectronNET.WebApp:
|
||||
|
||||
* Fixed usage of the `Electron.Tray.Show` according fixed bugs in the ElectronNET.CLI (thanks [Tum4ik](https://github.com/Tum4ik))
|
||||
|
||||
# 5.22.13
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* Fixed bug: Menu Item visibility [\#257](https://github.com/ElectronNET/Electron.NET/issues/257)
|
||||
* Fixed bug: electron.manifest.json - singleInstance not working [\#258](https://github.com/ElectronNET/Electron.NET/issues/258)
|
||||
* Fixed security issue: ASP.NET Core process is now bound to 127.0.0.1 instead of the broader localhost [\#258](https://github.com/ElectronNET/Electron.NET/pull/266)
|
||||
|
||||
# 5.22.12
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* New Feature: Changed from **electron packager** to [**electron builder**](https://www.electron.build/)
|
||||
* New Feature: 'add hosthook' command for add a ElectronHostHook-Directory
|
||||
* Fixed bug: 'Unexpected firewall warnings' [\#181](https://github.com/ElectronNET/Electron.NET/issues/181)
|
||||
* Fixed bug: 'found 8 vulnerabilities (1 low, 5 moderate, 2 high)' [\#199](https://github.com/ElectronNET/Electron.NET/pull/199)
|
||||
* Merged pull request: Call electronize from the Path instead of via dotnet in launchSettings.json [\#243](https://github.com/ElectronNET/Electron.NET/pull/243) (thanks [grbd](https://github.com/grbd))
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* New Feature: Electron 5.0.1 support, but not all new features
|
||||
* New Feature: Auto Updater [(Based on electron-updater)](https://www.electron.build/auto-update)
|
||||
* New Feature: Splashscreen-Support
|
||||
* New Feature: HostHook-API for execute own TypeScript/JavaScript code on native Electron Main-Process
|
||||
* New Feature: Session-API functions
|
||||
* Fixed bug: Node process running after stopping app [\#96](https://github.com/ElectronNET/Electron.NET/issues/96)
|
||||
* Fixed bug: 'X and Y options to not work on Windows 10' [\#193](https://github.com/ElectronNET/Electron.NET/issues/193)
|
||||
* Fixed bug: Unable to clear cache [\#66](https://github.com/ElectronNET/Electron.NET/issues/66)
|
||||
* Merged pull request: Fix BrowserWindow::SetMenu [\#231](https://github.com/ElectronNET/Electron.NET/pull/231) thanks (thanks [CodeKenpachi](https://github.com/CodeKenpachi))
|
||||
* Merged pull request: FIX application hangs after socket reconnect [\#233](https://github.com/ElectronNET/Electron.NET/pull/233) (thanks [pedromrpinto](https://github.com/pedromrpinto))
|
||||
* Merged pull request: Reduce chance of detecting false positives when scanning subprocesses for errors. [\#236](https://github.com/ElectronNET/Electron.NET/pull/236) (thanks [BorisTheBrave](https://github.com/BorisTheBrave))
|
||||
* Merged pull request: Updates the C# API to accept floating point as in JS. [\#240](https://github.com/ElectronNET/Electron.NET/pull/240) (thanks [BorisTheBrave](https://github.com/BorisTheBrave))
|
||||
* Merged pull request: buildReleaseNuGetPackages should leave you in the same directory you … [\#241](https://github.com/ElectronNET/Electron.NET/pull/241) (thanks [BorisTheBrave](https://github.com/BorisTheBrave))
|
||||
|
||||
ElectronNET.WebApp:
|
||||
|
||||
* Implemented a sample for the new HostHook-API
|
||||
* Fixed bug: 'Electron.NET API Demo: unable to copy code?' [\#247](https://github.com/ElectronNET/Electron.NET/issues/247)
|
||||
|
||||
# 0.0.11
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* Invoke 'npm install' without --prod flag to install needed devDependencies as well.
|
||||
* Enable SourceLink
|
||||
* NuGet Package License Information updated (deprecation of licenseUrl)
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* Documentation added for WebContents.GetUrl()
|
||||
* Enable SourceLink
|
||||
* NuGet Package License Information updated (deprecation of licenseUrl)
|
||||
|
||||
# 0.0.10
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* manifestJsonFilePath fixed (thanks @smack0007)
|
||||
* Use Electron release 3.0.0 and updated packages (thanks @deinok)
|
||||
* fixes for Socket interaction (thanks @mojinxun)
|
||||
* Fixing SingleInstances (thanks @yaofeng)
|
||||
* Enhance WebContent.GetUrl (thanks @ru-sh)
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* Show Resultcode for better debugging when using Build/Start Command
|
||||
* ElectronNET.CLI is now a global dotnet tool
|
||||
|
||||
# 0.0.9
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* Better Async handling - thanks @danielmarbach
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* More options on the 'build' command, e.g. for a 32bit debug build with electron prune: build /target custom win7-x86;win32 /dotnet-configuration Debug /electron-arch ia32 /electron-params "--prune=true "
|
||||
* .NET Core project is now built with Release configuration but can be adjusted with the new params.
|
||||
* Be aware: "Breaking" (but because of the alpha status of this project, we won't use SemVer)
|
||||
|
||||
# 0.0.8
|
||||
|
||||
This version was skipped because we unfortunately released a pre-version of this on NuGet.
|
||||
|
||||
# 0.0.7
|
||||
|
||||
@@ -11,7 +192,7 @@ ElectronNET.CLI:
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* nuget packages are now release bits and have the correct assembly verion
|
||||
* nuget packages are now release bits and have the correct assembly version
|
||||
* Version command
|
||||
* better devCleanup.cmd
|
||||
* Better Platform Support Issue - thanks to @Petermarcu
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
505
ElectronNET.API/AutoUpdater.cs
Normal file
505
ElectronNET.API/AutoUpdater.cs
Normal file
@@ -0,0 +1,505 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Enable apps to automatically update themselves. Based on electron-updater.
|
||||
/// </summary>
|
||||
public sealed class AutoUpdater
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether to automatically download an update when it is found. (Default is true)
|
||||
/// </summary>
|
||||
public bool AutoDownload
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-autoDownload-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-autoDownload-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoDownload-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoDownload-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically install a downloaded update on app quit (if `QuitAndInstall` was not called before).
|
||||
///
|
||||
/// Applicable only on Windows and Linux.
|
||||
/// </summary>
|
||||
public bool AutoInstallOnAppQuit
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-autoInstallOnAppQuit-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-autoInstallOnAppQuit-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.* Whether to allow update to pre-release versions.
|
||||
/// Defaults to "true" if application version contains prerelease components (e.g. "0.12.1-alpha.1", here "alpha" is a prerelease component), otherwise "false".
|
||||
///
|
||||
/// If "true", downgrade will be allowed("allowDowngrade" will be set to "true").
|
||||
/// </summary>
|
||||
public bool AllowPrerelease
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-allowPrerelease-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-allowPrerelease-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.*
|
||||
/// Get all release notes (from current version to latest), not just the latest (Default is false).
|
||||
/// </summary>
|
||||
public bool FullChangelog
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-fullChangelog-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-fullChangelog-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to allow version downgrade (when a user from the beta channel wants to go back to the stable channel).
|
||||
/// Taken in account only if channel differs (pre-release version component in terms of semantic versioning).
|
||||
/// Default is false.
|
||||
/// </summary>
|
||||
public bool AllowDowngrade
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-allowDowngrade-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-allowDowngrade-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For test only.
|
||||
/// </summary>
|
||||
public string UpdateConfigPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<string>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-updateConfigPath-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-updateConfigPath-get-reply");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-updateConfigPath-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the update channel. Not applicable for GitHub.
|
||||
/// Doesn’t return channel from the update configuration, only if was previously set.
|
||||
/// </summary>
|
||||
public string Channel
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<string>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-channel-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-channel-get-reply");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-channel-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is an error while updating.
|
||||
/// </summary>
|
||||
public event Action<string> OnError
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_error == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-error" + GetHashCode(), (message) =>
|
||||
{
|
||||
_error(message.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-error-event", GetHashCode());
|
||||
}
|
||||
_error += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_error -= value;
|
||||
|
||||
if (_error == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-error" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<string> _error;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when checking if an update has started.
|
||||
/// </summary>
|
||||
public event Action OnCheckingForUpdate
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_checkingForUpdate == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-checking-for-update" + GetHashCode(), () =>
|
||||
{
|
||||
_checkingForUpdate();
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-checking-for-update-event", GetHashCode());
|
||||
}
|
||||
_checkingForUpdate += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_checkingForUpdate -= value;
|
||||
|
||||
if (_checkingForUpdate == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-checking-for-update" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _checkingForUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is an available update.
|
||||
/// The update is downloaded automatically if AutoDownload is true.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateAvailable
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_updateAvailable == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-update-available" + GetHashCode(), (updateInfo) =>
|
||||
{
|
||||
_updateAvailable(JObject.Parse(updateInfo.ToString()).ToObject<UpdateInfo>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-update-available-event", GetHashCode());
|
||||
}
|
||||
_updateAvailable += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_updateAvailable -= value;
|
||||
|
||||
if (_updateAvailable == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-update-available" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is no available update.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateNotAvailable
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_updateNotAvailable == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-update-not-available" + GetHashCode(), (updateInfo) =>
|
||||
{
|
||||
_updateNotAvailable(JObject.Parse(updateInfo.ToString()).ToObject<UpdateInfo>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-update-not-available-event", GetHashCode());
|
||||
}
|
||||
_updateNotAvailable += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_updateNotAvailable -= value;
|
||||
|
||||
if (_updateNotAvailable == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-update-not-available" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateNotAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download progress.
|
||||
/// </summary>
|
||||
public event Action<ProgressInfo> OnDownloadProgress
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_downloadProgress == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-download-progress" + GetHashCode(), (progressInfo) =>
|
||||
{
|
||||
_downloadProgress(JObject.Parse(progressInfo.ToString()).ToObject<ProgressInfo>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-download-progress-event", GetHashCode());
|
||||
}
|
||||
_downloadProgress += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_downloadProgress -= value;
|
||||
|
||||
if (_downloadProgress == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-download-progress" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<ProgressInfo> _downloadProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download complete.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateDownloaded
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_updateDownloaded == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("autoUpdater-update-downloaded" + GetHashCode(), (updateInfo) =>
|
||||
{
|
||||
_updateDownloaded(JObject.Parse(updateInfo.ToString()).ToObject<UpdateInfo>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-autoUpdater-update-downloaded-event", GetHashCode());
|
||||
}
|
||||
_updateDownloaded += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_updateDownloaded -= value;
|
||||
|
||||
if (_updateDownloaded == null)
|
||||
BridgeConnector.Socket.Off("autoUpdater-update-downloaded" + GetHashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateDownloaded;
|
||||
|
||||
private static AutoUpdater _autoUpdater;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal AutoUpdater() { }
|
||||
|
||||
internal static AutoUpdater Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_autoUpdater == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_autoUpdater == null)
|
||||
{
|
||||
_autoUpdater = new AutoUpdater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _autoUpdater;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asks the server whether there is an update.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<UpdateCheckResult> CheckForUpdatesAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
|
||||
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asks the server whether there is an update.
|
||||
///
|
||||
/// This will immediately download an update, then install when the app quits.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<UpdateCheckResult> CheckForUpdatesAndNotifyAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
|
||||
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the app and installs the update after it has been downloaded.
|
||||
/// It should only be called after `update-downloaded` has been emitted.
|
||||
///
|
||||
/// Note: QuitAndInstall() will close all application windows first and only emit `before-quit` event on `app` after that.
|
||||
/// This is different from the normal quit event sequence.
|
||||
/// </summary>
|
||||
/// <param name="isSilent">*windows-only* Runs the installer in silent mode. Defaults to `false`.</param>
|
||||
/// <param name="isForceRunAfter">Run the app after finish even on silent install. Not applicable for macOS. Ignored if `isSilent` is set to `false`.</param>
|
||||
public void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start downloading update manually. You can use this method if "AutoDownload" option is set to "false".
|
||||
/// </summary>
|
||||
/// <returns>Path to downloaded file.</returns>
|
||||
public Task<string> DownloadUpdateAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterDownloadUpdateComplete" + guid, (downloadedPath) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterDownloadUpdateComplete" + guid);
|
||||
taskCompletionSource.SetResult(downloadedPath.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterDownloadUpdate", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feed URL.
|
||||
/// </summary>
|
||||
/// <returns>Feed URL.</returns>
|
||||
public Task<string> GetFeedURLAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterGetFeedURLComplete" + guid, (downloadedPath) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterGetFeedURLComplete" + guid);
|
||||
taskCompletionSource.SetResult(downloadedPath.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterGetFeedURL", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace ElectronNET.API
|
||||
internal static class BridgeConnector
|
||||
{
|
||||
private static Socket _socket;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
public static Socket Socket
|
||||
{
|
||||
|
||||
138
ElectronNET.API/BrowserView.cs
Normal file
138
ElectronNET.API/BrowserView.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
public class BrowserView
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The identifier.
|
||||
/// </value>
|
||||
public int Id { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Render and control web pages.
|
||||
/// </summary>
|
||||
public WebContents WebContents { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the view is destroyed.
|
||||
/// </summary>
|
||||
public Task<bool> IsDestroyedAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("browserView-isDestroyed-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("browserView-isDestroyed-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("browserView-isDestroyed", Id);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes and moves the view to the supplied bounds relative to the window.
|
||||
///
|
||||
/// (experimental)
|
||||
/// </summary>
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<Rectangle>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Rectangle>();
|
||||
|
||||
BridgeConnector.Socket.On("browserView-getBounds-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("browserView-getBounds-reply");
|
||||
taskCompletionSource.SetResult((Rectangle)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("browserView-getBounds", Id);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setBounds", Id, JObject.FromObject(value, _jsonSerializer));
|
||||
}
|
||||
}
|
||||
|
||||
internal Action<BrowserView> Destroyed;
|
||||
|
||||
/// <summary>
|
||||
/// BrowserView
|
||||
/// </summary>
|
||||
internal BrowserView(int id)
|
||||
{
|
||||
Id = id;
|
||||
|
||||
// Workaround: increase the Id so as not to conflict with BrowserWindow id
|
||||
// the backend detect about the value an BrowserView
|
||||
WebContents = new WebContents(id + 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force closing the view, the `unload` and `beforeunload` events won't be emitted
|
||||
/// for the web page.After you're done with a view, call this function in order to
|
||||
/// free memory and other resources as soon as possible.
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-destroy", Id);
|
||||
|
||||
Destroyed?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (experimental)
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public void SetAutoResize(AutoResizeOptions options)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setAutoResize", Id, JObject.FromObject(options, _jsonSerializer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color in #aarrggbb or #argb form. The alpha channel is optional.
|
||||
///
|
||||
/// (experimental)
|
||||
/// </summary>
|
||||
/// <param name="color">Color in #aarrggbb or #argb form. The alpha channel is optional.</param>
|
||||
public void SetBackgroundColor(string color)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setBackgroundColor", Id, color);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -1657,6 +1658,13 @@ namespace ElectronNET.API
|
||||
/// <param name="y"></param>
|
||||
public void SetPosition(int x, int y)
|
||||
{
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (isWindows10())
|
||||
{
|
||||
x = x - 7;
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Emit("browserWindowSetPosition", Id, x, y);
|
||||
}
|
||||
|
||||
@@ -1668,9 +1676,21 @@ namespace ElectronNET.API
|
||||
/// <param name="animate"></param>
|
||||
public void SetPosition(int x, int y, bool animate)
|
||||
{
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (isWindows10())
|
||||
{
|
||||
x = x - 7;
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Emit("browserWindowSetPosition", Id, x, y, animate);
|
||||
}
|
||||
|
||||
private bool isWindows10()
|
||||
{
|
||||
return RuntimeInformation.OSDescription.Contains("Windows 10");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the window’s current position.
|
||||
/// </summary>
|
||||
@@ -1909,7 +1929,7 @@ namespace ElectronNET.API
|
||||
public void SetMenu(MenuItem[] menuItems)
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("browserWindowSetMenu", JArray.FromObject(menuItems, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("browserWindowSetMenu", Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_items.AddRange(menuItems);
|
||||
|
||||
BridgeConnector.Socket.Off("windowMenuItemClicked");
|
||||
@@ -1919,6 +1939,14 @@ namespace ElectronNET.API
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the window's menu bar.
|
||||
/// </summary>
|
||||
public void RemoveMenu()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserWindowRemoveMenu", Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets progress value in progress bar. Valid range is [0, 1.0]. Remove progress
|
||||
/// bar when progress smaler as 0; Change to indeterminate mode when progress bigger as 1. On Linux
|
||||
@@ -1930,7 +1958,7 @@ namespace ElectronNET.API
|
||||
/// assumed.
|
||||
/// </summary>
|
||||
/// <param name="progress"></param>
|
||||
public void SetProgressBar(int progress)
|
||||
public void SetProgressBar(double progress)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserWindowSetProgressBar", Id, progress);
|
||||
}
|
||||
@@ -1947,7 +1975,7 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="progress"></param>
|
||||
/// <param name="progressBarOptions"></param>
|
||||
public void SetProgressBar(int progress, ProgressBarOptions progressBarOptions)
|
||||
public void SetProgressBar(double progress, ProgressBarOptions progressBarOptions)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserWindowSetProgressBar", Id, progress, JObject.FromObject(progressBarOptions, _jsonSerializer));
|
||||
}
|
||||
@@ -2277,10 +2305,74 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
public WebContents WebContents { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
/// <param name="browserView"></param>
|
||||
public void SetBrowserView(BrowserView browserView)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserWindow-setBrowserView", Id, browserView.Id);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Adds Chrome extension located at path, and returns extension's name.
|
||||
/// The method will also not return if the extension's manifest is missing or incomplete.
|
||||
/// Note: This API cannot be called before the ready event of the app module is emitted.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the Chrome extension</param>
|
||||
/// <returns></returns>
|
||||
public static Task<string> AddExtensionAsync(string path)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("browserWindow-addExtension-completed", (extensionname) => {
|
||||
BridgeConnector.Socket.Off("browserWindow-addExtension-completed");
|
||||
|
||||
taskCompletionSource.SetResult(extensionname.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("browserWindowAddExtension", path);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove Chrome extension with the specified name.
|
||||
/// Note: This API cannot be called before the ready event of the app module is emitted.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the Chrome extension to remove</param>
|
||||
public static void RemoveExtension(string name)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserWindowRemoveExtension", name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The keys are the extension names and each value is an object containing name and version properties.
|
||||
/// Note: This API cannot be called before the ready event of the app module is emitted.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Task<ChromeExtensionInfo[]> GetExtensionsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ChromeExtensionInfo[]>();
|
||||
|
||||
BridgeConnector.Socket.On("browserWindow-getExtensions-completed", (extensionslist) => {
|
||||
BridgeConnector.Socket.Off("browserWindow-getExtensions-completed");
|
||||
var chromeExtensionInfos = ((JArray)extensionslist).ToObject<ChromeExtensionInfo[]>();
|
||||
|
||||
taskCompletionSource.SetResult(chromeExtensionInfos);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("browserWindowGetExtensions");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -13,7 +12,7 @@ namespace ElectronNET.API
|
||||
public sealed class Clipboard
|
||||
{
|
||||
private static Clipboard _clipboard;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Clipboard() { }
|
||||
|
||||
@@ -238,6 +237,40 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.Emit("clipboard-write", JObject.FromObject(data, _jsonSerializer), type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an image from the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public Task<NativeImage> ReadImageAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<NativeImage>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readImage-Completed", (image) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readImage-Completed");
|
||||
|
||||
var nativeImage = ((JObject)image).ToObject<NativeImage>();
|
||||
|
||||
taskCompletionSource.SetResult(nativeImage);
|
||||
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readImage", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an image to the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="image"></param>
|
||||
/// <param name="type"></param>
|
||||
public void WriteImage(NativeImage image, string type = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-writeImage", JsonConvert.SerializeObject(image), type);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
|
||||
116
ElectronNET.API/CommandLine.cs
Normal file
116
ElectronNET.API/CommandLine.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Manipulate the command line arguments for your app that Chromium reads.
|
||||
/// </summary>
|
||||
public sealed class CommandLine
|
||||
{
|
||||
internal CommandLine() { }
|
||||
|
||||
internal static CommandLine Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_commandLine == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_commandLine == null)
|
||||
{
|
||||
_commandLine = new CommandLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _commandLine;
|
||||
}
|
||||
}
|
||||
|
||||
private static CommandLine _commandLine;
|
||||
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Append a switch (with optional value) to Chromium's command line.
|
||||
/// </summary>
|
||||
/// <param name="the_switch">A command-line switch, without the leading --</param>
|
||||
/// <param name="value">(optional) - A value for the given switch</param>
|
||||
/// <remarks>
|
||||
/// Note: This will not affect process.argv. The intended usage of this function is to control Chromium's behavior.
|
||||
/// </remarks>
|
||||
public void AppendSwitch(string the_switch, string value = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", the_switch, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append an argument to Chromium's command line. The argument will be quoted correctly. Switches will precede arguments regardless of appending order.
|
||||
///
|
||||
/// If you're appending an argument like <code>--switch=value</code>, consider using <code>appendSwitch('switch', 'value')</code> instead.
|
||||
/// </summary>
|
||||
/// <param name="value">The argument to append to the command line</param>
|
||||
/// <remarks>
|
||||
/// Note: This will not affect process.argv. The intended usage of this function is to control Chromium's behavior.
|
||||
/// </remarks>
|
||||
public void AppendArgument(string value)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("appCommandLineAppendArgument", value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the command-line switch is present.
|
||||
/// </summary>
|
||||
/// <param name="switchName">A command-line switch</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Whether the command-line switch is present.</returns>
|
||||
public async Task<bool> HasSwitchAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("appCommandLineHasSwitchCompleted", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("appCommandLineHasSwitchCompleted");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("appCommandLineHasSwitch", switchName);
|
||||
|
||||
return await taskCompletionSource.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The command-line switch value.
|
||||
/// </summary>
|
||||
/// <param name="switchName">A command-line switch</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The command-line switch value.</returns>
|
||||
/// <remarks>
|
||||
/// Note: When the switch is not present or has no value, it returns empty string.
|
||||
/// </remarks>
|
||||
public async Task<string> GetSwitchValueAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("appCommandLineGetSwitchValueCompleted", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("appCommandLineGetSwitchValueCompleted");
|
||||
taskCompletionSource.SetResult((string)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("appCommandLineGetSwitchValue", switchName);
|
||||
|
||||
return await taskCompletionSource.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -13,7 +15,7 @@ namespace ElectronNET.API
|
||||
public sealed class Dialog
|
||||
{
|
||||
private static Dialog _dialog;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Dialog() { }
|
||||
|
||||
@@ -47,18 +49,25 @@ namespace ElectronNET.API
|
||||
public Task<string[]> ShowOpenDialogAsync(BrowserWindow browserWindow, OpenDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string[]>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showOpenDialogComplete", (filePaths) =>
|
||||
BridgeConnector.Socket.On("showOpenDialogComplete" + guid, (filePaths) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showOpenDialogComplete");
|
||||
BridgeConnector.Socket.Off("showOpenDialogComplete" + guid);
|
||||
|
||||
var result = ((JArray)filePaths).ToObject<string[]>();
|
||||
taskCompletionSource.SetResult(result);
|
||||
var list = new List<string>();
|
||||
foreach (var item in result)
|
||||
{
|
||||
list.Add(HttpUtility.UrlDecode(item));
|
||||
}
|
||||
taskCompletionSource.SetResult(list.ToArray());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("showOpenDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer));
|
||||
|
||||
BridgeConnector.Socket.Emit("showOpenDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
@@ -72,17 +81,19 @@ namespace ElectronNET.API
|
||||
public Task<string> ShowSaveDialogAsync(BrowserWindow browserWindow, SaveDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showSaveDialogComplete", (filename) =>
|
||||
BridgeConnector.Socket.On("showSaveDialogComplete" + guid, (filename) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showSaveDialogComplete");
|
||||
BridgeConnector.Socket.Off("showSaveDialogComplete" + guid);
|
||||
|
||||
taskCompletionSource.SetResult(filename.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("showSaveDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer));
|
||||
JObject.FromObject(options, _jsonSerializer),
|
||||
guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
@@ -139,10 +150,11 @@ namespace ElectronNET.API
|
||||
public Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<MessageBoxResult>();
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showMessageBoxComplete", (args) =>
|
||||
BridgeConnector.Socket.On("showMessageBoxComplete" + guid, (args) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showMessageBoxComplete");
|
||||
BridgeConnector.Socket.Off("showMessageBoxComplete" + guid);
|
||||
|
||||
var result = ((JArray)args);
|
||||
|
||||
@@ -156,12 +168,13 @@ namespace ElectronNET.API
|
||||
|
||||
if (browserWindow == null)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer), guid);
|
||||
} else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("showMessageBox",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(messageBoxOptions, _jsonSerializer));
|
||||
JObject.FromObject(messageBoxOptions, _jsonSerializer),
|
||||
guid);
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
@@ -205,16 +218,18 @@ namespace ElectronNET.API
|
||||
public Task ShowCertificateTrustDialogAsync(BrowserWindow browserWindow, CertificateTrustDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showCertificateTrustDialogComplete", () =>
|
||||
BridgeConnector.Socket.On("showCertificateTrustDialogComplete" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showCertificateTrustDialogComplete");
|
||||
BridgeConnector.Socket.Off("showCertificateTrustDialogComplete" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("showCertificateTrustDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer));
|
||||
JObject.FromObject(options, _jsonSerializer),
|
||||
guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
/// </summary>
|
||||
public static App App { get { return App.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Enable apps to automatically update themselves. Based on electron-updater.
|
||||
/// </summary>
|
||||
public static AutoUpdater AutoUpdater { get { return AutoUpdater.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Control your windows.
|
||||
/// </summary>
|
||||
@@ -59,5 +64,14 @@
|
||||
/// Perform copy and paste operations on the system clipboard.
|
||||
/// </summary>
|
||||
public static Clipboard Clipboard { get { return Clipboard.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to execute native JavaScript/TypeScript code from the host process.
|
||||
///
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// ElectronHostHook directory:
|
||||
/// <c>electronize add HostHook</c>
|
||||
/// </summary>
|
||||
public static HostHook HostHook { get { return HostHook.Instance; } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageOutputPath>..\artifacts</PackageOutputPath>
|
||||
<PackageId>ElectronNET.API</PackageId>
|
||||
<Authors>Gregor Biswanger, Robert Muehsig</Authors>
|
||||
<Company />
|
||||
<Product>Electron.NET</Product>
|
||||
<PackageLicenseUrl>https://github.com/ElectronNET/Electron.NET/blob/master/LICENSE</PackageLicenseUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/ElectronNET/Electron.NET/</PackageProjectUrl>
|
||||
<Description>Building cross platform electron based desktop apps with .NET Core and ASP.NET NET Core.
|
||||
<Description>Building cross platform electron based desktop apps with .NET Core and ASP.NET Core.
|
||||
This package contains the API to access the "native" electron API.</Description>
|
||||
<RepositoryUrl>https://github.com/ElectronNET/Electron.NET/</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<PackageTags>electron aspnetcore</PackageTags>
|
||||
<PackageReleaseNotes>Changelog: https://github.com/ElectronNET/Electron.NET/blob/master/Changelog.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/ElectronNET/Electron.NET/master/assets/images/electron.net-logo-square.png</PackageIconUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\netcoreapp2.0\ElectronNET.API.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile>bin\Release\netcoreapp2.0\ElectronNET.API.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\netcoreapp2.0\ElectronNET.API.xml</DocumentationFile>
|
||||
<PackageIcon>PackageIcon.png</PackageIcon>
|
||||
<Version>99.0.0.0</Version>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.0.0" />
|
||||
<PackageReference Include="SocketIoClientDotNet" Version="1.0.3" />
|
||||
<None Include="PackageIcon.png" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' == 'Windows_NT'">
|
||||
@@ -41,5 +32,16 @@ This package contains the API to access the "native" electron API.</Description>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' != 'Windows_NT'">
|
||||
<Exec Command="$(ProjectDir)devCleanup.sh" IgnoreExitCode="true" />
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SocketIoClientDotNet" Version="1.0.5" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
33
ElectronNET.API/Entities/AddRepresentationOptions.cs
Normal file
33
ElectronNET.API/Entities/AddRepresentationOptions.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AddRepresentationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height
|
||||
/// </summary>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the buffer
|
||||
/// </summary>
|
||||
public byte[] Buffer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dataURL
|
||||
/// </summary>
|
||||
public string DataUrl { get; set; }
|
||||
}
|
||||
}
|
||||
38
ElectronNET.API/Entities/AutoResizeOptions.cs
Normal file
38
ElectronNET.API/Entities/AutoResizeOptions.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AutoResizeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// If `true`, the view's width will grow and shrink together with the window.
|
||||
/// `false` by default.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Width { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// If `true`, the view's height will grow and shrink together with the window.
|
||||
/// `false` by default.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Height { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// If `true`, the view's x position and width will grow and shrink proportionally
|
||||
/// with the window. `false` by default.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Horizontal { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// If `true`, the view's y position and height will grow and shrink proportionally
|
||||
/// with the window. `false` by default.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Vertical { get; set; } = false;
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/BitmapOptions.cs
Normal file
13
ElectronNET.API/Entities/BitmapOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BitmapOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scale factor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
35
ElectronNET.API/Entities/BlockMapDataHolder.cs
Normal file
35
ElectronNET.API/Entities/BlockMapDataHolder.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlockMapDataHolder
|
||||
{
|
||||
/// <summary>
|
||||
/// The file size. Used to verify downloaded size (save one HTTP request to get length).
|
||||
/// Also used when block map data is embedded into the file(appimage, windows web installer package).
|
||||
/// </summary>
|
||||
public double Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The block map file size. Used when block map data is embedded into the file (appimage, windows web installer package).
|
||||
/// This information can be obtained from the file itself, but it requires additional HTTP request,
|
||||
/// so, to reduce request count, block map size is specified in the update metadata too.
|
||||
/// </summary>
|
||||
public double BlockMapSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file checksum.
|
||||
/// </summary>
|
||||
public string Sha512 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool IsAdminRightsRequired { get; set; }
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/BrowserViewConstructorOptions.cs
Normal file
13
ElectronNET.API/Entities/BrowserViewConstructorOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BrowserViewConstructorOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// See BrowserWindow.
|
||||
/// </summary>
|
||||
public WebPreferences WebPreferences { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,24 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// Window's width in pixels. Default is 800.
|
||||
/// </summary>
|
||||
public int Width { get; set; }
|
||||
public int Width { get; set; } = 800;
|
||||
|
||||
/// <summary>
|
||||
/// Window's height in pixels. Default is 600.
|
||||
/// </summary>
|
||||
public int Height { get; set; }
|
||||
public int Height { get; set; } = 600;
|
||||
|
||||
/// <summary>
|
||||
/// ( if y is used) Window's left offset from screen. Default is to center the
|
||||
/// window.
|
||||
/// </summary>
|
||||
public int X { get; set; }
|
||||
public int X { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// ( if x is used) Window's top offset from screen. Default is to center the
|
||||
/// window.
|
||||
/// </summary>
|
||||
public int Y { get; set; }
|
||||
public int Y { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The width and height would be used as web page's size, which means the actual
|
||||
|
||||
33
ElectronNET.API/Entities/ChromeExtensionInfo.cs
Normal file
33
ElectronNET.API/Entities/ChromeExtensionInfo.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Provide metadata about the current loaded Chrome extension
|
||||
/// </summary>
|
||||
public class ChromeExtensionInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChromeExtensionInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the Chrome extension.</param>
|
||||
/// <param name="version">The version of the Chrome extension.</param>
|
||||
public ChromeExtensionInfo(string name, string version)
|
||||
{
|
||||
Name = name;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the Chrome extension
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version of the Chrome extension
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
||||
24
ElectronNET.API/Entities/ClearStorageDataOptions.cs
Normal file
24
ElectronNET.API/Entities/ClearStorageDataOptions.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ClearStorageDataOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Should follow window.location.origin’s representation scheme://host:port.
|
||||
/// </summary>
|
||||
public string Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The types of storages to clear, can contain: appcache, cookies, filesystem,
|
||||
/// indexdb, localstorage, shadercache, websql, serviceworkers, cachestorage.
|
||||
/// </summary>
|
||||
public string[] Storages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The types of quotas to clear, can contain: temporary, persistent, syncable.
|
||||
/// </summary>
|
||||
public string[] Quotas { get; set; }
|
||||
}
|
||||
}
|
||||
23
ElectronNET.API/Entities/CreateFromBitmapOptions.cs
Normal file
23
ElectronNET.API/Entities/CreateFromBitmapOptions.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateFromBitmapOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height
|
||||
/// </summary>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
23
ElectronNET.API/Entities/CreateFromBufferOptions.cs
Normal file
23
ElectronNET.API/Entities/CreateFromBufferOptions.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateFromBufferOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height
|
||||
/// </summary>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
67
ElectronNET.API/Entities/CreateInterruptedDownloadOptions.cs
Normal file
67
ElectronNET.API/Entities/CreateInterruptedDownloadOptions.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateInterruptedDownloadOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Absolute path of the download.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Complete URL chain for the download.
|
||||
/// </summary>
|
||||
public string[] UrlChain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string MimeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start range for the download.
|
||||
/// </summary>
|
||||
public int Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total length of the download.
|
||||
/// </summary>
|
||||
public int Length { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Last-Modified header value.
|
||||
/// </summary>
|
||||
public string LastModified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ETag header value.
|
||||
/// </summary>
|
||||
public string ETag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time when download was started in number of seconds since UNIX epoch.
|
||||
/// </summary>
|
||||
public int StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="path">Absolute path of the download.</param>
|
||||
/// <param name="urlChain">Complete URL chain for the download.</param>
|
||||
/// <param name="offset">Start range for the download.</param>
|
||||
/// <param name="length">Total length of the download.</param>
|
||||
/// <param name="lastModified">Last-Modified header value.</param>
|
||||
/// <param name="eTag">ETag header value.</param>
|
||||
public CreateInterruptedDownloadOptions(string path, string[] urlChain, int offset, int length, string lastModified, string eTag)
|
||||
{
|
||||
Path = path;
|
||||
UrlChain = urlChain;
|
||||
Offset = offset;
|
||||
Length = length;
|
||||
LastModified = lastModified;
|
||||
ETag = eTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
ElectronNET.API/Entities/EnableNetworkEmulationOptions.cs
Normal file
28
ElectronNET.API/Entities/EnableNetworkEmulationOptions.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EnableNetworkEmulationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether to emulate network outage. Defaults to false.
|
||||
/// </summary>
|
||||
public bool Offline { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// RTT in ms. Defaults to 0 which will disable latency throttling.
|
||||
/// </summary>
|
||||
public int Latency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Download rate in Bps. Defaults to 0 which will disable download throttling.
|
||||
/// </summary>
|
||||
public int DownloadThroughput { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Upload rate in Bps. Defaults to 0 which will disable upload throttling.
|
||||
/// </summary>
|
||||
public int UploadThroughput { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum HighlightMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Highlight the tray icon when it is clicked and also when its context menu is open. This is the default.
|
||||
/// </summary>
|
||||
selection,
|
||||
|
||||
/// <summary>
|
||||
/// Always highlight the tray icon.
|
||||
/// </summary>
|
||||
always,
|
||||
|
||||
/// <summary>
|
||||
/// Never highlight the tray icon.
|
||||
/// </summary>
|
||||
never
|
||||
}
|
||||
}
|
||||
@@ -21,5 +21,10 @@
|
||||
/// files.
|
||||
/// </summary>
|
||||
public string BaseURLForDataURL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra headers for the request.
|
||||
/// </summary>
|
||||
public string ExtraHeaders { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -68,12 +69,12 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// If false, the menu item will be greyed out and unclickable.
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// If false, the menu item will be entirely hidden.
|
||||
/// </summary>
|
||||
public bool Visible { get; set; }
|
||||
public bool Visible { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Should only be specified for checkbox or radio type menu items.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/// <summary>
|
||||
/// The undo
|
||||
/// </summary>
|
||||
undo,
|
||||
undo = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The redo
|
||||
|
||||
@@ -1,109 +1,453 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
// TODO: Need some of real code :)
|
||||
/// <summary>
|
||||
///
|
||||
/// Native Image handler for Electron.NET
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(NativeImageJsonConverter))]
|
||||
public class NativeImage
|
||||
{
|
||||
// public static NativeImage CreateEmpty()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
private readonly Dictionary<float, Image> _images = new Dictionary<float, Image>();
|
||||
private bool _isTemplateImage;
|
||||
|
||||
// public static NativeImage CreateFromBuffer(byte[] buffer)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
private static readonly Dictionary<string, float> ScaleFactorPairs = new Dictionary<string, float>
|
||||
{
|
||||
{"@2x", 2.0f}, {"@3x", 3.0f}, {"@1x", 1.0f}, {"@4x", 4.0f},
|
||||
{"@5x", 5.0f}, {"@1.25x", 1.25f}, {"@1.33x", 1.33f}, {"@1.4x", 1.4f},
|
||||
{"@1.5x", 1.5f}, {"@1.8x", 1.8f}, {"@2.5x", 2.5f}
|
||||
};
|
||||
|
||||
// public static NativeImage CreateFromBuffer(byte[] buffer, CreateFromBufferOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
private static float? ExtractDpiFromFilePath(string filePath)
|
||||
{
|
||||
var withoutExtension = Path.GetFileNameWithoutExtension(filePath);
|
||||
return ScaleFactorPairs
|
||||
.Where(p => withoutExtension.EndsWith(p.Key))
|
||||
.Select(p => p.Value)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
private static Image BytesToImage(byte[] bytes)
|
||||
{
|
||||
var ms = new MemoryStream(bytes);
|
||||
return Image.FromStream(ms);
|
||||
}
|
||||
|
||||
// public static NativeImage CreateFromDataURL(string dataURL)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates an empty NativeImage
|
||||
/// </summary>
|
||||
public static NativeImage CreateEmpty()
|
||||
{
|
||||
return new NativeImage();
|
||||
}
|
||||
|
||||
// public static NativeImage CreateFromPath(string path)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static NativeImage CreateFromBitmap(Bitmap bitmap, CreateFromBitmapOptions options = null)
|
||||
{
|
||||
if (options is null)
|
||||
{
|
||||
options = new CreateFromBitmapOptions();
|
||||
}
|
||||
|
||||
// public void AddRepresentation(AddRepresentationOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
return new NativeImage(bitmap, options.ScaleFactor);
|
||||
}
|
||||
|
||||
// public NativeImage Crop(Rectangle rect)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates a NativeImage from a byte array.
|
||||
/// </summary>
|
||||
public static NativeImage CreateFromBuffer(byte[] buffer, CreateFromBufferOptions options = null)
|
||||
{
|
||||
if (options is null)
|
||||
{
|
||||
options = new CreateFromBufferOptions();
|
||||
}
|
||||
|
||||
// public int GetAspectRatio()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
var ms = new MemoryStream(buffer);
|
||||
var image = Image.FromStream(ms);
|
||||
|
||||
// public byte[] GetBitmap()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
return new NativeImage(image, options.ScaleFactor);
|
||||
}
|
||||
|
||||
// public byte[] GetBitmap(BitmapOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates a NativeImage from a base64 encoded data URL.
|
||||
/// </summary>
|
||||
/// <param name="dataUrl">A data URL with a base64 encoded image.</param>
|
||||
public static NativeImage CreateFromDataURL(string dataUrl)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
var parsedDataUrl = Regex.Match(dataUrl, @"data:image/(?<type>.+?),(?<data>.+)");
|
||||
var actualData = parsedDataUrl.Groups["data"].Value;
|
||||
var binData = Convert.FromBase64String(actualData);
|
||||
|
||||
// public byte[] GetNativeHandle()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
var image = BytesToImage(binData);
|
||||
|
||||
// public Size GetSize()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
images.Add(1.0f, image);
|
||||
|
||||
// public bool IsEmpty()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
return new NativeImage(images);
|
||||
}
|
||||
|
||||
// public bool IsTemplateImage()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates a NativeImage from an image on the disk.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the image</param>
|
||||
public static NativeImage CreateFromPath(string path)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
if (Regex.IsMatch(path, "(@.+?x)"))
|
||||
{
|
||||
var dpi = ExtractDpiFromFilePath(path);
|
||||
if (dpi == null)
|
||||
{
|
||||
throw new Exception($"Invalid scaling factor for '{path}'.");
|
||||
}
|
||||
|
||||
// public NativeImage Resize(ResizeOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
images[dpi.Value] = Image.FromFile(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||
var extension = Path.GetExtension(path);
|
||||
// Load as 1x dpi
|
||||
images[1.0f] = Image.FromFile(path);
|
||||
|
||||
// public void SetTemplateImage(bool option)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
foreach (var scale in ScaleFactorPairs)
|
||||
{
|
||||
var fileName = $"{fileNameWithoutExtension}{scale}.{extension}";
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
var dpi = ExtractDpiFromFilePath(fileName);
|
||||
if (dpi != null)
|
||||
{
|
||||
images[dpi.Value] = Image.FromFile(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public byte[] ToBitmap(ToBitmapOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
return new NativeImage(images);
|
||||
}
|
||||
|
||||
// public string ToDataURL(ToDataURLOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates an empty NativeImage
|
||||
/// </summary>
|
||||
public NativeImage()
|
||||
{
|
||||
}
|
||||
|
||||
// public byte[] ToJPEG(int quality)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates a NativeImage from a bitmap and scale factor
|
||||
/// </summary>
|
||||
public NativeImage(Image bitmap, float scaleFactor = 1.0f)
|
||||
{
|
||||
_images.Add(scaleFactor, bitmap);
|
||||
}
|
||||
|
||||
// public byte[] ToPNG(ToPNGOptions options)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
/// <summary>
|
||||
/// Creates a NativeImage from a dictionary of scales and images.
|
||||
/// </summary>
|
||||
public NativeImage(Dictionary<float, Image> imageDictionary)
|
||||
{
|
||||
_images = imageDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Crops the image specified by the input rectangle and computes scale factor
|
||||
/// </summary>
|
||||
public NativeImage Crop(Rectangle rect)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
foreach (var image in _images)
|
||||
{
|
||||
images.Add(image.Key, Crop(rect.X, rect.Y, rect.Width, rect.Height, image.Key));
|
||||
}
|
||||
|
||||
return new NativeImage(images);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the image and computes scale factor
|
||||
/// </summary>
|
||||
public NativeImage Resize(ResizeOptions options)
|
||||
{
|
||||
var images = new Dictionary<float, Image>();
|
||||
foreach (var image in _images)
|
||||
{
|
||||
images.Add(image.Key, Resize(options.Width, options.Height, image.Key));
|
||||
}
|
||||
|
||||
return new NativeImage(images);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an image representation for a specific scale factor.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public void AddRepresentation(AddRepresentationOptions options)
|
||||
{
|
||||
if (options.Buffer.Length > 0)
|
||||
{
|
||||
_images[options.ScaleFactor] =
|
||||
CreateFromBuffer(options.Buffer, new CreateFromBufferOptions {ScaleFactor = options.ScaleFactor})
|
||||
.GetScale(options.ScaleFactor);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(options.DataUrl))
|
||||
{
|
||||
_images[options.ScaleFactor] = CreateFromDataURL(options.DataUrl).GetScale(options.ScaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the aspect ratio for the image based on scale factor
|
||||
/// </summary>
|
||||
/// <param name="scaleFactor">Optional</param>
|
||||
public float GetAspectRatio(float scaleFactor = 1.0f)
|
||||
{
|
||||
var image = GetScale(scaleFactor);
|
||||
if (image != null)
|
||||
{
|
||||
return image.Width / image.Height;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a byte array that contains the image's raw bitmap pixel data.
|
||||
/// </summary>
|
||||
public byte[] GetBitmap(BitmapOptions options)
|
||||
{
|
||||
return ToBitmap(new ToBitmapOptions{ ScaleFactor = options.ScaleFactor });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a byte array that contains the image's raw bitmap pixel data.
|
||||
/// </summary>
|
||||
public byte[] GetNativeHandle()
|
||||
{
|
||||
return ToBitmap(new ToBitmapOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the specified image based on scale factor
|
||||
/// </summary>
|
||||
public Size GetSize(float scaleFactor = 1.0f)
|
||||
{
|
||||
if (_images.ContainsKey(scaleFactor))
|
||||
{
|
||||
var image = _images[scaleFactor];
|
||||
return new Size
|
||||
{
|
||||
Width = image.Width,
|
||||
Height = image.Height
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the NativeImage instance is empty.
|
||||
/// </summary>
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return _images.Count <= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated. Whether the image is a template image.
|
||||
/// </summary>
|
||||
public bool IsTemplateImage => _isTemplateImage;
|
||||
|
||||
/// <summary>
|
||||
/// Deprecated. Marks the image as a template image.
|
||||
/// </summary>
|
||||
public void SetTemplateImage(bool option)
|
||||
{
|
||||
_isTemplateImage = option;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a bitmap based on the scale factor
|
||||
/// </summary>
|
||||
public byte[] ToBitmap(ToBitmapOptions options)
|
||||
{
|
||||
return ImageToBytes(ImageFormat.Bmp, options.ScaleFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a data URL based on the scale factor
|
||||
/// </summary>
|
||||
public string ToDataURL(ToDataUrlOptions options)
|
||||
{
|
||||
if (!_images.ContainsKey(options.ScaleFactor))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var image = _images[options.ScaleFactor];
|
||||
var mimeType = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == image.RawFormat.Guid)?.MimeType;
|
||||
if (mimeType is null)
|
||||
{
|
||||
mimeType = "image/png";
|
||||
}
|
||||
|
||||
var bytes = ImageToBytes(image.RawFormat, options.ScaleFactor);
|
||||
var base64 = Convert.ToBase64String(bytes);
|
||||
|
||||
return $"data:{mimeType};base64,{base64}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a JPEG for the default scale factor
|
||||
/// </summary>
|
||||
public byte[] ToJPEG(int quality)
|
||||
{
|
||||
return ImageToBytes(ImageFormat.Jpeg, 1.0f, quality);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a PNG for the specified scale factor
|
||||
/// </summary>
|
||||
public byte[] ToPNG(ToPNGOptions options)
|
||||
{
|
||||
return ImageToBytes(ImageFormat.Png, options.ScaleFactor);
|
||||
}
|
||||
|
||||
private byte[] ImageToBytes(ImageFormat imageFormat = null, float scaleFactor = 1.0f, int quality = 100)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
|
||||
if (_images.ContainsKey(scaleFactor))
|
||||
{
|
||||
var image = _images[scaleFactor];
|
||||
var encoderCodecInfo = GetEncoder(imageFormat ?? image.RawFormat);
|
||||
var encoder = Encoder.Quality;
|
||||
|
||||
var encoderParameters = new EncoderParameters(1)
|
||||
{
|
||||
Param = new[]
|
||||
{
|
||||
new EncoderParameter(encoder, quality)
|
||||
}
|
||||
};
|
||||
|
||||
image.Save(ms, encoderCodecInfo, encoderParameters);
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Image Resize(int? width, int? height, float scaleFactor = 1.0f)
|
||||
{
|
||||
if (!_images.ContainsKey(scaleFactor) || (width is null && height is null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var image = _images[scaleFactor];
|
||||
using (var g = Graphics.FromImage(image))
|
||||
{
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
|
||||
var aspect = GetAspectRatio(scaleFactor);
|
||||
|
||||
width ??= Convert.ToInt32(image.Width * aspect);
|
||||
height ??= Convert.ToInt32(image.Height * aspect);
|
||||
|
||||
width = Convert.ToInt32(width * scaleFactor);
|
||||
height = Convert.ToInt32(height * scaleFactor);
|
||||
|
||||
var bmp = new Bitmap(width.Value, height.Value);
|
||||
g.DrawImage(bmp,
|
||||
new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
|
||||
new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
|
||||
GraphicsUnit.Pixel);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
|
||||
private Image Crop(int? x, int? y, int? width, int? height, float scaleFactor = 1.0f)
|
||||
{
|
||||
if (!_images.ContainsKey(scaleFactor))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var image = _images[scaleFactor];
|
||||
using (var g = Graphics.FromImage(image))
|
||||
{
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
|
||||
x ??= 0;
|
||||
y ??= 0;
|
||||
|
||||
x = Convert.ToInt32(x * scaleFactor);
|
||||
y = Convert.ToInt32(y * scaleFactor);
|
||||
|
||||
width ??= image.Width;
|
||||
height ??= image.Height;
|
||||
|
||||
width = Convert.ToInt32(width * scaleFactor);
|
||||
height = Convert.ToInt32(height * scaleFactor);
|
||||
|
||||
var bmp = new Bitmap(width.Value, height.Value);
|
||||
g.DrawImage(bmp, new System.Drawing.Rectangle(0, 0, image.Width, image.Height), new System.Drawing.Rectangle(x.Value, y.Value, width.Value, height.Value), GraphicsUnit.Pixel);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoder(ImageFormat format)
|
||||
{
|
||||
var codecs = ImageCodecInfo.GetImageDecoders();
|
||||
foreach (ImageCodecInfo codec in codecs)
|
||||
{
|
||||
if (codec.FormatID == format.Guid)
|
||||
{
|
||||
return codec;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal Dictionary<float,string> GetAllScaledImages()
|
||||
{
|
||||
var dict = new Dictionary<float,string>();
|
||||
try
|
||||
{
|
||||
foreach (var (scale, image) in _images)
|
||||
{
|
||||
dict.Add(scale, Convert.ToBase64String(ImageToBytes(null, scale)));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
internal Image GetScale(float scaleFactor)
|
||||
{
|
||||
if (_images.ContainsKey(scaleFactor))
|
||||
{
|
||||
return _images[scaleFactor];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
ElectronNET.API/Entities/NativeImageJsonConverter.cs
Normal file
34
ElectronNET.API/Entities/NativeImageJsonConverter.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
internal class NativeImageJsonConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value is NativeImage nativeImage)
|
||||
{
|
||||
var scaledImages = nativeImage.GetAllScaledImages();
|
||||
serializer.Serialize(writer, scaledImages);
|
||||
}
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var dict = serializer.Deserialize<Dictionary<float, string>>(reader);
|
||||
var newDictionary = new Dictionary<float, Image>();
|
||||
foreach (var item in dict)
|
||||
{
|
||||
var bytes = Convert.FromBase64String(item.Value);
|
||||
newDictionary.Add(item.Key, Image.FromStream(new MemoryStream(bytes)));
|
||||
}
|
||||
return new NativeImage(newDictionary);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(NativeImage);
|
||||
}
|
||||
}
|
||||
107
ElectronNET.API/Entities/PrintOptions.cs
Normal file
107
ElectronNET.API/Entities/PrintOptions.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Print dpi
|
||||
/// </summary>
|
||||
public class PrintDpi
|
||||
{
|
||||
/// <summary>
|
||||
/// The horizontal dpi
|
||||
/// </summary>
|
||||
public float Horizontal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The vertical dpi
|
||||
/// </summary>
|
||||
public float Vertical { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The page range to print
|
||||
/// </summary>
|
||||
public class PrintPageRange
|
||||
{
|
||||
/// <summary>
|
||||
/// From
|
||||
/// </summary>
|
||||
public int From { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// To
|
||||
/// </summary>
|
||||
public int To { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print options
|
||||
/// </summary>
|
||||
public class PrintOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't ask user for print settings
|
||||
/// </summary>
|
||||
public bool Silent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prints the background color and image of the web page
|
||||
/// </summary>
|
||||
public bool PrintBackground { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the printer device name to use
|
||||
/// </summary>
|
||||
public string DeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set whether the printed web page will be in color or grayscale
|
||||
/// </summary>
|
||||
public bool Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the type of margins to use. Uses 0 for default margin, 1 for no
|
||||
/// margin, and 2 for minimum margin.
|
||||
/// </summary>
|
||||
public int MarginsType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// true for landscape, false for portrait.
|
||||
/// </summary>
|
||||
public bool Landscape { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The scale factor of the web page
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of pages to print per page sheet
|
||||
/// </summary>
|
||||
public int PagesPerSheet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of copies of the web page to print
|
||||
/// </summary>
|
||||
public bool Copies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the web page should be collated
|
||||
/// </summary>
|
||||
public bool Collate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The page range to print
|
||||
/// </summary>
|
||||
public PrintPageRange PageRanges { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the duplex mode of the printed web page. Can be simplex, shortEdge, or longEdge.
|
||||
/// </summary>
|
||||
public string DuplexMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dpi
|
||||
/// </summary>
|
||||
public PrintDpi Dpi { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
29
ElectronNET.API/Entities/PrinterInfo.cs
Normal file
29
ElectronNET.API/Entities/PrinterInfo.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Printer info
|
||||
/// </summary>
|
||||
public class PrinterInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Status
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is default
|
||||
/// </summary>
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
37
ElectronNET.API/Entities/ProgressInfo.cs
Normal file
37
ElectronNET.API/Entities/ProgressInfo.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProgressInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string BytesPerSecond { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Percent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Total { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Transferred { get; set; }
|
||||
}
|
||||
}
|
||||
36
ElectronNET.API/Entities/ProxyConfig.cs
Normal file
36
ElectronNET.API/Entities/ProxyConfig.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProxyConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL associated with the PAC file.
|
||||
/// </summary>
|
||||
public string PacScript { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rules indicating which proxies to use.
|
||||
/// </summary>
|
||||
public string ProxyRules { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rules indicating which URLs should bypass the proxy settings.
|
||||
/// </summary>
|
||||
public string ProxyBypassRules { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pacScript">The URL associated with the PAC file.</param>
|
||||
/// <param name="proxyRules">Rules indicating which proxies to use.</param>
|
||||
/// <param name="proxyBypassRules">Rules indicating which URLs should bypass the proxy settings.</param>
|
||||
public ProxyConfig(string pacScript, string proxyRules, string proxyBypassRules)
|
||||
{
|
||||
PacScript = pacScript;
|
||||
ProxyRules = proxyRules;
|
||||
ProxyBypassRules = proxyBypassRules;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
ElectronNET.API/Entities/ReleaseNoteInfo.cs
Normal file
18
ElectronNET.API/Entities/ReleaseNoteInfo.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ReleaseNoteInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The version.
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The note.
|
||||
/// </summary>
|
||||
public string Note { get; set; }
|
||||
}
|
||||
}
|
||||
31
ElectronNET.API/Entities/RemoveClientCertificate.cs
Normal file
31
ElectronNET.API/Entities/RemoveClientCertificate.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RemoveClientCertificate
|
||||
{
|
||||
/// <summary>
|
||||
/// Origin of the server whose associated client certificate must be removed from
|
||||
/// the cache.
|
||||
/// </summary>
|
||||
public string Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// clientCertificate.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="origin">Origin of the server whose associated client certificate
|
||||
/// must be removed from the cache.</param>
|
||||
/// <param name="type">clientCertificate.</param>
|
||||
public RemoveClientCertificate(string origin, string type)
|
||||
{
|
||||
Origin = origin;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
ElectronNET.API/Entities/RemovePassword.cs
Normal file
53
ElectronNET.API/Entities/RemovePassword.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RemovePassword
|
||||
{
|
||||
/// <summary>
|
||||
/// When provided, the authentication info related to the origin will only be
|
||||
/// removed otherwise the entire cache will be cleared.
|
||||
/// </summary>
|
||||
public string Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Credentials of the authentication. Must be provided if removing by origin.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Realm of the authentication. Must be provided if removing by origin.
|
||||
/// </summary>
|
||||
public string Realm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scheme of the authentication. Can be basic, digest, ntlm, negotiate.
|
||||
/// Must be provided if removing by origin.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public Scheme Scheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// password.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Credentials of the authentication. Must be provided if removing by origin.
|
||||
/// </summary>
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type">password.</param>
|
||||
public RemovePassword(string type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
ElectronNET.API/Entities/ResizeOptions.cs
Normal file
23
ElectronNET.API/Entities/ResizeOptions.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ResizeOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height
|
||||
/// </summary>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// good, better, or best. Default is "best";
|
||||
/// </summary>
|
||||
public string Quality { get; set; } = "best";
|
||||
}
|
||||
}
|
||||
28
ElectronNET.API/Entities/Scheme.cs
Normal file
28
ElectronNET.API/Entities/Scheme.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum Scheme
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
basic,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
digest,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
ntlm,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
negotiate
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/ToBitmapOptions.cs
Normal file
13
ElectronNET.API/Entities/ToBitmapOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ToBitmapOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/ToDataUrlOptions.cs
Normal file
13
ElectronNET.API/Entities/ToDataUrlOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ToDataUrlOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/ToPNGOptions.cs
Normal file
13
ElectronNET.API/Entities/ToPNGOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ToPNGOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
29
ElectronNET.API/Entities/UpdateCancellationToken.cs
Normal file
29
ElectronNET.API/Entities/UpdateCancellationToken.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateCancellationToken
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool Cancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
23
ElectronNET.API/Entities/UpdateCheckResult.cs
Normal file
23
ElectronNET.API/Entities/UpdateCheckResult.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateCheckResult
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UpdateInfo UpdateInfo { get; set; } = new UpdateInfo();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string[] Download { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UpdateCancellationToken CancellationToken { get; set; }
|
||||
}
|
||||
}
|
||||
13
ElectronNET.API/Entities/UpdateFileInfo.cs
Normal file
13
ElectronNET.API/Entities/UpdateFileInfo.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateFileInfo : BlockMapDataHolder
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
38
ElectronNET.API/Entities/UpdateInfo.cs
Normal file
38
ElectronNET.API/Entities/UpdateInfo.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The version.
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UpdateFileInfo[] Files { get; set; } = new UpdateFileInfo[0];
|
||||
|
||||
/// <summary>
|
||||
/// The release name.
|
||||
/// </summary>
|
||||
public string ReleaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The release notes.
|
||||
/// </summary>
|
||||
public ReleaseNoteInfo[] ReleaseNotes { get; set; } = new ReleaseNoteInfo[0];
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ReleaseDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The staged rollout percentage, 0-100.
|
||||
/// </summary>
|
||||
public int StagingPercentage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace ElectronNET.API.Entities
|
||||
public bool DevTools { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether node integration is enabled. Default is true.
|
||||
/// Whether node integration is enabled. Required to enable IPC. Default is true.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public bool NodeIntegration { get; set; } = true;
|
||||
@@ -126,7 +126,7 @@ namespace ElectronNET.API.Entities
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public string BlinkFeatures { get; set; }
|
||||
public string EnableBlinkFeatures { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of feature strings separated by ,, like CSSVariables,KeyboardEventKey to
|
||||
@@ -185,7 +185,8 @@ namespace ElectronNET.API.Entities
|
||||
/// Context' entry in the combo box at the top of the Console tab. This option is
|
||||
/// currently experimental and may change or be removed in future Electron releases.
|
||||
/// </summary>
|
||||
public bool ContextIsolation { get; set; }
|
||||
[DefaultValue(true)]
|
||||
public bool ContextIsolation { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use native window.open(). Defaults to false. This option is currently experimental.
|
||||
@@ -203,6 +204,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// <c>true</c> if [webview tag]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool WebviewTag { get; set; }
|
||||
[DefaultValue(false)]
|
||||
public bool WebviewTag { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace ElectronNET.API
|
||||
public sealed class GlobalShortcut
|
||||
{
|
||||
private static GlobalShortcut _globalShortcut;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal GlobalShortcut() { }
|
||||
|
||||
|
||||
126
ElectronNET.API/HostHook.cs
Normal file
126
ElectronNET.API/HostHook.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows you to execute native JavaScript/TypeScript code from the host process.
|
||||
///
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// ElectronHostHook directory:
|
||||
/// <c>electronize add HostHook</c>
|
||||
/// </summary>
|
||||
public sealed class HostHook
|
||||
{
|
||||
private static HostHook _electronHostHook;
|
||||
private static object _syncRoot = new object();
|
||||
string oneCallguid = Guid.NewGuid().ToString();
|
||||
|
||||
internal HostHook() { }
|
||||
|
||||
internal static HostHook Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_electronHostHook == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_electronHostHook == null)
|
||||
{
|
||||
_electronHostHook = new HostHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _electronHostHook;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
public void Call(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + oneCallguid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + oneCallguid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments, oneCallguid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Results from the executed host code.</typeparam>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
/// <returns></returns>
|
||||
public Task<T> CallAsync<T>(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Complete" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
BridgeConnector.Socket.Off(socketEventName + "Complete" + guid);
|
||||
T data;
|
||||
|
||||
try
|
||||
{
|
||||
if (result.GetType().IsValueType || result is string)
|
||||
{
|
||||
data = (T)result;
|
||||
}
|
||||
else
|
||||
{
|
||||
var token = JToken.Parse(result.ToString());
|
||||
if (token is JArray)
|
||||
{
|
||||
data = token.ToObject<T>();
|
||||
}
|
||||
else if (token is JObject)
|
||||
{
|
||||
data = token.ToObject<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (T)result;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new InvalidCastException("Return value does not match with the generic type.", exception);
|
||||
}
|
||||
|
||||
taskCompletionSource.SetResult(data);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace ElectronNET.API
|
||||
public sealed class IpcMain
|
||||
{
|
||||
private static IpcMain _ipcMain;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal IpcMain() { }
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace ElectronNET.API
|
||||
public void On(string channel, Action<object> listener)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("registerIpcMainChannel", channel);
|
||||
BridgeConnector.Socket.Off(channel);
|
||||
BridgeConnector.Socket.On(channel, (args) =>
|
||||
{
|
||||
List<object> objectArray = FormatArguments(args);
|
||||
@@ -152,7 +153,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
List<JObject> jobjects = new List<JObject>();
|
||||
List<JArray> jarrays = new List<JArray>();
|
||||
List<Object> objects = new List<Object>();
|
||||
List<object> objects = new List<object>();
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using ElectronNET.API.Extensions;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -16,7 +15,7 @@ namespace ElectronNET.API
|
||||
public sealed class Menu
|
||||
{
|
||||
private static Menu _menu;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Menu() { }
|
||||
|
||||
@@ -83,25 +82,25 @@ namespace ElectronNET.API
|
||||
/// <param name="menuItems">The menu items.</param>
|
||||
public void SetContextMenu(BrowserWindow browserWindow, MenuItem[] menuItems)
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
|
||||
if (!_contextMenuItems.ContainsKey(browserWindow.Id))
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_contextMenuItems.Add(browserWindow.Id, menuItems.ToList());
|
||||
|
||||
var x = _contextMenuItems.ToDictionary(kv => kv.Key, kv => kv.Value.AsReadOnly());
|
||||
ContextMenuItems = new ReadOnlyDictionary<int, ReadOnlyCollection<MenuItem>>(x);
|
||||
|
||||
BridgeConnector.Socket.Off("contextMenuItemClicked");
|
||||
BridgeConnector.Socket.On("contextMenuItemClicked", (results) =>
|
||||
{
|
||||
var id = ((JArray)results).First.ToString();
|
||||
var browserWindowId = (int)((JArray)results).Last;
|
||||
|
||||
MenuItem menuItem = _contextMenuItems[browserWindowId].GetMenuItem(id);
|
||||
menuItem.Click?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Off("contextMenuItemClicked");
|
||||
BridgeConnector.Socket.On("contextMenuItemClicked", (results) =>
|
||||
{
|
||||
var id = ((JArray)results).First.ToString();
|
||||
var browserWindowId = (int)((JArray)results).Last;
|
||||
|
||||
MenuItem menuItem = _contextMenuItems[browserWindowId].GetMenuItem(id);
|
||||
menuItem.Click?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -116,8 +115,7 @@ namespace ElectronNET.API
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ElectronNET.API
|
||||
public sealed class Notification
|
||||
{
|
||||
private static Notification _notification;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Notification() { }
|
||||
|
||||
|
||||
BIN
ElectronNET.API/PackageIcon.png
Normal file
BIN
ElectronNET.API/PackageIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
16
ElectronNET.API/QuitEventArgs.cs
Normal file
16
ElectronNET.API/QuitEventArgs.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed class QuitEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Will prevent the default behaviour, which is terminating the application.
|
||||
/// </summary>
|
||||
public void PreventDefault()
|
||||
{
|
||||
Electron.App.PreventQuit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace ElectronNET.API
|
||||
private event Action<Display, string[]> _onDisplayMetricsChanged;
|
||||
|
||||
private static Screen _screen;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Screen() { }
|
||||
|
||||
|
||||
380
ElectronNET.API/Session.cs
Normal file
380
ElectronNET.API/Session.cs
Normal file
@@ -0,0 +1,380 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage browser sessions, cookies, cache, proxy settings, etc.
|
||||
/// </summary>
|
||||
public class Session
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The identifier.
|
||||
/// </value>
|
||||
public int Id { get; private set; }
|
||||
|
||||
internal Session(int id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate authentication.
|
||||
/// </summary>
|
||||
/// <param name="domains">A comma-separated list of servers for which integrated authentication is enabled.</param>
|
||||
public void AllowNTLMCredentialsForDomains(string domains)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-allowNTLMCredentialsForDomains", Id, domains);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the session’s HTTP authentication cache.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public Task ClearAuthCacheAsync(RemovePassword options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearAuthCache-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearAuthCache-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearAuthCache", Id, JObject.FromObject(options, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the session’s HTTP authentication cache.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public Task ClearAuthCacheAsync(RemoveClientCertificate options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearAuthCache-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearAuthCache-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearAuthCache", Id, JObject.FromObject(options, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the session’s HTTP cache.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task ClearCacheAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearCache-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearCache-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearCache", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the host resolver cache.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task ClearHostResolverCacheAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearHostResolverCache-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearHostResolverCache-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearHostResolverCache", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the data of web storages.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task ClearStorageDataAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearStorageData-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearStorageData-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearStorageData", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the data of web storages.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public Task ClearStorageDataAsync(ClearStorageDataOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-clearStorageData-options-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-clearStorageData-options-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-clearStorageData-options", Id, JObject.FromObject(options, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows resuming cancelled or interrupted downloads from previous Session. The
|
||||
/// API will generate a DownloadItem that can be accessed with the will-download
|
||||
/// event. The DownloadItem will not have any WebContents associated with it and the
|
||||
/// initial state will be interrupted. The download will start only when the resume
|
||||
/// API is called on the DownloadItem.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public void CreateInterruptedDownload(CreateInterruptedDownloadOptions options)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-createInterruptedDownload", Id, JObject.FromObject(options, _jsonSerializer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables any network emulation already active for the session. Resets to the
|
||||
/// original network configuration.
|
||||
/// </summary>
|
||||
public void DisableNetworkEmulation()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-disableNetworkEmulation", Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emulates network with the given configuration for the session.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public void EnableNetworkEmulation(EnableNetworkEmulationOptions options)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-enableNetworkEmulation", Id, JObject.FromObject(options, _jsonSerializer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes any unwritten DOMStorage data to disk.
|
||||
/// </summary>
|
||||
public void FlushStorageData()
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-flushStorageData", Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="identifier"></param>
|
||||
/// <returns></returns>
|
||||
public Task<int[]> GetBlobDataAsync(string identifier)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<int[]>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-getBlobData-completed" + guid, (buffer) =>
|
||||
{
|
||||
var result = ((JArray)buffer).ToObject<int[]>();
|
||||
|
||||
BridgeConnector.Socket.Off("webContents-session-getBlobData-completed" + guid);
|
||||
taskCompletionSource.SetResult(result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-getBlobData", Id, identifier, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get session's current cache size.
|
||||
/// </summary>
|
||||
/// <returns>Callback is invoked with the session's current cache size.</returns>
|
||||
public Task<int> GetCacheSizeAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<int>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-getCacheSize-completed" + guid, (size) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-getCacheSize-completed" + guid);
|
||||
taskCompletionSource.SetResult((int)size);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-getCacheSize", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<string[]> GetPreloadsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string[]>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-getPreloads-completed" + guid, (preloads) =>
|
||||
{
|
||||
var result = ((JArray)preloads).ToObject<string[]>();
|
||||
BridgeConnector.Socket.Off("webContents-session-getPreloads-completed" + guid);
|
||||
taskCompletionSource.SetResult(result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-getPreloads", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<string> GetUserAgent()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-getUserAgent-completed" + guid, (userAgent) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-getUserAgent-completed" + guid);
|
||||
taskCompletionSource.SetResult(userAgent.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-getUserAgent", Id, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the proxy information for url. The callback will be called with
|
||||
/// callback(proxy) when the request is performed.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public Task<string> ResolveProxyAsync(string url)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-resolveProxy-completed" + guid, (proxy) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-resolveProxy-completed" + guid);
|
||||
taskCompletionSource.SetResult(proxy.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-resolveProxy", Id, url, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets download saving directory. By default, the download directory will be the
|
||||
/// Downloads under the respective app folder.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
public void SetDownloadPath(string path)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-setDownloadPath", Id, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds scripts that will be executed on ALL web contents that are associated with
|
||||
/// this session just before normal preload scripts run.
|
||||
/// </summary>
|
||||
/// <param name="preloads"></param>
|
||||
public void SetPreloads(string[] preloads)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-setPreloads", Id, preloads);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the proxy settings. When pacScript and proxyRules are provided together,
|
||||
/// the proxyRules option is ignored and pacScript configuration is applied.
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public Task SetProxyAsync(ProxyConfig config)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-session-setProxy-completed" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-session-setProxy-completed" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-session-setProxy", Id, JObject.FromObject(config, _jsonSerializer), guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the userAgent for this session. This doesn't affect existing WebContents, and
|
||||
/// each WebContents can use webContents.setUserAgent to override the session-wide
|
||||
/// user agent.
|
||||
/// </summary>
|
||||
/// <param name="userAgent"></param>
|
||||
public void SetUserAgent(string userAgent)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-setUserAgent", Id, userAgent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the userAgent and acceptLanguages for this session. The
|
||||
/// acceptLanguages must a comma separated ordered list of language codes, for
|
||||
/// example "en-US,fr,de,ko,zh-CN,ja". This doesn't affect existing WebContents, and
|
||||
/// each WebContents can use webContents.setUserAgent to override the session-wide
|
||||
/// user agent.
|
||||
/// </summary>
|
||||
/// <param name="userAgent"></param>
|
||||
/// <param name="acceptLanguages">The
|
||||
/// acceptLanguages must a comma separated ordered list of language codes, for
|
||||
/// example "en-US,fr,de,ko,zh-CN,ja".</param>
|
||||
public void SetUserAgent(string userAgent, string acceptLanguages)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-session-setUserAgent", Id, userAgent, acceptLanguages);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace ElectronNET.API
|
||||
public sealed class Shell
|
||||
{
|
||||
private static Shell _shell;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Shell() { }
|
||||
|
||||
@@ -132,10 +132,10 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="options">macOS only</param>
|
||||
/// <param name="action">macOS only</param>
|
||||
/// <param name="errorAction">Action to get the error message.</param>
|
||||
/// <returns>Whether an application was available to open the URL.
|
||||
/// If callback is specified, always returns true.</returns>
|
||||
public Task<bool> OpenExternalAsync(string url, OpenExternalOptions options, Action<Error> action)
|
||||
public Task<bool> OpenExternalAsync(string url, OpenExternalOptions options, Action<Error> errorAction)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace ElectronNET.API
|
||||
}
|
||||
});
|
||||
|
||||
_openExternalCallbacks.Add(url, action);
|
||||
_openExternalCallbacks.Add(url, errorAction);
|
||||
|
||||
BridgeConnector.Socket.Emit("shell-openExternal", url, JObject.FromObject(options, _jsonSerializer), true);
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace ElectronNET.API
|
||||
// TODO: Implement macOS Events
|
||||
|
||||
private static Tray _tray;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Tray() { }
|
||||
|
||||
@@ -252,6 +252,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("create-tray", image, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
_items.Clear();
|
||||
_items.AddRange(menuItems);
|
||||
|
||||
BridgeConnector.Socket.Off("trayMenuItemClicked");
|
||||
@@ -307,18 +308,6 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.Emit("tray-setTitle", title);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// macOS: Sets when the tray’s icon background becomes highlighted (in blue).
|
||||
///
|
||||
/// Note: You can use highlightMode with a BrowserWindow by toggling between
|
||||
/// 'never' and 'always' modes when the window visibility changes.
|
||||
/// </summary>
|
||||
/// <param name="highlightMode"></param>
|
||||
public void SetHighlightMode(HighlightMode highlightMode)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("tray-setHighlightMode", highlightMode.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Windows: Displays a tray balloon.
|
||||
/// </summary>
|
||||
@@ -351,8 +340,7 @@ namespace ElectronNET.API
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace ElectronNET.API
|
||||
/// </value>
|
||||
public int Id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Manage browser sessions, cookies, cache, proxy settings, etc.
|
||||
/// </summary>
|
||||
public Session Session { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the renderer process crashes or is killed.
|
||||
/// </summary>
|
||||
@@ -82,6 +87,7 @@ namespace ElectronNET.API
|
||||
internal WebContents(int id)
|
||||
{
|
||||
Id = id;
|
||||
Session = new Session(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,6 +107,53 @@ namespace ElectronNET.API
|
||||
BridgeConnector.Socket.Emit("webContentsOpenDevTools", Id, JObject.FromObject(openDevToolsOptions, _jsonSerializer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get system printers.
|
||||
/// </summary>
|
||||
/// <returns>printers</returns>
|
||||
public Task<PrinterInfo[]> GetPrintersAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<PrinterInfo[]>();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-getPrinters-completed", (printers) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-getPrinters-completed");
|
||||
|
||||
taskCompletionSource.SetResult(((Newtonsoft.Json.Linq.JArray)printers).ToObject<PrinterInfo[]>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-getPrinters", Id);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints window's web page.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns>success</returns>
|
||||
public Task<bool> PrintAsync(PrintOptions options = null)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-print-completed", (success) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-print-completed");
|
||||
taskCompletionSource.SetResult((bool)success);
|
||||
});
|
||||
|
||||
if(options == null)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-print", Id, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("webContents-print", Id, JObject.FromObject(options, _jsonSerializer));
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints window's web page as PDF with Chromium's preview printing custom
|
||||
/// settings.The landscape will be ignored if @page CSS at-rule is used in the web page.
|
||||
@@ -132,6 +185,79 @@ namespace ElectronNET.API
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is used to get the Url of the loaded page.
|
||||
/// It's usefull if a web-server redirects you and you need to know where it redirects. For instance, It's useful in case of Implicit Authorization.
|
||||
/// </summary>
|
||||
/// <returns>URL of the loaded page</returns>
|
||||
public Task<string> GetUrl()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
var eventString = "webContents-getUrl" + Id;
|
||||
BridgeConnector.Socket.On(eventString, (url) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(eventString);
|
||||
taskCompletionSource.SetResult((string)url);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-getUrl", Id);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The async method will resolve when the page has finished loading,
|
||||
/// and rejects if the page fails to load.
|
||||
///
|
||||
/// A noop rejection handler is already attached, which avoids unhandled rejection
|
||||
/// errors.
|
||||
///
|
||||
/// Loads the `url` in the window. The `url` must contain the protocol prefix, e.g.
|
||||
/// the `http://` or `file://`. If the load should bypass http cache then use the
|
||||
/// `pragma` header to achieve it.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
public Task LoadURLAsync(string url)
|
||||
{
|
||||
return LoadURLAsync(url, new LoadURLOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The async method will resolve when the page has finished loading,
|
||||
/// and rejects if the page fails to load.
|
||||
///
|
||||
/// A noop rejection handler is already attached, which avoids unhandled rejection
|
||||
/// errors.
|
||||
///
|
||||
/// Loads the `url` in the window. The `url` must contain the protocol prefix, e.g.
|
||||
/// the `http://` or `file://`. If the load should bypass http cache then use the
|
||||
/// `pragma` header to achieve it.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="options"></param>
|
||||
public Task LoadURLAsync(string url, LoadURLOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
|
||||
BridgeConnector.Socket.On("webContents-loadURL-complete" + Id, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-loadURL-complete" + Id);
|
||||
BridgeConnector.Socket.Off("webContents-loadURL-error" + Id);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.On("webContents-loadURL-error" + Id, (error) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("webContents-loadURL-error" + Id);
|
||||
taskCompletionSource.SetException(new InvalidOperationException(error.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("webContents-loadURL", Id, url, JObject.FromObject(options, _jsonSerializer));
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -22,16 +23,27 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeSettings.SocketPort = argument.ToUpper().Replace("/ELECTRONPORT=", "");
|
||||
Console.WriteLine("Use Electron Port: " + BridgeSettings.SocketPort);
|
||||
} else if(argument.ToUpper().Contains("ELECTRONWEBPORT"))
|
||||
}
|
||||
else if (argument.ToUpper().Contains("ELECTRONWEBPORT"))
|
||||
{
|
||||
BridgeSettings.WebPort = argument.ToUpper().Replace("/ELECTRONWEBPORT=", "");
|
||||
}
|
||||
}
|
||||
|
||||
if(HybridSupport.IsElectronActive)
|
||||
if (HybridSupport.IsElectronActive)
|
||||
{
|
||||
builder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
|
||||
.UseUrls("http://0.0.0.0:" + BridgeSettings.WebPort);
|
||||
// check for the content folder if its exists in base director otherwise no need to include
|
||||
// It was used before because we are publishing the project which copies everything to bin folder and contentroot wwwroot was folder there.
|
||||
// now we have implemented the live reload if app is run using /watch then we need to use the default project path.
|
||||
if (Directory.Exists($"{AppDomain.CurrentDomain.BaseDirectory}\\wwwroot"))
|
||||
{
|
||||
builder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
|
||||
.UseUrls("http://localhost:" + BridgeSettings.WebPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.UseUrls("http://localhost:" + BridgeSettings.WebPort);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -15,7 +16,7 @@ namespace ElectronNET.API
|
||||
public sealed class WindowManager
|
||||
{
|
||||
private static WindowManager _windowManager;
|
||||
private static object _syncRoot = new Object();
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal WindowManager() { }
|
||||
|
||||
@@ -38,6 +39,23 @@ namespace ElectronNET.API
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quit when all windows are closed. (Default is true)
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [quit window all closed]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsQuitOnWindowAllClosed
|
||||
{
|
||||
get { return _isQuitOnWindowAllClosed; }
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("quit-app-window-all-closed-event", value);
|
||||
_isQuitOnWindowAllClosed = value;
|
||||
}
|
||||
}
|
||||
private bool _isQuitOnWindowAllClosed = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser windows.
|
||||
/// </summary>
|
||||
@@ -47,6 +65,15 @@ namespace ElectronNET.API
|
||||
public IReadOnlyCollection<BrowserWindow> BrowserWindows { get { return _browserWindows.AsReadOnly(); } }
|
||||
private List<BrowserWindow> _browserWindows = new List<BrowserWindow>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser views.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The browser view.
|
||||
/// </value>
|
||||
public IReadOnlyCollection<BrowserView> BrowserViews { get { return _browserViews.AsReadOnly(); } }
|
||||
private List<BrowserView> _browserViews = new List<BrowserView>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the window asynchronous.
|
||||
/// </summary>
|
||||
@@ -97,7 +124,87 @@ namespace ElectronNET.API
|
||||
loadUrl = $"{loadUrl}:{BridgeSettings.WebPort}";
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Emit("createBrowserWindow", JObject.FromObject(options, _jsonSerializer), loadUrl);
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (isWindows10())
|
||||
{
|
||||
options.Width = options.Width + 14;
|
||||
options.Height = options.Height + 7;
|
||||
}
|
||||
|
||||
if (options.X == -1 && options.Y == -1)
|
||||
{
|
||||
options.X = 0;
|
||||
options.Y = 0;
|
||||
|
||||
BridgeConnector.Socket.Emit("createBrowserWindow", JObject.FromObject(options, _jsonSerializer), loadUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (isWindows10())
|
||||
{
|
||||
options.X = options.X - 7;
|
||||
}
|
||||
|
||||
var ownjsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
BridgeConnector.Socket.Emit("createBrowserWindow", JObject.FromObject(options, ownjsonSerializer), loadUrl);
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private bool isWindows10()
|
||||
{
|
||||
return RuntimeInformation.OSDescription.Contains("Windows 10");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<BrowserView> CreateBrowserViewAsync()
|
||||
{
|
||||
return CreateBrowserViewAsync(new BrowserViewConstructorOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public Task<BrowserView> CreateBrowserViewAsync(BrowserViewConstructorOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<BrowserView>();
|
||||
|
||||
BridgeConnector.Socket.On("BrowserViewCreated", (id) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("BrowserViewCreated");
|
||||
|
||||
string browserViewId = id.ToString();
|
||||
BrowserView browserView = new BrowserView(int.Parse(browserViewId));
|
||||
browserView.Destroyed += (b) => _browserViews.Remove(b);
|
||||
|
||||
_browserViews.Add(browserView);
|
||||
|
||||
taskCompletionSource.SetResult(browserView);
|
||||
});
|
||||
|
||||
var ownjsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
BridgeConnector.Socket.Emit("createBrowserView", JObject.FromObject(options, ownjsonSerializer));
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
@@ -11,7 +8,7 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "main.js");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "package.json");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "package-lock.json");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(tempPath, "build-helper.js");
|
||||
|
||||
string hostApiFolder = Path.Combine(tempPath, "api");
|
||||
if (Directory.Exists(hostApiFolder) == false)
|
||||
@@ -21,6 +18,7 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "ipc.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "app.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserWindows.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "commandLine.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "dialog.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "menu.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "notification.js", "api.");
|
||||
@@ -30,6 +28,15 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "shell.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "screen.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "clipboard.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "autoUpdater.js", "api.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserView.js", "api.");
|
||||
|
||||
string splashscreenFolder = Path.Combine(tempPath, "splashscreen");
|
||||
if (Directory.Exists(splashscreenFolder) == false)
|
||||
{
|
||||
Directory.CreateDirectory(splashscreenFolder);
|
||||
}
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(splashscreenFolder, "index.html", "splashscreen.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
67
ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs
Normal file
67
ElectronNET.CLI/Commands/Actions/DirectoryCopy.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
public static class DirectoryCopy
|
||||
{
|
||||
public static void Do(string sourceDirName, string destDirName, bool copySubDirs, List<string> ignoredSubDirs)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourceDirName);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
// If the destination directory doesn't exist, create it.
|
||||
if (!Directory.Exists(destDirName))
|
||||
{
|
||||
Directory.CreateDirectory(destDirName);
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryInfo targetDir = new DirectoryInfo(destDirName);
|
||||
|
||||
foreach (FileInfo fileDel in targetDir.EnumerateFiles())
|
||||
{
|
||||
fileDel.Delete();
|
||||
}
|
||||
foreach (DirectoryInfo dirDel in targetDir.EnumerateDirectories())
|
||||
{
|
||||
dirDel.Delete(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Get the files in the directory and copy them to the new location.
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string temppath = Path.Combine(destDirName, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
// If copying subdirectories, copy them and their contents to new location.
|
||||
if (copySubDirs)
|
||||
{
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
if (ignoredSubDirs.Contains(subdir.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string temppath = Path.Combine(destDirName, subdir.Name);
|
||||
Do(subdir.FullName, temppath, copySubDirs, ignoredSubDirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
@@ -9,13 +7,12 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
public struct GetTargetPlatformInformationResult
|
||||
{
|
||||
public string DesiredPlatform { get; set; }
|
||||
public string NetCorePublishRid { get; set; }
|
||||
public string ElectronPackerPlatform { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public static GetTargetPlatformInformationResult Do(string desiredPlatform)
|
||||
public static GetTargetPlatformInformationResult Do(string desiredPlatform, string specifiedPlatfromFromCustom)
|
||||
{
|
||||
string netCorePublishRid = string.Empty;
|
||||
string electronPackerPlatform = string.Empty;
|
||||
@@ -24,32 +21,38 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
{
|
||||
case "win":
|
||||
netCorePublishRid = "win-x64";
|
||||
electronPackerPlatform = "win32";
|
||||
electronPackerPlatform = "win";
|
||||
break;
|
||||
case "osx":
|
||||
netCorePublishRid = "osx-x64";
|
||||
electronPackerPlatform = "darwin";
|
||||
electronPackerPlatform = "mac";
|
||||
break;
|
||||
case "linux":
|
||||
netCorePublishRid = "linux-x64";
|
||||
electronPackerPlatform = "linux";
|
||||
break;
|
||||
case "linux-arm":
|
||||
netCorePublishRid = "linux-arm";
|
||||
electronPackerPlatform = "linux";
|
||||
break;
|
||||
case "custom":
|
||||
var splittedSpecified = specifiedPlatfromFromCustom.Split(';');
|
||||
netCorePublishRid = splittedSpecified[0];
|
||||
electronPackerPlatform = splittedSpecified[1];
|
||||
break;
|
||||
default:
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
desiredPlatform = "win";
|
||||
netCorePublishRid = "win-x64";
|
||||
electronPackerPlatform = "win32";
|
||||
netCorePublishRid = $"win-x{(Environment.Is64BitOperatingSystem ? "64" : "86")}";
|
||||
electronPackerPlatform = "win";
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
desiredPlatform = "osx";
|
||||
netCorePublishRid = "osx-x64";
|
||||
electronPackerPlatform = "darwin";
|
||||
electronPackerPlatform = "mac";
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
desiredPlatform = "linux";
|
||||
netCorePublishRid = "linux-x64";
|
||||
electronPackerPlatform = "linux";
|
||||
}
|
||||
@@ -59,7 +62,6 @@ namespace ElectronNET.CLI.Commands.Actions
|
||||
|
||||
return new GetTargetPlatformInformationResult()
|
||||
{
|
||||
DesiredPlatform = desiredPlatform,
|
||||
ElectronPackerPlatform = electronPackerPlatform,
|
||||
NetCorePublishRid = netCorePublishRid
|
||||
};
|
||||
|
||||
136
ElectronNET.CLI/Commands/AddCommand.cs
Normal file
136
ElectronNET.CLI/Commands/AddCommand.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace ElectronNET.CLI.Commands
|
||||
{
|
||||
public class AddCommand : ICommand
|
||||
{
|
||||
public const string COMMAND_NAME = "add";
|
||||
public const string COMMAND_DESCRIPTION = "The add command needs to be invoked via 'add hosthook'. This creates a special folder for your custom npm package installation.";
|
||||
public const string COMMAND_ARGUMENTS = "hosthook";
|
||||
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
|
||||
|
||||
|
||||
private string[] _args;
|
||||
|
||||
public AddCommand(string[] args)
|
||||
{
|
||||
_args = args;
|
||||
}
|
||||
|
||||
private static string ElectronHostHookFolderName = "ElectronHostHook";
|
||||
|
||||
public Task<bool> ExecuteAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
if(_args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Specify 'hosthook' to add custom npm packages.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(_args[0].ToLowerInvariant() != "hosthook")
|
||||
{
|
||||
Console.WriteLine("Specify 'hosthook' to add custom npm packages.");
|
||||
return false;
|
||||
}
|
||||
|
||||
string aspCoreProjectPath = "";
|
||||
|
||||
// Maybe ToDo: Adding the possiblity to specify a path (like we did in the InitCommand, but this would require a better command args parser)
|
||||
aspCoreProjectPath = Directory.GetCurrentDirectory();
|
||||
|
||||
var currentDirectory = aspCoreProjectPath;
|
||||
|
||||
var targetFilePath = Path.Combine(currentDirectory, ElectronHostHookFolderName);
|
||||
|
||||
if(Directory.Exists(targetFilePath))
|
||||
{
|
||||
Console.WriteLine("ElectronHostHook directory already in place. If you want to start over, delete the folder and invoke this command again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Console.WriteLine("Adding the ElectronHostHook folder to your project...");
|
||||
|
||||
Directory.CreateDirectory(targetFilePath);
|
||||
|
||||
// Deploy related files
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "index.ts", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "connector.ts", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "package.json", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, "tsconfig.json", "ElectronHostHook.");
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(targetFilePath, ".gitignore", "ElectronHostHook.");
|
||||
|
||||
// npm for typescript compiler etc.
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", targetFilePath);
|
||||
|
||||
// run typescript compiler
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"npx tsc -p ../../", targetFilePath);
|
||||
|
||||
// search .csproj
|
||||
Console.WriteLine($"Search your .csproj to add configure CopyToPublishDirectory to 'Never'");
|
||||
var projectFile = Directory.EnumerateFiles(currentDirectory, "*.csproj", SearchOption.TopDirectoryOnly).FirstOrDefault();
|
||||
|
||||
Console.WriteLine($"Found your .csproj: {projectFile} - check for existing CopyToPublishDirectory setting or update it.");
|
||||
|
||||
if (!EditCsProj(projectFile)) return false;
|
||||
|
||||
Console.WriteLine($"Everything done - happy electronizing with your custom npm packages!");
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// ToDo: Cleanup this copy/past code.
|
||||
private static bool EditCsProj(string projectFile)
|
||||
{
|
||||
using (var stream = File.Open(projectFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
|
||||
{
|
||||
var xmlDocument = XDocument.Load(stream);
|
||||
|
||||
var projectElement = xmlDocument.Descendants("Project").FirstOrDefault();
|
||||
if (projectElement == null || projectElement.Attribute("Sdk")?.Value != "Microsoft.NET.Sdk.Web")
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Project file is not a compatible type of 'Microsoft.NET.Sdk.Web'. Your project: {projectElement?.Attribute("Sdk")?.Value}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string itemGroupXmlString = "<ItemGroup>" +
|
||||
"<Content Update=\"ElectronHostHook\\**\\*.*\">" +
|
||||
"<CopyToPublishDirectory>Never</CopyToPublishDirectory>" +
|
||||
"</Content>" +
|
||||
"</ItemGroup>";
|
||||
|
||||
var newItemGroupForConfig = XElement.Parse(itemGroupXmlString);
|
||||
xmlDocument.Root.Add(newItemGroupForConfig);
|
||||
|
||||
stream.SetLength(0);
|
||||
stream.Position = 0;
|
||||
|
||||
var xws = new XmlWriterSettings
|
||||
{
|
||||
OmitXmlDeclaration = true,
|
||||
Indent = true
|
||||
};
|
||||
using (XmlWriter xw = XmlWriter.Create(stream, xws))
|
||||
{
|
||||
xmlDocument.Save(xw);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Console.WriteLine($"Publish setting added in csproj!");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.CLI.Commands.Actions;
|
||||
@@ -11,7 +12,18 @@ namespace ElectronNET.CLI.Commands
|
||||
{
|
||||
public const string COMMAND_NAME = "build";
|
||||
public const string COMMAND_DESCRIPTION = "Build your Electron Application.";
|
||||
public const string COMMAND_ARGUMENTS = "<Platform> to build (default is current OS, possible values are: win,osx,linux)";
|
||||
public static string COMMAND_ARGUMENTS = "Needed: '/target' with params 'win/osx/linux' to build for a typical app or use 'custom' and specify .NET Core build config & electron build config" + Environment.NewLine +
|
||||
" for custom target, check .NET Core RID Catalog and Electron build target/" + Environment.NewLine +
|
||||
" e.g. '/target win' or '/target custom \"win7-x86;win32\"'" + Environment.NewLine +
|
||||
"Optional: '/dotnet-configuration' with the desired .NET Core build config e.g. release or debug. Default = Release" + Environment.NewLine +
|
||||
"Optional: '/electron-arch' to specify the resulting electron processor architecture (e.g. ia86 for x86 builds). Be aware to use the '/target custom' param as well!" + Environment.NewLine +
|
||||
"Optional: '/electron-params' specify any other valid parameter, which will be routed to the electron-packager." + Environment.NewLine +
|
||||
"Optional: '/relative-path' to specify output a subdirectory for output." + Environment.NewLine +
|
||||
"Optional: '/absolute-path to specify and absolute path for output." + Environment.NewLine +
|
||||
"Optional: '/package-json' to specify a custom package.json file." + Environment.NewLine +
|
||||
"Optional: '/install-modules' to force node module install. Implied by '/package-json'" + Environment.NewLine +
|
||||
"Full example for a 32bit debug build with electron prune: build /target custom win7-x86;win32 /dotnet-configuration Debug /electron-arch ia32 /electron-params \"--prune=true \"";
|
||||
|
||||
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
|
||||
|
||||
private string[] _args;
|
||||
@@ -21,70 +33,166 @@ namespace ElectronNET.CLI.Commands
|
||||
_args = args;
|
||||
}
|
||||
|
||||
private string _paramTarget = "target";
|
||||
private string _paramDotNetConfig = "dotnet-configuration";
|
||||
private string _paramElectronArch = "electron-arch";
|
||||
private string _paramElectronParams = "electron-params";
|
||||
private string _paramOutputDirectory = "relative-path";
|
||||
private string _paramAbsoluteOutput = "absolute-path";
|
||||
private string _paramPackageJson = "package-json";
|
||||
private string _paramForceNodeInstall = "install-modules";
|
||||
private string _manifest = "manifest";
|
||||
private string _paramPublishReadyToRun = "PublishReadyToRun";
|
||||
|
||||
public Task<bool> ExecuteAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
Console.WriteLine("Build Electron Application...");
|
||||
|
||||
string desiredPlatform = "";
|
||||
SimpleCommandLineParser parser = new SimpleCommandLineParser();
|
||||
parser.Parse(_args);
|
||||
|
||||
if (_args.Length > 0)
|
||||
if (!parser.Arguments.ContainsKey(_paramTarget))
|
||||
{
|
||||
desiredPlatform = _args[0];
|
||||
Console.WriteLine($"Error: missing '{_paramTarget}' argument.");
|
||||
Console.WriteLine(COMMAND_ARGUMENTS);
|
||||
return false;
|
||||
}
|
||||
|
||||
var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform);
|
||||
var desiredPlatform = parser.Arguments[_paramTarget][0];
|
||||
string specifiedFromCustom = string.Empty;
|
||||
if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
|
||||
{
|
||||
specifiedFromCustom = parser.Arguments[_paramTarget][1];
|
||||
}
|
||||
|
||||
string configuration = "Release";
|
||||
if (parser.Arguments.ContainsKey(_paramDotNetConfig))
|
||||
{
|
||||
configuration = parser.Arguments[_paramDotNetConfig][0];
|
||||
}
|
||||
|
||||
var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);
|
||||
|
||||
Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}...");
|
||||
|
||||
string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform);
|
||||
|
||||
if (Directory.Exists(tempPath) == false)
|
||||
{
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Directory.Delete(tempPath, true);
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine("Executing dotnet publish in this directory: " + tempPath);
|
||||
|
||||
string tempBinPath = Path.Combine(tempPath, "bin");
|
||||
|
||||
Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}...");
|
||||
Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration...");
|
||||
|
||||
ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} --output \"{tempBinPath}\"", Directory.GetCurrentDirectory());
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
|
||||
Console.WriteLine("Start npm install electron-packager...");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
string publishReadyToRun = "/p:PublishReadyToRun=";
|
||||
if (parser.Arguments.ContainsKey(_paramPublishReadyToRun))
|
||||
{
|
||||
// Works proper on Windows...
|
||||
ProcessHelper.CmdExecute("npm install electron-packager --global", tempPath);
|
||||
}
|
||||
publishReadyToRun += parser.Arguments[_paramPublishReadyToRun][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: find another solution or document it proper
|
||||
// GH Issue https://github.com/electron-userland/electron-prebuilt/issues/48
|
||||
Console.WriteLine("Electron Packager - make sure you invoke 'sudo npm install electron-packager --global' at " + tempPath + " manually. Sry.");
|
||||
publishReadyToRun += "true";
|
||||
}
|
||||
|
||||
var resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} -c {configuration} --output \"{tempBinPath}\" {publishReadyToRun} --self-contained", Directory.GetCurrentDirectory());
|
||||
|
||||
if (resultCode != 0)
|
||||
{
|
||||
Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
if (parser.Arguments.ContainsKey(_paramPackageJson))
|
||||
{
|
||||
Console.WriteLine("Copying custom package.json.");
|
||||
|
||||
File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true);
|
||||
}
|
||||
|
||||
var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install --production", tempPath);
|
||||
|
||||
Console.WriteLine("ElectronHostHook handling started...");
|
||||
|
||||
string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
|
||||
|
||||
if (Directory.Exists(electronhosthookDir))
|
||||
{
|
||||
string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
|
||||
DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List<string>() { "node_modules" });
|
||||
|
||||
Console.WriteLine("Start npm install for hosthooks...");
|
||||
ProcessHelper.CmdExecute("npm install", hosthookDir);
|
||||
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
|
||||
}
|
||||
|
||||
Console.WriteLine("Build Electron Desktop Application...");
|
||||
|
||||
// Specifying an absolute path supercedes a relative path
|
||||
string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop");
|
||||
if (parser.Arguments.ContainsKey(_paramAbsoluteOutput))
|
||||
{
|
||||
buildPath = parser.Arguments[_paramAbsoluteOutput][0];
|
||||
}
|
||||
else if (parser.Arguments.ContainsKey(_paramOutputDirectory))
|
||||
{
|
||||
buildPath = Path.Combine(Directory.GetCurrentDirectory(),parser.Arguments[_paramOutputDirectory][0]);
|
||||
}
|
||||
|
||||
Console.WriteLine("Executing electron magic in this directory: " + buildPath);
|
||||
|
||||
// ToDo: Need a solution for --asar support
|
||||
string electronArch = "x64";
|
||||
if (parser.Arguments.ContainsKey(_paramElectronArch))
|
||||
{
|
||||
electronArch = parser.Arguments[_paramElectronArch][0];
|
||||
}
|
||||
|
||||
string electronParams = "";
|
||||
if (parser.Arguments.ContainsKey(_paramElectronParams))
|
||||
{
|
||||
electronParams = parser.Arguments[_paramElectronParams][0];
|
||||
}
|
||||
|
||||
// ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :)
|
||||
Console.WriteLine("Create electron-builder configuration file...");
|
||||
|
||||
string manifestFileName = "electron.manifest.json";
|
||||
|
||||
if(parser.Arguments.ContainsKey(_manifest))
|
||||
{
|
||||
manifestFileName = parser.Arguments[_manifest].First();
|
||||
}
|
||||
|
||||
ProcessHelper.CmdExecute($"node build-helper.js " + manifestFileName, tempPath);
|
||||
|
||||
Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
|
||||
ProcessHelper.CmdExecute($"electron-packager . --platform={platformInfo.ElectronPackerPlatform} --arch=x64 --out=\"{buildPath}\" --overwrite", tempPath);
|
||||
ProcessHelper.CmdExecute($"npx electron-builder . --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=8.2.3 {electronParams}", tempPath);
|
||||
|
||||
Console.WriteLine("... done");
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
@@ -17,26 +16,30 @@ namespace ElectronNET.CLI.Commands
|
||||
public const string COMMAND_ARGUMENTS = "<Path> from ASP.NET Core Project.";
|
||||
public static IList<CommandOption> CommandOptions { get; set; } = new List<CommandOption>();
|
||||
|
||||
private const string ConfigName = "electron.manifest.json";
|
||||
|
||||
private string[] _args;
|
||||
private static SimpleCommandLineParser _parser = new SimpleCommandLineParser();
|
||||
private static string ConfigName = "electron.manifest.json";
|
||||
private const string DefaultConfigFileName = "electron.manifest.json";
|
||||
|
||||
public InitCommand(string[] args)
|
||||
{
|
||||
_args = args;
|
||||
_parser.Parse(args);
|
||||
}
|
||||
|
||||
private static string _aspCoreProjectPath = "project-path";
|
||||
private static string _manifest = "manifest";
|
||||
|
||||
public Task<bool> ExecuteAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
string aspCoreProjectPath = "";
|
||||
|
||||
if (_args.Length > 0)
|
||||
if (_parser.Arguments.ContainsKey(_aspCoreProjectPath))
|
||||
{
|
||||
if (Directory.Exists(_args[0]))
|
||||
string projectPath = _parser.Arguments[_aspCoreProjectPath].First();
|
||||
if (Directory.Exists(projectPath))
|
||||
{
|
||||
aspCoreProjectPath = _args[0];
|
||||
aspCoreProjectPath = projectPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -46,7 +49,15 @@ namespace ElectronNET.CLI.Commands
|
||||
|
||||
var currentDirectory = aspCoreProjectPath;
|
||||
|
||||
Console.WriteLine("Adding our config file to your project...");
|
||||
if(_parser.Arguments.ContainsKey(_manifest))
|
||||
{
|
||||
ConfigName = "electron.manifest." + _parser.Arguments[_manifest].First() + ".json";
|
||||
Console.WriteLine($"Adding your custom {ConfigName} config file to your project...");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Adding our config file to your project...");
|
||||
}
|
||||
|
||||
var targetFilePath = Path.Combine(currentDirectory, ConfigName);
|
||||
|
||||
@@ -57,7 +68,7 @@ namespace ElectronNET.CLI.Commands
|
||||
}
|
||||
|
||||
// Deploy config file
|
||||
EmbeddedFileHelper.DeployEmbeddedFile(currentDirectory, ConfigName);
|
||||
EmbeddedFileHelper.DeployEmbeddedFileToTargetFile(currentDirectory, DefaultConfigFileName, ConfigName);
|
||||
|
||||
// search .csproj
|
||||
Console.WriteLine($"Search your .csproj to add the needed {ConfigName}...");
|
||||
@@ -100,15 +111,41 @@ namespace ElectronNET.CLI.Commands
|
||||
|
||||
string launchSettingText = File.ReadAllText(launchSettingFile);
|
||||
|
||||
if (launchSettingText.Contains("electronize start") == false)
|
||||
if(_parser.Arguments.ContainsKey(_manifest))
|
||||
{
|
||||
string manifestName = _parser.Arguments[_manifest].First();
|
||||
|
||||
if(launchSettingText.Contains("start /manifest " + ConfigName) == false)
|
||||
{
|
||||
StringBuilder debugProfileBuilder = new StringBuilder();
|
||||
debugProfileBuilder.AppendLine("profiles\": {");
|
||||
debugProfileBuilder.AppendLine(" \"Electron.NET App - " + manifestName + "\": {");
|
||||
debugProfileBuilder.AppendLine(" \"commandName\": \"Executable\",");
|
||||
debugProfileBuilder.AppendLine(" \"executablePath\": \"electronize\",");
|
||||
debugProfileBuilder.AppendLine(" \"commandLineArgs\": \"start /manifest " + ConfigName + "\",");
|
||||
debugProfileBuilder.AppendLine(" \"workingDirectory\": \".\"");
|
||||
debugProfileBuilder.AppendLine(" },");
|
||||
|
||||
launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString());
|
||||
File.WriteAllText(launchSettingFile, launchSettingText);
|
||||
|
||||
Console.WriteLine($"Debug profile added!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Debug profile already existing");
|
||||
}
|
||||
}
|
||||
else if (launchSettingText.Contains("\"executablePath\": \"electronize\"") == false)
|
||||
{
|
||||
StringBuilder debugProfileBuilder = new StringBuilder();
|
||||
debugProfileBuilder.AppendLine("profiles\": {");
|
||||
debugProfileBuilder.AppendLine("\"Electron.NET App\": {");
|
||||
debugProfileBuilder.AppendLine("\"commandName\": \"Executable\",");
|
||||
debugProfileBuilder.AppendLine("\"executablePath\": \"C:\\\\Program Files\\\\dotnet\\\\dotnet.exe\",");
|
||||
debugProfileBuilder.AppendLine("\"commandLineArgs\": \"electronize start\"");
|
||||
debugProfileBuilder.AppendLine("},");
|
||||
debugProfileBuilder.AppendLine(" \"Electron.NET App\": {");
|
||||
debugProfileBuilder.AppendLine(" \"commandName\": \"Executable\",");
|
||||
debugProfileBuilder.AppendLine(" \"executablePath\": \"electronize\",");
|
||||
debugProfileBuilder.AppendLine(" \"commandLineArgs\": \"start\",");
|
||||
debugProfileBuilder.AppendLine(" \"workingDirectory\": \".\"");
|
||||
debugProfileBuilder.AppendLine(" },");
|
||||
|
||||
launchSettingText = launchSettingText.Replace("profiles\": {", debugProfileBuilder.ToString());
|
||||
File.WriteAllText(launchSettingFile, launchSettingText);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.CLI.Commands.Actions;
|
||||
@@ -22,19 +22,29 @@ namespace ElectronNET.CLI.Commands
|
||||
_args = args;
|
||||
}
|
||||
|
||||
private string _aspCoreProjectPath = "project-path";
|
||||
private string _arguments = "args";
|
||||
private string _manifest = "manifest";
|
||||
private string _clearCache = "clear-cache";
|
||||
private string _paramPublishReadyToRun = "PublishReadyToRun";
|
||||
|
||||
public Task<bool> ExecuteAsync()
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
Console.WriteLine("Start Electron Desktop Application...");
|
||||
|
||||
SimpleCommandLineParser parser = new SimpleCommandLineParser();
|
||||
parser.Parse(_args);
|
||||
|
||||
string aspCoreProjectPath = "";
|
||||
|
||||
if (_args.Length > 0)
|
||||
if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
|
||||
{
|
||||
if (Directory.Exists(_args[0]))
|
||||
string projectPath = parser.Arguments[_aspCoreProjectPath].First();
|
||||
if (Directory.Exists(projectPath))
|
||||
{
|
||||
aspCoreProjectPath = _args[0];
|
||||
aspCoreProjectPath = projectPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -48,43 +58,98 @@ namespace ElectronNET.CLI.Commands
|
||||
Directory.CreateDirectory(tempPath);
|
||||
}
|
||||
|
||||
var platformInfo = GetTargetPlatformInformation.Do(string.Empty);
|
||||
var platformInfo = GetTargetPlatformInformation.Do(string.Empty, string.Empty);
|
||||
|
||||
string tempBinPath = Path.Combine(tempPath, "bin");
|
||||
ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} --output \"{tempBinPath}\"", aspCoreProjectPath);
|
||||
var resultCode = 0;
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
|
||||
var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
if (Directory.Exists(checkForNodeModulesDirPath) == false)
|
||||
string publishReadyToRun = "/p:PublishReadyToRun=";
|
||||
if (parser.Arguments.ContainsKey(_paramPublishReadyToRun))
|
||||
{
|
||||
Console.WriteLine("node_modules missing in: " + checkForNodeModulesDirPath);
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
publishReadyToRun += parser.Arguments[_paramPublishReadyToRun][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Skip npm install, because node_modules directory exists in: " + checkForNodeModulesDirPath);
|
||||
publishReadyToRun += "true";
|
||||
}
|
||||
|
||||
if (parser != null && !parser.Arguments.ContainsKey("watch"))
|
||||
{
|
||||
resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} --output \"{tempBinPath}\" {publishReadyToRun} --no-self-contained", aspCoreProjectPath);
|
||||
}
|
||||
|
||||
if (resultCode != 0)
|
||||
{
|
||||
Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
DeployEmbeddedElectronFiles.Do(tempPath);
|
||||
|
||||
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
|
||||
|
||||
Console.WriteLine("node_modules missing in: " + nodeModulesDirPath);
|
||||
|
||||
Console.WriteLine("Start npm install...");
|
||||
ProcessHelper.CmdExecute("npm install", tempPath);
|
||||
|
||||
Console.WriteLine("ElectronHostHook handling started...");
|
||||
|
||||
string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
|
||||
|
||||
if (Directory.Exists(electronhosthookDir))
|
||||
{
|
||||
string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
|
||||
DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List<string>() { "node_modules" });
|
||||
|
||||
Console.WriteLine("Start npm install for typescript & hosthooks...");
|
||||
ProcessHelper.CmdExecute("npm install", hosthookDir);
|
||||
|
||||
// ToDo: Not sure if this runs under linux/macos
|
||||
ProcessHelper.CmdExecute(@"npx tsc -p ../../ElectronHostHook", tempPath);
|
||||
}
|
||||
|
||||
string arguments = "";
|
||||
|
||||
if (parser.Arguments.ContainsKey(_arguments))
|
||||
{
|
||||
arguments = string.Join(' ', parser.Arguments[_arguments]);
|
||||
}
|
||||
|
||||
if (parser.Arguments.ContainsKey(_manifest))
|
||||
{
|
||||
arguments += " --manifest=" + parser.Arguments[_manifest].First();
|
||||
}
|
||||
|
||||
if (parser.Arguments.ContainsKey(_clearCache))
|
||||
{
|
||||
arguments += " --clear-cache=true";
|
||||
}
|
||||
|
||||
if (parser.Arguments.ContainsKey("watch"))
|
||||
{
|
||||
arguments += " --watch=true";
|
||||
}
|
||||
|
||||
string path = Path.Combine(tempPath, "node_modules", ".bin");
|
||||
|
||||
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
if (isWindows)
|
||||
{
|
||||
Console.WriteLine("Invoke electron.cmd - in dir: " + path);
|
||||
ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js""", path);
|
||||
ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Invoke electron - in dir: " + path);
|
||||
ProcessHelper.CmdExecute(@"./electron ""../../main.js""", path);
|
||||
ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<AssemblyName>dotnet-electronize</AssemblyName>
|
||||
|
||||
<ToolCommandName>electronize</ToolCommandName>
|
||||
|
||||
<PackageType>DotnetCliTool</PackageType>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageOutputPath>..\artifacts</PackageOutputPath>
|
||||
<PackageId>ElectronNET.CLI</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<!-- Version 99 is just set for local development stuff to avoid a conflict with "real" packages on NuGet.org -->
|
||||
<Version>99.0.0.0</Version>
|
||||
<Authors>Gregor Biswanger, Robert Muehsig</Authors>
|
||||
<Product>Electron.NET</Product>
|
||||
<Company />
|
||||
<Description>Building cross platform electron based desktop apps with .NET Core and ASP.NET NET Core.
|
||||
This package contains the dotnet tooling to electronize your application.</Description>
|
||||
<PackageLicenseUrl>https://github.com/ElectronNET/Electron.NET/blob/master/LICENSE</PackageLicenseUrl>
|
||||
<Description>
|
||||
Building cross platform electron based desktop apps with .NET Core and ASP.NET Core.
|
||||
This package contains the dotnet tooling to electronize your application.
|
||||
</Description>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/ElectronNET/Electron.NET/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/ElectronNET/Electron.NET/</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<PackageTags>electron aspnetcore</PackageTags>
|
||||
<PackageReleaseNotes>Changelog: https://github.com/ElectronNET/Electron.NET/blob/master/Changelog.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/ElectronNET/Electron.NET/master/assets/images/electron.net-logo-square.png</PackageIconUrl>
|
||||
<PackageIcon>PackageIcon.png</PackageIcon>
|
||||
<PackAsTool>true</PackAsTool>
|
||||
<StartupObject></StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -28,52 +41,43 @@ This package contains the dotnet tooling to electronize your application.</Descr
|
||||
<None Remove="ElectronHost\package.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile></DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PackageIcon.png" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile></DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\electron.manifest.json" Link="ElectronHost\electron.manifest.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\package-lock.json" Link="ElectronHost\package-lock.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\package.json" Link="ElectronHost\package.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\main.js" Link="ElectronHost\main.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\build-helper.js" Link="ElectronHost\build-helper.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\ipc.js" Link="ElectronHost\api\ipc.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\index.ts" Link="ElectronHost\ElectronHostHook\index.ts" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\connector.ts" Link="ElectronHost\ElectronHostHook\connector.ts" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\tsconfig.json" Link="ElectronHost\ElectronHostHook\tsconfig.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\package.json" Link="ElectronHost\ElectronHostHook\package.json" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\ElectronHostHook\.gitignore" Link="ElectronHost\ElectronHostHook\.gitignore" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\splashscreen\index.html" Link="ElectronHost\splashscreen\index.html" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\app.js" Link="ElectronHost\api\app.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\browserWindows.js" Link="ElectronHost\api\browserWindows.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\commandLine.js" Link="ElectronHost\api\commandLine.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\dialog.js" Link="ElectronHost\api\dialog.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\menu.js" Link="ElectronHost\api\menu.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\notification.js" Link="ElectronHost\api\notification.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\tray.js" Link="ElectronHost\api\tray.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\globalShortcut.js" Link="ElectronHost\api\globalShortcut.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\screen.js" Link="ElectronHost\api\screen.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\shell.js" Link="ElectronHost\api\shell.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\webContents.js" Link="ElectronHost\api\webContents.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\clipboard.js" Link="ElectronHost\api\clipboard.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\autoUpdater.js" Link="ElectronHost\api\autoUpdater.js" />
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\browserView.js" Link="ElectronHost\api\browserView.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\ElectronNET.Host\api\clipboard.js" Link="ElectronHost\api\clipboard.js" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' == 'Windows_NT'">
|
||||
<Exec Command="$(ProjectDir)devCleanup.cmd" IgnoreExitCode="true" />
|
||||
|
||||
@@ -29,5 +29,19 @@ namespace ElectronNET.CLI
|
||||
streamFromEmbeddedFile.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeployEmbeddedFileToTargetFile(string targetPath, string embeddedFile, string targetFile, string namespacePath = "")
|
||||
{
|
||||
using (var fileStream = File.Create(Path.Combine(targetPath, targetFile)))
|
||||
{
|
||||
var streamFromEmbeddedFile = GetTestResourceFileStream("ElectronHost." + namespacePath + embeddedFile);
|
||||
if (streamFromEmbeddedFile == null)
|
||||
{
|
||||
Console.WriteLine("Error: Couldn't find embedded file: " + embeddedFile);
|
||||
}
|
||||
|
||||
streamFromEmbeddedFile.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
ElectronNET.CLI/PackageIcon.png
Normal file
BIN
ElectronNET.CLI/PackageIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -1,12 +1,15 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ElectronNET.CLI
|
||||
{
|
||||
public class ProcessHelper
|
||||
{
|
||||
public static void CmdExecute(string command, string workingDirectoryPath, bool output = true, bool waitForExit = true)
|
||||
private readonly static Regex ErrorRegex = new Regex(@"\berror\b", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
public static int CmdExecute(string command, string workingDirectoryPath, bool output = true, bool waitForExit = true)
|
||||
{
|
||||
using (Process cmd = new Process())
|
||||
{
|
||||
@@ -28,10 +31,50 @@ namespace ElectronNET.CLI
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.WorkingDirectory = workingDirectoryPath;
|
||||
|
||||
int returnCode = 0;
|
||||
|
||||
if (output)
|
||||
{
|
||||
cmd.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
|
||||
cmd.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
|
||||
cmd.OutputDataReceived += (s, e) =>
|
||||
{
|
||||
// (sometimes error messages are only visbile here)
|
||||
// poor mans solution, we just seek for the term 'error'
|
||||
|
||||
// we can't just use cmd.ExitCode, because
|
||||
// we delegate it to cmd.exe, which runs fine
|
||||
// but we can catch any error here and return
|
||||
// 1 if something fails
|
||||
if (e != null && string.IsNullOrWhiteSpace(e.Data) == false)
|
||||
{
|
||||
if (ErrorRegex.IsMatch(e.Data))
|
||||
{
|
||||
returnCode = 1;
|
||||
}
|
||||
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
|
||||
};
|
||||
cmd.ErrorDataReceived += (s, e) =>
|
||||
{
|
||||
// poor mans solution, we just seek for the term 'error'
|
||||
|
||||
// we can't just use cmd.ExitCode, because
|
||||
// we delegate it to cmd.exe, which runs fine
|
||||
// but we can catch any error here and return
|
||||
// 1 if something fails
|
||||
if (e != null && string.IsNullOrWhiteSpace(e.Data) == false)
|
||||
{
|
||||
if (ErrorRegex.IsMatch(e.Data))
|
||||
{
|
||||
returnCode = 1;
|
||||
}
|
||||
|
||||
Console.WriteLine(e.Data);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
cmd.Start();
|
||||
@@ -46,6 +89,8 @@ namespace ElectronNET.CLI
|
||||
{
|
||||
cmd.WaitForExit();
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Text;
|
||||
|
||||
namespace ElectronNET.CLI
|
||||
{
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
@@ -32,6 +31,9 @@ namespace ElectronNET.CLI
|
||||
case InitCommand.COMMAND_NAME:
|
||||
command = new InitCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
case AddCommand.COMMAND_NAME:
|
||||
command = new AddCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
case VersionCommand.COMMAND_NAME:
|
||||
command = new VersionCommand(args.Skip(1).ToArray());
|
||||
break;
|
||||
@@ -71,7 +73,7 @@ namespace ElectronNET.CLI
|
||||
sb.Append($" ({version})");
|
||||
}
|
||||
Console.WriteLine(sb.ToString());
|
||||
Console.WriteLine("Project Home: https://github.com/GregorBiswanger/ElectronNET");
|
||||
Console.WriteLine("Project Home: https://github.com/ElectronNET/Electron.NET");
|
||||
Console.WriteLine("\t");
|
||||
}
|
||||
|
||||
@@ -84,15 +86,20 @@ namespace ElectronNET.CLI
|
||||
Console.WriteLine($"\t{StartElectronCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {StartElectronCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to build the Electron Application:");
|
||||
Console.WriteLine("Command to build the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{BuildCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {BuildCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to init the Electron Application:");
|
||||
Console.WriteLine("Command to init the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{InitCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {InitCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Command to add a custom npm packages to the Electron Application:");
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine($"\t{AddCommand.COMMAND_NAME.PadRight(NAME_WIDTH)} {AddCommand.COMMAND_DESCRIPTION}");
|
||||
|
||||
Console.WriteLine("\t");
|
||||
Console.WriteLine("Commands to see the current ElectronNET version number:");
|
||||
Console.WriteLine("\t");
|
||||
@@ -117,6 +124,9 @@ namespace ElectronNET.CLI
|
||||
case InitCommand.COMMAND_NAME:
|
||||
PrintUsage(InitCommand.COMMAND_NAME, InitCommand.COMMAND_DESCRIPTION, InitCommand.CommandOptions, InitCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
case AddCommand.COMMAND_NAME:
|
||||
PrintUsage(AddCommand.COMMAND_NAME, AddCommand.COMMAND_DESCRIPTION, AddCommand.CommandOptions, AddCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
case VersionCommand.COMMAND_NAME:
|
||||
PrintUsage(VersionCommand.COMMAND_NAME, VersionCommand.COMMAND_DESCRIPTION, VersionCommand.CommandOptions, VersionCommand.COMMAND_ARGUMENTS);
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"ElectronNET.CLI": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "build \"C:\\Users\\Gregor\\Documents\\Visual Studio 2017\\Projects\\ElectronNET\\ElectronNET.WebApp\""
|
||||
"commandLineArgs": "start /project-path \"C:\\Users\\Rizvi\\source\\repos\\Electron.NET\\ElectronNET.WebApp\" /watch"
|
||||
}
|
||||
}
|
||||
}
|
||||
38
ElectronNET.CLI/SimpleCommandLineParser.cs
Normal file
38
ElectronNET.CLI/SimpleCommandLineParser.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ElectronNET.CLI
|
||||
{
|
||||
public class SimpleCommandLineParser
|
||||
{
|
||||
public SimpleCommandLineParser()
|
||||
{
|
||||
Arguments = new Dictionary<string, string[]>();
|
||||
}
|
||||
public IDictionary<string, string[]> Arguments { get; private set; }
|
||||
public void Parse(string[] args)
|
||||
{
|
||||
var currentName = "";
|
||||
var values = new List<string>();
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (arg.StartsWith("/"))
|
||||
{
|
||||
if (currentName != "")
|
||||
Arguments[currentName] = values.ToArray();
|
||||
values.Clear();
|
||||
currentName = arg.Substring(1);
|
||||
}
|
||||
else if (currentName == "")
|
||||
Arguments[arg] = new string[0];
|
||||
else
|
||||
values.Add(arg);
|
||||
}
|
||||
if (currentName != "")
|
||||
Arguments[currentName] = values.ToArray();
|
||||
}
|
||||
public bool Contains(string name)
|
||||
{
|
||||
return Arguments.ContainsKey(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
ElectronNET.Host/.gitignore
vendored
Normal file
2
ElectronNET.Host/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
bin
|
||||
22
ElectronNET.Host/.vscode/launch.json
vendored
22
ElectronNET.Host/.vscode/launch.json
vendored
@@ -8,9 +8,25 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Electron App",
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"runtimeExecutable": "${workspaceFolder}\\node_modules\\.bin\\electron",
|
||||
"sourceMaps": true
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
|
||||
"program": "${workspaceFolder}/main.js",
|
||||
"sourceMaps": true,
|
||||
"args": [
|
||||
"--test=true",
|
||||
"--blub=wuhuu"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch build-helper",
|
||||
"program": "${workspaceFolder}/build-helper.js",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"args": [
|
||||
"electron.manifest.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
2
ElectronNET.Host/.vscode/tasks.json
vendored
2
ElectronNET.Host/.vscode/tasks.json
vendored
@@ -1,6 +1,4 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
|
||||
91
ElectronNET.Host/ElectronHostHook/.gitignore
vendored
Normal file
91
ElectronNET.Host/ElectronHostHook/.gitignore
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
# Created by https://www.gitignore.io/api/node
|
||||
# Edit at https://www.gitignore.io/?templates=node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# End of https://www.gitignore.io/api/node
|
||||
27
ElectronNET.Host/ElectronHostHook/connector.js
Normal file
27
ElectronNET.Host/ElectronHostHook/connector.js
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Connector {
|
||||
constructor(socket,
|
||||
// @ts-ignore
|
||||
app) {
|
||||
this.socket = socket;
|
||||
this.app = app;
|
||||
}
|
||||
on(key, javaScriptCode) {
|
||||
this.socket.on(key, (...args) => {
|
||||
const id = args.pop();
|
||||
try {
|
||||
javaScriptCode(...args, (data) => {
|
||||
if (data) {
|
||||
this.socket.emit(`${key}Complete${id}`, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
this.socket.emit(`${key}Error${id}`, `Host Hook Exception`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.Connector = Connector;
|
||||
//# sourceMappingURL=connector.js.map
|
||||
1
ElectronNET.Host/ElectronHostHook/connector.js.map
Normal file
1
ElectronNET.Host/ElectronHostHook/connector.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"connector.js","sourceRoot":"","sources":["connector.ts"],"names":[],"mappings":";;AAAA,MAAa,SAAS;IAClB,YAAoB,MAAuB;IACvC,aAAa;IACN,GAAiB;QAFR,WAAM,GAAN,MAAM,CAAiB;QAEhC,QAAG,GAAH,GAAG,CAAc;IAAI,CAAC;IAEjC,EAAE,CAAC,GAAW,EAAE,cAAwB;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE;YACnC,MAAM,EAAE,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;YAE9B,IAAI;gBACA,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC7B,IAAI,IAAI,EAAE;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;qBACjD;gBACL,CAAC,CAAC,CAAC;aACN;YAAC,OAAO,KAAK,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,QAAQ,EAAE,EAAE,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC;aACtE;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AApBD,8BAoBC"}
|
||||
21
ElectronNET.Host/ElectronHostHook/connector.ts
Normal file
21
ElectronNET.Host/ElectronHostHook/connector.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export class Connector {
|
||||
constructor(private socket: SocketIO.Socket,
|
||||
// @ts-ignore
|
||||
public app: Electron.App) { }
|
||||
|
||||
on(key: string, javaScriptCode: Function): void {
|
||||
this.socket.on(key, (...args: any[]) => {
|
||||
const id: string = args.pop();
|
||||
|
||||
try {
|
||||
javaScriptCode(...args, (data) => {
|
||||
if (data) {
|
||||
this.socket.emit(`${key}Complete${id}`, data);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this.socket.emit(`${key}Error${id}`, `Host Hook Exception`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
14
ElectronNET.Host/ElectronHostHook/index.js
Normal file
14
ElectronNET.Host/ElectronHostHook/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const connector_1 = require("./connector");
|
||||
class HookService extends connector_1.Connector {
|
||||
constructor(socket, app) {
|
||||
super(socket, app);
|
||||
this.app = app;
|
||||
}
|
||||
onHostReady() {
|
||||
// execute your own JavaScript Host logic here
|
||||
}
|
||||
}
|
||||
exports.HookService = HookService;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
ElectronNET.Host/ElectronHostHook/index.js.map
Normal file
1
ElectronNET.Host/ElectronHostHook/index.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;AAEA,2CAAwC;AAExC,MAAa,WAAY,SAAQ,qBAAS;IACtC,YAAY,MAAuB,EAAS,GAAiB;QACzD,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QADqB,QAAG,GAAH,GAAG,CAAc;IAE7D,CAAC;IAED,WAAW;QACP,8CAA8C;IAClD,CAAC;CACJ;AARD,kCAQC"}
|
||||
14
ElectronNET.Host/ElectronHostHook/index.ts
Normal file
14
ElectronNET.Host/ElectronHostHook/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// @ts-ignore
|
||||
import * as Electron from "electron";
|
||||
import { Connector } from "./connector";
|
||||
|
||||
export class HookService extends Connector {
|
||||
constructor(socket: SocketIO.Socket, public app: Electron.App) {
|
||||
super(socket, app);
|
||||
}
|
||||
|
||||
onHostReady(): void {
|
||||
// execute your own JavaScript Host logic here
|
||||
}
|
||||
}
|
||||
|
||||
19
ElectronNET.Host/ElectronHostHook/package.json
Normal file
19
ElectronNET.Host/ElectronHostHook/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "electron-host-hook",
|
||||
"version": "1.0.0",
|
||||
"description": "Connector for Electron.NET projects.",
|
||||
"repository": {
|
||||
"url": "https://github.com/ElectronNET/Electron.NET"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Gregor Biswanger",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/socket.io": "^2.1.2",
|
||||
"typescript": "^3.4.5"
|
||||
}
|
||||
}
|
||||
11
ElectronNET.Host/ElectronHostHook/tsconfig.json
Normal file
11
ElectronNET.Host/ElectronHostHook/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"target": "es2015"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,77 +1,86 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
module.exports = function (socket, app) {
|
||||
socket.on('register-app-window-all-closed-event', function (id) {
|
||||
app.on('window-all-closed', function () {
|
||||
socket.emit('app-window-all-closed' + id);
|
||||
let isQuitWindowAllClosed = true, electronSocket;
|
||||
module.exports = (socket, app) => {
|
||||
electronSocket = socket;
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin' &&
|
||||
isQuitWindowAllClosed) {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
socket.on('quit-app-window-all-closed-event', (quit) => {
|
||||
isQuitWindowAllClosed = quit;
|
||||
});
|
||||
socket.on('register-app-window-all-closed-event', (id) => {
|
||||
app.on('window-all-closed', () => {
|
||||
electronSocket.emit('app-window-all-closed' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-before-quit-event', function (id) {
|
||||
app.on('before-quit', function () {
|
||||
socket.emit('app-before-quit' + id);
|
||||
socket.on('register-app-before-quit-event', (id) => {
|
||||
app.on('before-quit', (event) => {
|
||||
event.preventDefault();
|
||||
electronSocket.emit('app-before-quit' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-will-quit-event', function (id) {
|
||||
app.on('will-quit', function () {
|
||||
socket.emit('app-will-quit' + id);
|
||||
socket.on('register-app-will-quit-event', (id) => {
|
||||
app.on('will-quit', (event) => {
|
||||
event.preventDefault();
|
||||
electronSocket.emit('app-will-quit' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-quit-event', function (id) {
|
||||
app.on('quit', function () {
|
||||
socket.emit('app-quit' + id);
|
||||
socket.on('register-app-browser-window-blur-event', (id) => {
|
||||
app.on('browser-window-blur', () => {
|
||||
electronSocket.emit('app-browser-window-blur' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-browser-window-blur-event', function (id) {
|
||||
app.on('browser-window-blur', function () {
|
||||
socket.emit('app-browser-window-blur' + id);
|
||||
socket.on('register-app-browser-window-focus-event', (id) => {
|
||||
app.on('browser-window-focus', () => {
|
||||
electronSocket.emit('app-browser-window-focus' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-browser-window-focus-event', function (id) {
|
||||
app.on('browser-window-focus', function () {
|
||||
socket.emit('app-browser-window-focus' + id);
|
||||
socket.on('register-app-browser-window-created-event', (id) => {
|
||||
app.on('browser-window-created', () => {
|
||||
electronSocket.emit('app-browser-window-created' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-browser-window-created-event', function (id) {
|
||||
app.on('browser-window-created', function () {
|
||||
socket.emit('app-browser-window-created' + id);
|
||||
socket.on('register-app-web-contents-created-event', (id) => {
|
||||
app.on('web-contents-created', () => {
|
||||
electronSocket.emit('app-web-contents-created' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-web-contents-created-event', function (id) {
|
||||
app.on('web-contents-created', function () {
|
||||
socket.emit('app-web-contents-created' + id);
|
||||
socket.on('register-app-accessibility-support-changed-event', (id) => {
|
||||
app.on('accessibility-support-changed', (event, accessibilitySupportEnabled) => {
|
||||
electronSocket.emit('app-accessibility-support-changed' + id, accessibilitySupportEnabled);
|
||||
});
|
||||
});
|
||||
socket.on('register-app-accessibility-support-changed-event', function (id) {
|
||||
app.on('accessibility-support-changed', function (event, accessibilitySupportEnabled) {
|
||||
socket.emit('app-accessibility-support-changed' + id, accessibilitySupportEnabled);
|
||||
});
|
||||
});
|
||||
socket.on('appQuit', function () {
|
||||
socket.on('appQuit', () => {
|
||||
app.quit();
|
||||
});
|
||||
socket.on('appExit', function (exitCode) {
|
||||
if (exitCode === void 0) { exitCode = 0; }
|
||||
socket.on('appExit', (exitCode = 0) => {
|
||||
app.exit(exitCode);
|
||||
});
|
||||
socket.on('appRelaunch', function (options) {
|
||||
socket.on('appRelaunch', (options) => {
|
||||
app.relaunch(options);
|
||||
});
|
||||
socket.on('appFocus', function () {
|
||||
socket.on('appFocus', () => {
|
||||
app.focus();
|
||||
});
|
||||
socket.on('appHide', function () {
|
||||
socket.on('appHide', () => {
|
||||
app.hide();
|
||||
});
|
||||
socket.on('appShow', function () {
|
||||
socket.on('appShow', () => {
|
||||
app.show();
|
||||
});
|
||||
socket.on('appGetAppPath', function () {
|
||||
var path = app.getAppPath();
|
||||
socket.emit('appGetAppPathCompleted', path);
|
||||
socket.on('appGetAppPath', () => {
|
||||
const path = app.getAppPath();
|
||||
electronSocket.emit('appGetAppPathCompleted', path);
|
||||
});
|
||||
socket.on('appGetPath', function (name) {
|
||||
var path = app.getPath(name);
|
||||
socket.emit('appGetPathCompleted', path);
|
||||
socket.on('appGetPath', (name) => {
|
||||
const path = app.getPath(name);
|
||||
electronSocket.emit('appGetPathCompleted', path);
|
||||
});
|
||||
// const nativeImages = {};
|
||||
// function addNativeImage(nativeImage: Electron.NativeImage) {
|
||||
@@ -82,166 +91,154 @@ module.exports = function (socket, app) {
|
||||
// nativeImage[indexCount] = nativeImage;
|
||||
// }
|
||||
// }
|
||||
socket.on('appGetFileIcon', function (path, options) {
|
||||
socket.on('appGetFileIcon', async (path, options) => {
|
||||
let error = {};
|
||||
if (options) {
|
||||
app.getFileIcon(path, options, function (error, nativeImage) {
|
||||
socket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
});
|
||||
const nativeImage = await app.getFileIcon(path, options).catch((errorFileIcon) => error = errorFileIcon);
|
||||
electronSocket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
}
|
||||
else {
|
||||
app.getFileIcon(path, function (error, nativeImage) {
|
||||
socket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
});
|
||||
const nativeImage = await app.getFileIcon(path).catch((errorFileIcon) => error = errorFileIcon);
|
||||
electronSocket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
}
|
||||
});
|
||||
socket.on('appSetPath', function (name, path) {
|
||||
socket.on('appSetPath', (name, path) => {
|
||||
app.setPath(name, path);
|
||||
});
|
||||
socket.on('appGetVersion', function () {
|
||||
var version = app.getVersion();
|
||||
socket.emit('appGetVersionCompleted', version);
|
||||
socket.on('appGetVersion', () => {
|
||||
const version = app.getVersion();
|
||||
electronSocket.emit('appGetVersionCompleted', version);
|
||||
});
|
||||
socket.on('appGetName', function () {
|
||||
var name = app.getName();
|
||||
socket.emit('appGetNameCompleted', name);
|
||||
socket.on('appGetName', () => {
|
||||
electronSocket.emit('appGetNameCompleted', app.name);
|
||||
});
|
||||
socket.on('appSetName', function (name) {
|
||||
app.setName(name);
|
||||
socket.on('appSetName', (name) => {
|
||||
app.name = name;
|
||||
});
|
||||
socket.on('appGetLocale', function () {
|
||||
var locale = app.getLocale();
|
||||
socket.emit('appGetLocaleCompleted', locale);
|
||||
socket.on('appGetLocale', () => {
|
||||
const locale = app.getLocale();
|
||||
electronSocket.emit('appGetLocaleCompleted', locale);
|
||||
});
|
||||
socket.on('appAddRecentDocument', function (path) {
|
||||
socket.on('appAddRecentDocument', (path) => {
|
||||
app.addRecentDocument(path);
|
||||
});
|
||||
socket.on('appClearRecentDocuments', function () {
|
||||
socket.on('appClearRecentDocuments', () => {
|
||||
app.clearRecentDocuments();
|
||||
});
|
||||
socket.on('appSetAsDefaultProtocolClient', function (protocol, path, args) {
|
||||
var success = app.setAsDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appSetAsDefaultProtocolClientCompleted', success);
|
||||
socket.on('appSetAsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.setAsDefaultProtocolClient(protocol, path, args);
|
||||
electronSocket.emit('appSetAsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
socket.on('appRemoveAsDefaultProtocolClient', function (protocol, path, args) {
|
||||
var success = app.removeAsDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appRemoveAsDefaultProtocolClientCompleted', success);
|
||||
socket.on('appRemoveAsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.removeAsDefaultProtocolClient(protocol, path, args);
|
||||
electronSocket.emit('appRemoveAsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
socket.on('appIsDefaultProtocolClient', function (protocol, path, args) {
|
||||
var success = app.isDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appIsDefaultProtocolClientCompleted', success);
|
||||
socket.on('appIsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.isDefaultProtocolClient(protocol, path, args);
|
||||
electronSocket.emit('appIsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
socket.on('appSetUserTasks', function (tasks) {
|
||||
var success = app.setUserTasks(tasks);
|
||||
socket.emit('appSetUserTasksCompleted', success);
|
||||
socket.on('appSetUserTasks', (tasks) => {
|
||||
const success = app.setUserTasks(tasks);
|
||||
electronSocket.emit('appSetUserTasksCompleted', success);
|
||||
});
|
||||
socket.on('appGetJumpListSettings', function () {
|
||||
var jumpListSettings = app.getJumpListSettings();
|
||||
socket.emit('appGetJumpListSettingsCompleted', jumpListSettings);
|
||||
socket.on('appGetJumpListSettings', () => {
|
||||
const jumpListSettings = app.getJumpListSettings();
|
||||
electronSocket.emit('appGetJumpListSettingsCompleted', jumpListSettings);
|
||||
});
|
||||
socket.on('appSetJumpList', function (categories) {
|
||||
socket.on('appSetJumpList', (categories) => {
|
||||
app.setJumpList(categories);
|
||||
});
|
||||
socket.on('appMakeSingleInstance', function () {
|
||||
var success = app.makeSingleInstance(function (args, workingDirectory) {
|
||||
socket.emit('newInstanceOpened', [args, workingDirectory]);
|
||||
socket.on('appRequestSingleInstanceLock', () => {
|
||||
app.on('second-instance', (args, workingDirectory) => {
|
||||
electronSocket.emit('secondInstance', [args, workingDirectory]);
|
||||
});
|
||||
socket.emit('appMakeSingleInstanceCompleted', success);
|
||||
const success = app.requestSingleInstanceLock();
|
||||
electronSocket.emit('appRequestSingleInstanceLockCompleted', success);
|
||||
});
|
||||
socket.on('appReleaseSingleInstance', function () {
|
||||
app.releaseSingleInstance();
|
||||
socket.on('appReleaseSingleInstanceLock', () => {
|
||||
app.releaseSingleInstanceLock();
|
||||
});
|
||||
socket.on('appSetUserActivity', function (type, userInfo, webpageURL) {
|
||||
socket.on('appSetUserActivity', (type, userInfo, webpageURL) => {
|
||||
app.setUserActivity(type, userInfo, webpageURL);
|
||||
});
|
||||
socket.on('appGetCurrentActivityType', function () {
|
||||
var activityType = app.getCurrentActivityType();
|
||||
socket.emit('appGetCurrentActivityTypeCompleted', activityType);
|
||||
socket.on('appGetCurrentActivityType', () => {
|
||||
const activityType = app.getCurrentActivityType();
|
||||
electronSocket.emit('appGetCurrentActivityTypeCompleted', activityType);
|
||||
});
|
||||
socket.on('appSetAppUserModelId', function (id) {
|
||||
socket.on('appSetAppUserModelId', (id) => {
|
||||
app.setAppUserModelId(id);
|
||||
});
|
||||
socket.on('appImportCertificate', function (options) {
|
||||
app.importCertificate(options, function (result) {
|
||||
socket.emit('appImportCertificateCompleted', result);
|
||||
socket.on('appImportCertificate', (options) => {
|
||||
app.importCertificate(options, (result) => {
|
||||
electronSocket.emit('appImportCertificateCompleted', result);
|
||||
});
|
||||
});
|
||||
socket.on('appGetAppMetrics', function () {
|
||||
var processMetrics = app.getAppMetrics();
|
||||
socket.emit('appGetAppMetricsCompleted', processMetrics);
|
||||
socket.on('appGetAppMetrics', () => {
|
||||
const processMetrics = app.getAppMetrics();
|
||||
electronSocket.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('appGetGpuFeatureStatus', () => {
|
||||
const gpuFeatureStatus = app.getGPUFeatureStatus();
|
||||
electronSocket.emit('appGetGpuFeatureStatusCompleted', gpuFeatureStatus);
|
||||
});
|
||||
socket.on('appSetBadgeCount', function (count) {
|
||||
var success = app.setBadgeCount(count);
|
||||
socket.emit('appSetBadgeCountCompleted', success);
|
||||
socket.on('appSetBadgeCount', (count) => {
|
||||
const success = app.setBadgeCount(count);
|
||||
electronSocket.emit('appSetBadgeCountCompleted', success);
|
||||
});
|
||||
socket.on('appGetBadgeCount', function () {
|
||||
var count = app.getBadgeCount();
|
||||
socket.emit('appGetBadgeCountCompleted', count);
|
||||
socket.on('appGetBadgeCount', () => {
|
||||
const count = app.getBadgeCount();
|
||||
electronSocket.emit('appGetBadgeCountCompleted', count);
|
||||
});
|
||||
socket.on('appIsUnityRunning', function () {
|
||||
var isUnityRunning = app.isUnityRunning();
|
||||
socket.emit('appIsUnityRunningCompleted', isUnityRunning);
|
||||
socket.on('appIsUnityRunning', () => {
|
||||
const isUnityRunning = app.isUnityRunning();
|
||||
electronSocket.emit('appIsUnityRunningCompleted', isUnityRunning);
|
||||
});
|
||||
socket.on('appGetLoginItemSettings', function (options) {
|
||||
var loginItemSettings = app.getLoginItemSettings(options);
|
||||
socket.emit('appGetLoginItemSettingsCompleted', loginItemSettings);
|
||||
socket.on('appGetLoginItemSettings', (options) => {
|
||||
const loginItemSettings = app.getLoginItemSettings(options);
|
||||
electronSocket.emit('appGetLoginItemSettingsCompleted', loginItemSettings);
|
||||
});
|
||||
socket.on('appSetLoginItemSettings', function (settings) {
|
||||
socket.on('appSetLoginItemSettings', (settings) => {
|
||||
app.setLoginItemSettings(settings);
|
||||
});
|
||||
socket.on('appIsAccessibilitySupportEnabled', function () {
|
||||
var isAccessibilitySupportEnabled = app.isAccessibilitySupportEnabled();
|
||||
socket.emit('appIsAccessibilitySupportEnabledCompleted', isAccessibilitySupportEnabled);
|
||||
socket.on('appIsAccessibilitySupportEnabled', () => {
|
||||
const isAccessibilitySupportEnabled = app.isAccessibilitySupportEnabled();
|
||||
electronSocket.emit('appIsAccessibilitySupportEnabledCompleted', isAccessibilitySupportEnabled);
|
||||
});
|
||||
socket.on('appSetAboutPanelOptions', function (options) {
|
||||
socket.on('appSetAboutPanelOptions', (options) => {
|
||||
app.setAboutPanelOptions(options);
|
||||
});
|
||||
socket.on('appCommandLineAppendSwitch', function (theSwitch, value) {
|
||||
app.commandLine.appendSwitch(theSwitch, value);
|
||||
socket.on('appDockBounce', (type) => {
|
||||
const id = app.dock.bounce(type);
|
||||
electronSocket.emit('appDockBounceCompleted', id);
|
||||
});
|
||||
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) {
|
||||
socket.on('appDockCancelBounce', (id) => {
|
||||
app.dock.cancelBounce(id);
|
||||
});
|
||||
socket.on('appDockDownloadFinished', function (filePath) {
|
||||
socket.on('appDockDownloadFinished', (filePath) => {
|
||||
app.dock.downloadFinished(filePath);
|
||||
});
|
||||
socket.on('appDockSetBadge', function (text) {
|
||||
socket.on('appDockSetBadge', (text) => {
|
||||
app.dock.setBadge(text);
|
||||
});
|
||||
socket.on('appDockGetBadge', function () {
|
||||
var text = app.dock.getBadge();
|
||||
socket.emit('appDockGetBadgeCompleted', text);
|
||||
socket.on('appDockGetBadge', () => {
|
||||
const text = app.dock.getBadge();
|
||||
electronSocket.emit('appDockGetBadgeCompleted', text);
|
||||
});
|
||||
socket.on('appDockHide', function () {
|
||||
socket.on('appDockHide', () => {
|
||||
app.dock.hide();
|
||||
});
|
||||
socket.on('appDockShow', function () {
|
||||
socket.on('appDockShow', () => {
|
||||
app.dock.show();
|
||||
});
|
||||
socket.on('appDockIsVisible', function () {
|
||||
var isVisible = app.dock.isVisible();
|
||||
socket.emit('appDockIsVisibleCompleted', isVisible);
|
||||
socket.on('appDockIsVisible', () => {
|
||||
const isVisible = app.dock.isVisible();
|
||||
electronSocket.emit('appDockIsVisibleCompleted', isVisible);
|
||||
});
|
||||
// TODO: Menü Lösung muss noch implementiert werden
|
||||
socket.on('appDockSetMenu', function (menu) {
|
||||
socket.on('appDockSetMenu', (menu) => {
|
||||
app.dock.setMenu(menu);
|
||||
});
|
||||
socket.on('appDockSetIcon', function (image) {
|
||||
socket.on('appDockSetIcon', (image) => {
|
||||
app.dock.setIcon(image);
|
||||
});
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,58 +1,69 @@
|
||||
import { nativeImage as NativeImage } from 'electron';
|
||||
let isQuitWindowAllClosed = true, electronSocket;
|
||||
export = (socket: SocketIO.Socket, app: Electron.App) => {
|
||||
electronSocket = socket;
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin' &&
|
||||
isQuitWindowAllClosed) {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('quit-app-window-all-closed-event', (quit) => {
|
||||
isQuitWindowAllClosed = quit;
|
||||
});
|
||||
|
||||
module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('register-app-window-all-closed-event', (id) => {
|
||||
app.on('window-all-closed', () => {
|
||||
socket.emit('app-window-all-closed' + id);
|
||||
electronSocket.emit('app-window-all-closed' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-before-quit-event', (id) => {
|
||||
app.on('before-quit', () => {
|
||||
socket.emit('app-before-quit' + id);
|
||||
app.on('before-quit', (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
electronSocket.emit('app-before-quit' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-will-quit-event', (id) => {
|
||||
app.on('will-quit', () => {
|
||||
socket.emit('app-will-quit' + id);
|
||||
});
|
||||
});
|
||||
app.on('will-quit', (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
socket.on('register-app-quit-event', (id) => {
|
||||
app.on('quit', () => {
|
||||
socket.emit('app-quit' + id);
|
||||
electronSocket.emit('app-will-quit' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-browser-window-blur-event', (id) => {
|
||||
app.on('browser-window-blur', () => {
|
||||
socket.emit('app-browser-window-blur' + id);
|
||||
electronSocket.emit('app-browser-window-blur' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-browser-window-focus-event', (id) => {
|
||||
app.on('browser-window-focus', () => {
|
||||
socket.emit('app-browser-window-focus' + id);
|
||||
electronSocket.emit('app-browser-window-focus' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-browser-window-created-event', (id) => {
|
||||
app.on('browser-window-created', () => {
|
||||
socket.emit('app-browser-window-created' + id);
|
||||
electronSocket.emit('app-browser-window-created' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-web-contents-created-event', (id) => {
|
||||
app.on('web-contents-created', () => {
|
||||
socket.emit('app-web-contents-created' + id);
|
||||
electronSocket.emit('app-web-contents-created' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-app-accessibility-support-changed-event', (id) => {
|
||||
app.on('accessibility-support-changed', (event, accessibilitySupportEnabled) => {
|
||||
socket.emit('app-accessibility-support-changed' + id, accessibilitySupportEnabled);
|
||||
electronSocket.emit('app-accessibility-support-changed' + id, accessibilitySupportEnabled);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,12 +93,12 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appGetAppPath', () => {
|
||||
const path = app.getAppPath();
|
||||
socket.emit('appGetAppPathCompleted', path);
|
||||
electronSocket.emit('appGetAppPathCompleted', path);
|
||||
});
|
||||
|
||||
socket.on('appGetPath', (name) => {
|
||||
const path = app.getPath(name);
|
||||
socket.emit('appGetPathCompleted', path);
|
||||
electronSocket.emit('appGetPathCompleted', path);
|
||||
});
|
||||
|
||||
// const nativeImages = {};
|
||||
@@ -102,15 +113,17 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
// }
|
||||
// }
|
||||
|
||||
socket.on('appGetFileIcon', (path, options) => {
|
||||
if(options) {
|
||||
app.getFileIcon(path, options, (error, nativeImage) => {
|
||||
socket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
});
|
||||
socket.on('appGetFileIcon', async (path, options) => {
|
||||
let error = {};
|
||||
|
||||
if (options) {
|
||||
const nativeImage = await app.getFileIcon(path, options).catch((errorFileIcon) => error = errorFileIcon);
|
||||
|
||||
electronSocket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
} else {
|
||||
app.getFileIcon(path, (error, nativeImage) => {
|
||||
socket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
});
|
||||
const nativeImage = await app.getFileIcon(path).catch((errorFileIcon) => error = errorFileIcon);
|
||||
|
||||
electronSocket.emit('appGetFileIconCompleted', [error, nativeImage]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -120,21 +133,20 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appGetVersion', () => {
|
||||
const version = app.getVersion();
|
||||
socket.emit('appGetVersionCompleted', version);
|
||||
electronSocket.emit('appGetVersionCompleted', version);
|
||||
});
|
||||
|
||||
socket.on('appGetName', () => {
|
||||
const name = app.getName();
|
||||
socket.emit('appGetNameCompleted', name);
|
||||
electronSocket.emit('appGetNameCompleted', app.name);
|
||||
});
|
||||
|
||||
socket.on('appSetName', (name) => {
|
||||
app.setName(name);
|
||||
app.name = name;
|
||||
});
|
||||
|
||||
socket.on('appGetLocale', () => {
|
||||
const locale = app.getLocale();
|
||||
socket.emit('appGetLocaleCompleted', locale);
|
||||
electronSocket.emit('appGetLocaleCompleted', locale);
|
||||
});
|
||||
|
||||
socket.on('appAddRecentDocument', (path) => {
|
||||
@@ -147,42 +159,44 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appSetAsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.setAsDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appSetAsDefaultProtocolClientCompleted', success);
|
||||
electronSocket.emit('appSetAsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appRemoveAsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.removeAsDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appRemoveAsDefaultProtocolClientCompleted', success);
|
||||
electronSocket.emit('appRemoveAsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appIsDefaultProtocolClient', (protocol, path, args) => {
|
||||
const success = app.isDefaultProtocolClient(protocol, path, args);
|
||||
socket.emit('appIsDefaultProtocolClientCompleted', success);
|
||||
electronSocket.emit('appIsDefaultProtocolClientCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appSetUserTasks', (tasks) => {
|
||||
const success = app.setUserTasks(tasks);
|
||||
socket.emit('appSetUserTasksCompleted', success);
|
||||
electronSocket.emit('appSetUserTasksCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appGetJumpListSettings', () => {
|
||||
const jumpListSettings = app.getJumpListSettings();
|
||||
socket.emit('appGetJumpListSettingsCompleted', jumpListSettings);
|
||||
electronSocket.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.on('appRequestSingleInstanceLock', () => {
|
||||
app.on('second-instance', (args, workingDirectory) => {
|
||||
electronSocket.emit('secondInstance', [args, workingDirectory]);
|
||||
});
|
||||
socket.emit('appMakeSingleInstanceCompleted', success);
|
||||
|
||||
const success = app.requestSingleInstanceLock();
|
||||
electronSocket.emit('appRequestSingleInstanceLockCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appReleaseSingleInstance', () => {
|
||||
app.releaseSingleInstance();
|
||||
socket.on('appReleaseSingleInstanceLock', () => {
|
||||
app.releaseSingleInstanceLock();
|
||||
});
|
||||
|
||||
socket.on('appSetUserActivity', (type, userInfo, webpageURL) => {
|
||||
@@ -191,7 +205,7 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appGetCurrentActivityType', () => {
|
||||
const activityType = app.getCurrentActivityType();
|
||||
socket.emit('appGetCurrentActivityTypeCompleted', activityType);
|
||||
electronSocket.emit('appGetCurrentActivityTypeCompleted', activityType);
|
||||
});
|
||||
|
||||
socket.on('appSetAppUserModelId', (id) => {
|
||||
@@ -200,40 +214,38 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appImportCertificate', (options) => {
|
||||
app.importCertificate(options, (result) => {
|
||||
socket.emit('appImportCertificateCompleted', result);
|
||||
electronSocket.emit('appImportCertificateCompleted', result);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('appGetAppMetrics', () => {
|
||||
const processMetrics = app.getAppMetrics();
|
||||
socket.emit('appGetAppMetricsCompleted', processMetrics);
|
||||
electronSocket.emit('appGetAppMetricsCompleted', processMetrics);
|
||||
});
|
||||
|
||||
socket.on('appGetGpuFeatureStatus', () => {
|
||||
// TS Workaround - TS say getGpuFeatureStatus - but it is getGPUFeatureStatus
|
||||
let x = <any>app;
|
||||
const gpuFeatureStatus = x.getGPUFeatureStatus();
|
||||
socket.emit('appGetGpuFeatureStatusCompleted', gpuFeatureStatus);
|
||||
const gpuFeatureStatus = app.getGPUFeatureStatus();
|
||||
electronSocket.emit('appGetGpuFeatureStatusCompleted', gpuFeatureStatus);
|
||||
});
|
||||
|
||||
socket.on('appSetBadgeCount', (count) => {
|
||||
const success = app.setBadgeCount(count);
|
||||
socket.emit('appSetBadgeCountCompleted', success);
|
||||
electronSocket.emit('appSetBadgeCountCompleted', success);
|
||||
});
|
||||
|
||||
socket.on('appGetBadgeCount', () => {
|
||||
const count = app.getBadgeCount();
|
||||
socket.emit('appGetBadgeCountCompleted', count);
|
||||
electronSocket.emit('appGetBadgeCountCompleted', count);
|
||||
});
|
||||
|
||||
socket.on('appIsUnityRunning', () => {
|
||||
const isUnityRunning = app.isUnityRunning();
|
||||
socket.emit('appIsUnityRunningCompleted', isUnityRunning);
|
||||
electronSocket.emit('appIsUnityRunningCompleted', isUnityRunning);
|
||||
});
|
||||
|
||||
socket.on('appGetLoginItemSettings', (options) => {
|
||||
const loginItemSettings = app.getLoginItemSettings(options);
|
||||
socket.emit('appGetLoginItemSettingsCompleted', loginItemSettings);
|
||||
electronSocket.emit('appGetLoginItemSettingsCompleted', loginItemSettings);
|
||||
});
|
||||
|
||||
socket.on('appSetLoginItemSettings', (settings) => {
|
||||
@@ -242,28 +254,16 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appIsAccessibilitySupportEnabled', () => {
|
||||
const isAccessibilitySupportEnabled = app.isAccessibilitySupportEnabled();
|
||||
socket.emit('appIsAccessibilitySupportEnabledCompleted', isAccessibilitySupportEnabled);
|
||||
electronSocket.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);
|
||||
electronSocket.emit('appDockBounceCompleted', id);
|
||||
});
|
||||
|
||||
socket.on('appDockCancelBounce', (id) => {
|
||||
@@ -280,7 +280,7 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appDockGetBadge', () => {
|
||||
const text = app.dock.getBadge();
|
||||
socket.emit('appDockGetBadgeCompleted', text);
|
||||
electronSocket.emit('appDockGetBadgeCompleted', text);
|
||||
});
|
||||
|
||||
socket.on('appDockHide', () => {
|
||||
@@ -293,7 +293,7 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
|
||||
socket.on('appDockIsVisible', () => {
|
||||
const isVisible = app.dock.isVisible();
|
||||
socket.emit('appDockIsVisibleCompleted', isVisible);
|
||||
electronSocket.emit('appDockIsVisibleCompleted', isVisible);
|
||||
});
|
||||
|
||||
// TODO: Menü Lösung muss noch implementiert werden
|
||||
@@ -304,4 +304,4 @@ module.exports = (socket: SocketIO.Server, app: Electron.App) => {
|
||||
socket.on('appDockSetIcon', (image) => {
|
||||
app.dock.setIcon(image);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
103
ElectronNET.Host/api/autoUpdater.js
Normal file
103
ElectronNET.Host/api/autoUpdater.js
Normal file
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
const electron_updater_1 = require("electron-updater");
|
||||
const path = require('path');
|
||||
let electronSocket;
|
||||
module.exports = (socket) => {
|
||||
electronSocket = socket;
|
||||
// Events ********
|
||||
socket.on('register-autoUpdater-error-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('error', (error) => {
|
||||
electronSocket.emit('autoUpdater-error' + id, error.message);
|
||||
});
|
||||
});
|
||||
socket.on('register-autoUpdater-checking-for-update-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('checking-for-update', () => {
|
||||
electronSocket.emit('autoUpdater-checking-for-update' + id);
|
||||
});
|
||||
});
|
||||
socket.on('register-autoUpdater-update-available-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('update-available', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-available' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
socket.on('register-autoUpdater-update-not-available-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('update-not-available', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-not-available' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
socket.on('register-autoUpdater-download-progress-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('download-progress', (progressInfo) => {
|
||||
electronSocket.emit('autoUpdater-download-progress' + id, progressInfo);
|
||||
});
|
||||
});
|
||||
socket.on('register-autoUpdater-update-downloaded-event', (id) => {
|
||||
electron_updater_1.autoUpdater.on('update-downloaded', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-downloaded' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
// Properties *****
|
||||
socket.on('autoUpdater-autoDownload-get', () => {
|
||||
electronSocket.emit('autoUpdater-autoDownload-get-reply', electron_updater_1.autoUpdater.autoDownload);
|
||||
});
|
||||
socket.on('autoUpdater-autoDownload-set', (value) => {
|
||||
electron_updater_1.autoUpdater.autoDownload = value;
|
||||
});
|
||||
socket.on('autoUpdater-autoInstallOnAppQuit-get', () => {
|
||||
electronSocket.emit('autoUpdater-autoInstallOnAppQuit-get-reply', electron_updater_1.autoUpdater.autoInstallOnAppQuit);
|
||||
});
|
||||
socket.on('autoUpdater-autoInstallOnAppQuit-set', (value) => {
|
||||
electron_updater_1.autoUpdater.autoInstallOnAppQuit = value;
|
||||
});
|
||||
socket.on('autoUpdater-allowPrerelease-get', () => {
|
||||
electronSocket.emit('autoUpdater-allowPrerelease-get-reply', electron_updater_1.autoUpdater.allowPrerelease);
|
||||
});
|
||||
socket.on('autoUpdater-allowPrerelease-set', (value) => {
|
||||
electron_updater_1.autoUpdater.allowPrerelease = value;
|
||||
});
|
||||
socket.on('autoUpdater-fullChangelog-get', () => {
|
||||
electronSocket.emit('autoUpdater-fullChangelog-get-reply', electron_updater_1.autoUpdater.fullChangelog);
|
||||
});
|
||||
socket.on('autoUpdater-fullChangelog-set', (value) => {
|
||||
electron_updater_1.autoUpdater.fullChangelog = value;
|
||||
});
|
||||
socket.on('autoUpdater-allowDowngrade-get', () => {
|
||||
electronSocket.emit('autoUpdater-allowDowngrade-get-reply', electron_updater_1.autoUpdater.allowDowngrade);
|
||||
});
|
||||
socket.on('autoUpdater-allowDowngrade-set', (value) => {
|
||||
electron_updater_1.autoUpdater.allowDowngrade = value;
|
||||
});
|
||||
socket.on('autoUpdater-updateConfigPath-get', () => {
|
||||
electronSocket.emit('autoUpdater-updateConfigPath-get-reply', electron_updater_1.autoUpdater.updateConfigPath || '');
|
||||
});
|
||||
socket.on('autoUpdater-updateConfigPath-set', (value) => {
|
||||
electron_updater_1.autoUpdater.updateConfigPath = value;
|
||||
});
|
||||
socket.on('autoUpdater-channel-get', () => {
|
||||
electronSocket.emit('autoUpdater-channel-get-reply', electron_updater_1.autoUpdater.channel || '');
|
||||
});
|
||||
socket.on('autoUpdater-channel-set', (value) => {
|
||||
electron_updater_1.autoUpdater.channel = value;
|
||||
});
|
||||
// Methods ********
|
||||
socket.on('autoUpdaterCheckForUpdatesAndNotify', async (guid) => {
|
||||
const updateCheckResult = await electron_updater_1.autoUpdater.checkForUpdatesAndNotify();
|
||||
electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult);
|
||||
});
|
||||
socket.on('autoUpdaterCheckForUpdates', async (guid) => {
|
||||
// autoUpdater.updateConfigPath = path.join(__dirname, 'dev-app-update.yml');
|
||||
const updateCheckResult = await electron_updater_1.autoUpdater.checkForUpdates();
|
||||
electronSocket.emit('autoUpdaterCheckForUpdatesComplete' + guid, updateCheckResult);
|
||||
});
|
||||
socket.on('autoUpdaterQuitAndInstall', async (isSilent, isForceRunAfter) => {
|
||||
electron_updater_1.autoUpdater.quitAndInstall(isSilent, isForceRunAfter);
|
||||
});
|
||||
socket.on('autoUpdaterDownloadUpdate', async (guid) => {
|
||||
const downloadedPath = await electron_updater_1.autoUpdater.downloadUpdate();
|
||||
electronSocket.emit('autoUpdaterDownloadUpdateComplete' + guid, downloadedPath);
|
||||
});
|
||||
socket.on('autoUpdaterGetFeedURL', async (guid) => {
|
||||
const feedUrl = await electron_updater_1.autoUpdater.getFeedURL();
|
||||
electronSocket.emit('autoUpdaterGetFeedURLComplete' + guid, feedUrl || '');
|
||||
});
|
||||
};
|
||||
//# sourceMappingURL=autoUpdater.js.map
|
||||
1
ElectronNET.Host/api/autoUpdater.js.map
Normal file
1
ElectronNET.Host/api/autoUpdater.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"autoUpdater.js","sourceRoot":"","sources":["autoUpdater.ts"],"names":[],"mappings":";AAAA,uDAA+C;AAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,kBAAkB;IAElB,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,CAAC,EAAE,EAAE,EAAE;QACjD,8BAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9B,cAAc,CAAC,IAAI,CAAC,mBAAmB,GAAG,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gDAAgD,EAAE,CAAC,EAAE,EAAE,EAAE;QAC/D,8BAAW,CAAC,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACvC,cAAc,CAAC,IAAI,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,6CAA6C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC5D,8BAAW,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,EAAE;YAC9C,cAAc,CAAC,IAAI,CAAC,8BAA8B,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iDAAiD,EAAE,CAAC,EAAE,EAAE,EAAE;QAChE,8BAAW,CAAC,EAAE,CAAC,sBAAsB,EAAE,CAAC,UAAU,EAAE,EAAE;YAClD,cAAc,CAAC,IAAI,CAAC,kCAAkC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8CAA8C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC7D,8BAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,YAAY,EAAE,EAAE;YACjD,cAAc,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8CAA8C,EAAE,CAAC,EAAE,EAAE,EAAE;QAC7D,8BAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,UAAU,EAAE,EAAE;YAC/C,cAAc,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,mBAAmB;IAEnB,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC3C,cAAc,CAAC,IAAI,CAAC,oCAAoC,EAAE,8BAAW,CAAC,YAAY,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,8BAA8B,EAAE,CAAC,KAAK,EAAE,EAAE;QAChD,8BAAW,CAAC,YAAY,GAAG,KAAK,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QACnD,cAAc,CAAC,IAAI,CAAC,4CAA4C,EAAE,8BAAW,CAAC,oBAAoB,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,sCAAsC,EAAE,CAAC,KAAK,EAAE,EAAE;QACxD,8BAAW,CAAC,oBAAoB,GAAG,KAAK,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC9C,cAAc,CAAC,IAAI,CAAC,uCAAuC,EAAE,8BAAW,CAAC,eAAe,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,CAAC,KAAK,EAAE,EAAE;QACnD,8BAAW,CAAC,eAAe,GAAG,KAAK,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC5C,cAAc,CAAC,IAAI,CAAC,qCAAqC,EAAE,8BAAW,CAAC,aAAa,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,+BAA+B,EAAE,CAAC,KAAK,EAAE,EAAE;QACjD,8BAAW,CAAC,aAAa,GAAG,KAAK,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAC7C,cAAc,CAAC,IAAI,CAAC,sCAAsC,EAAE,8BAAW,CAAC,cAAc,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gCAAgC,EAAE,CAAC,KAAK,EAAE,EAAE;QAClD,8BAAW,CAAC,cAAc,GAAG,KAAK,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC/C,cAAc,CAAC,IAAI,CAAC,wCAAwC,EAAE,8BAAW,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,CAAC,KAAK,EAAE,EAAE;QACpD,8BAAW,CAAC,gBAAgB,GAAG,KAAK,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACtC,cAAc,CAAC,IAAI,CAAC,+BAA+B,EAAE,8BAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3C,8BAAW,CAAC,OAAO,GAAG,KAAK,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,mBAAmB;IAEnB,MAAM,CAAC,EAAE,CAAC,qCAAqC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC5D,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,wBAAwB,EAAE,CAAC;QACvE,cAAc,CAAC,IAAI,CAAC,6CAA6C,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACnD,6EAA6E;QAC7E,MAAM,iBAAiB,GAAG,MAAM,8BAAW,CAAC,eAAe,EAAE,CAAC;QAC9D,cAAc,CAAC,IAAI,CAAC,oCAAoC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,EAAE;QACvE,8BAAW,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClD,MAAM,cAAc,GAAG,MAAM,8BAAW,CAAC,cAAc,EAAE,CAAC;QAC1D,cAAc,CAAC,IAAI,CAAC,mCAAmC,GAAG,IAAI,EAAE,cAAc,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9C,MAAM,OAAO,GAAG,MAAM,8BAAW,CAAC,UAAU,EAAE,CAAC;QAC/C,cAAc,CAAC,IAAI,CAAC,+BAA+B,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}
|
||||
130
ElectronNET.Host/api/autoUpdater.ts
Normal file
130
ElectronNET.Host/api/autoUpdater.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
const path = require('path');
|
||||
let electronSocket;
|
||||
|
||||
export = (socket: SocketIO.Socket) => {
|
||||
electronSocket = socket;
|
||||
|
||||
// Events ********
|
||||
|
||||
socket.on('register-autoUpdater-error-event', (id) => {
|
||||
autoUpdater.on('error', (error) => {
|
||||
electronSocket.emit('autoUpdater-error' + id, error.message);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-autoUpdater-checking-for-update-event', (id) => {
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
electronSocket.emit('autoUpdater-checking-for-update' + id);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-autoUpdater-update-available-event', (id) => {
|
||||
autoUpdater.on('update-available', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-available' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-autoUpdater-update-not-available-event', (id) => {
|
||||
autoUpdater.on('update-not-available', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-not-available' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-autoUpdater-download-progress-event', (id) => {
|
||||
autoUpdater.on('download-progress', (progressInfo) => {
|
||||
electronSocket.emit('autoUpdater-download-progress' + id, progressInfo);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('register-autoUpdater-update-downloaded-event', (id) => {
|
||||
autoUpdater.on('update-downloaded', (updateInfo) => {
|
||||
electronSocket.emit('autoUpdater-update-downloaded' + id, updateInfo);
|
||||
});
|
||||
});
|
||||
|
||||
// Properties *****
|
||||
|
||||
socket.on('autoUpdater-autoDownload-get', () => {
|
||||
electronSocket.emit('autoUpdater-autoDownload-get-reply', autoUpdater.autoDownload);
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-autoDownload-set', (value) => {
|
||||
autoUpdater.autoDownload = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-autoInstallOnAppQuit-get', () => {
|
||||
electronSocket.emit('autoUpdater-autoInstallOnAppQuit-get-reply', autoUpdater.autoInstallOnAppQuit);
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-autoInstallOnAppQuit-set', (value) => {
|
||||
autoUpdater.autoInstallOnAppQuit = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-allowPrerelease-get', () => {
|
||||
electronSocket.emit('autoUpdater-allowPrerelease-get-reply', autoUpdater.allowPrerelease);
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-allowPrerelease-set', (value) => {
|
||||
autoUpdater.allowPrerelease = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-fullChangelog-get', () => {
|
||||
electronSocket.emit('autoUpdater-fullChangelog-get-reply', autoUpdater.fullChangelog);
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-fullChangelog-set', (value) => {
|
||||
autoUpdater.fullChangelog = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-allowDowngrade-get', () => {
|
||||
electronSocket.emit('autoUpdater-allowDowngrade-get-reply', autoUpdater.allowDowngrade);
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-allowDowngrade-set', (value) => {
|
||||
autoUpdater.allowDowngrade = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-updateConfigPath-get', () => {
|
||||
electronSocket.emit('autoUpdater-updateConfigPath-get-reply', autoUpdater.updateConfigPath || '');
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-updateConfigPath-set', (value) => {
|
||||
autoUpdater.updateConfigPath = value;
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-channel-get', () => {
|
||||
electronSocket.emit('autoUpdater-channel-get-reply', autoUpdater.channel || '');
|
||||
});
|
||||
|
||||
socket.on('autoUpdater-channel-set', (value) => {
|
||||
autoUpdater.channel = value;
|
||||
});
|
||||
|
||||
// Methods ********
|
||||
|
||||
socket.on('autoUpdaterCheckForUpdatesAndNotify', async (guid) => {
|
||||
const updateCheckResult = await autoUpdater.checkForUpdatesAndNotify();
|
||||
electronSocket.emit('autoUpdaterCheckForUpdatesAndNotifyComplete' + guid, updateCheckResult);
|
||||
});
|
||||
|
||||
socket.on('autoUpdaterCheckForUpdates', async (guid) => {
|
||||
// autoUpdater.updateConfigPath = path.join(__dirname, 'dev-app-update.yml');
|
||||
const updateCheckResult = await autoUpdater.checkForUpdates();
|
||||
electronSocket.emit('autoUpdaterCheckForUpdatesComplete' + guid, updateCheckResult);
|
||||
});
|
||||
|
||||
socket.on('autoUpdaterQuitAndInstall', async (isSilent, isForceRunAfter) => {
|
||||
autoUpdater.quitAndInstall(isSilent, isForceRunAfter);
|
||||
});
|
||||
|
||||
socket.on('autoUpdaterDownloadUpdate', async (guid) => {
|
||||
const downloadedPath = await autoUpdater.downloadUpdate();
|
||||
electronSocket.emit('autoUpdaterDownloadUpdateComplete' + guid, downloadedPath);
|
||||
});
|
||||
|
||||
socket.on('autoUpdaterGetFeedURL', async (guid) => {
|
||||
const feedUrl = await autoUpdater.getFeedURL();
|
||||
electronSocket.emit('autoUpdaterGetFeedURLComplete' + guid, feedUrl || '');
|
||||
});
|
||||
};
|
||||
55
ElectronNET.Host/api/browserView.js
Normal file
55
ElectronNET.Host/api/browserView.js
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
const electron_1 = require("electron");
|
||||
let browserViews = [];
|
||||
let browserView, electronSocket;
|
||||
module.exports = (socket) => {
|
||||
electronSocket = socket;
|
||||
socket.on('createBrowserView', (options) => {
|
||||
if (!hasOwnChildreen(options, 'webPreferences', 'nodeIntegration')) {
|
||||
options = { ...options, webPreferences: { nodeIntegration: true } };
|
||||
}
|
||||
browserView = new electron_1.BrowserView(options);
|
||||
browserViews.push(browserView);
|
||||
electronSocket.emit('BrowserViewCreated', browserView.id);
|
||||
});
|
||||
socket.on('browserView-isDestroyed', (id) => {
|
||||
const isDestroyed = getBrowserViewById(id).isDestroyed();
|
||||
electronSocket.emit('browserView-isDestroyed-reply', isDestroyed);
|
||||
});
|
||||
socket.on('browserView-getBounds', (id) => {
|
||||
const bounds = getBrowserViewById(id).getBounds();
|
||||
electronSocket.emit('browserView-getBounds-reply', bounds);
|
||||
});
|
||||
socket.on('browserView-setBounds', (id, bounds) => {
|
||||
getBrowserViewById(id).setBounds(bounds);
|
||||
});
|
||||
socket.on('browserView-destroy', (id) => {
|
||||
const browserViewIndex = browserViews.findIndex(b => b.id === id);
|
||||
getBrowserViewById(id).destroy();
|
||||
browserViews.splice(browserViewIndex, 1);
|
||||
});
|
||||
socket.on('browserView-setAutoResize', (id, options) => {
|
||||
getBrowserViewById(id).setAutoResize(options);
|
||||
});
|
||||
socket.on('browserView-setBackgroundColor', (id, color) => {
|
||||
getBrowserViewById(id).setBackgroundColor(color);
|
||||
});
|
||||
function hasOwnChildreen(obj, ...childNames) {
|
||||
for (let i = 0; i < childNames.length; i++) {
|
||||
if (!obj || !obj.hasOwnProperty(childNames[i])) {
|
||||
return false;
|
||||
}
|
||||
obj = obj[childNames[i]];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function getBrowserViewById(id) {
|
||||
for (let index = 0; index < browserViews.length; index++) {
|
||||
const browserViewItem = browserViews[index];
|
||||
if (browserViewItem.id === id) {
|
||||
return browserViewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=browserView.js.map
|
||||
1
ElectronNET.Host/api/browserView.js.map
Normal file
1
ElectronNET.Host/api/browserView.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"browserView.js","sourceRoot":"","sources":["browserView.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,IAAI,YAAY,GAA2B,EAAE,CAAC;AAC9C,IAAI,WAAwB,EAAE,cAAc,CAAC;AAE7C,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,OAAO,EAAE,EAAE;QACvC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,EAAE;YAChE,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;SACvE;QAED,WAAW,GAAG,IAAI,sBAAW,CAAC,OAAO,CAAC,CAAC;QACvC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE/B,cAAc,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,EAAE,EAAE,EAAE;QACxC,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAEzD,cAAc,CAAC,IAAI,CAAC,+BAA+B,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,EAAE,EAAE,EAAE;QACtC,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;QAElD,cAAc,CAAC,IAAI,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE;QAC9C,kBAAkB,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,EAAE,EAAE,EAAE;QACpC,MAAM,gBAAgB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACjC,YAAY,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,2BAA2B,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE;QACnD,kBAAkB,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,gCAAgC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;QACtD,kBAAkB,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,SAAS,eAAe,CAAC,GAAG,EAAE,GAAG,UAAU;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACxC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC5C,OAAO,KAAK,CAAC;aAChB;YACD,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;SAC5B;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,SAAS,kBAAkB,CAAC,EAAU;QAClC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACtD,MAAM,eAAe,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE;gBAC3B,OAAO,eAAe,CAAC;aAC1B;SACJ;IACL,CAAC;AACL,CAAC,CAAC"}
|
||||
68
ElectronNET.Host/api/browserView.ts
Normal file
68
ElectronNET.Host/api/browserView.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { BrowserView } from 'electron';
|
||||
let browserViews: Electron.BrowserView[] = [];
|
||||
let browserView: BrowserView, electronSocket;
|
||||
|
||||
export = (socket: SocketIO.Socket) => {
|
||||
electronSocket = socket;
|
||||
|
||||
socket.on('createBrowserView', (options) => {
|
||||
if (!hasOwnChildreen(options, 'webPreferences', 'nodeIntegration')) {
|
||||
options = { ...options, webPreferences: { nodeIntegration: true } };
|
||||
}
|
||||
|
||||
browserView = new BrowserView(options);
|
||||
browserViews.push(browserView);
|
||||
|
||||
electronSocket.emit('BrowserViewCreated', browserView.id);
|
||||
});
|
||||
|
||||
socket.on('browserView-isDestroyed', (id) => {
|
||||
const isDestroyed = getBrowserViewById(id).isDestroyed();
|
||||
|
||||
electronSocket.emit('browserView-isDestroyed-reply', isDestroyed);
|
||||
});
|
||||
|
||||
socket.on('browserView-getBounds', (id) => {
|
||||
const bounds = getBrowserViewById(id).getBounds();
|
||||
|
||||
electronSocket.emit('browserView-getBounds-reply', bounds);
|
||||
});
|
||||
|
||||
socket.on('browserView-setBounds', (id, bounds) => {
|
||||
getBrowserViewById(id).setBounds(bounds);
|
||||
});
|
||||
|
||||
socket.on('browserView-destroy', (id) => {
|
||||
const browserViewIndex = browserViews.findIndex(b => b.id === id);
|
||||
getBrowserViewById(id).destroy();
|
||||
browserViews.splice(browserViewIndex, 1);
|
||||
});
|
||||
|
||||
socket.on('browserView-setAutoResize', (id, options) => {
|
||||
getBrowserViewById(id).setAutoResize(options);
|
||||
});
|
||||
|
||||
socket.on('browserView-setBackgroundColor', (id, color) => {
|
||||
getBrowserViewById(id).setBackgroundColor(color);
|
||||
});
|
||||
|
||||
function hasOwnChildreen(obj, ...childNames) {
|
||||
for (let i = 0; i < childNames.length; i++) {
|
||||
if (!obj || !obj.hasOwnProperty(childNames[i])) {
|
||||
return false;
|
||||
}
|
||||
obj = obj[childNames[i]];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getBrowserViewById(id: number) {
|
||||
for (let index = 0; index < browserViews.length; index++) {
|
||||
const browserViewItem = browserViews[index];
|
||||
if (browserViewItem.id === id) {
|
||||
return browserViewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user