Compare commits

..

350 Commits

Author SHA1 Message Date
Gregor Biswanger
e9bf393165 Merge branch 'theolivenbaum-master' 2022-07-28 11:52:12 +02:00
Gregor Biswanger
d3aa9783d3 Merge of theolivenbaum PR 2022-07-28 11:51:18 +02:00
theolivenbaum
a5bc910926 Release 19.0.9 2022-07-22 10:45:24 +02:00
theolivenbaum
89033c61d4 Return socket port 2022-07-14 17:07:19 +02:00
theolivenbaum
90b4a287d9 Add experimental mode to start electron from C# (for development purposes) 2022-07-14 16:56:50 +02:00
theolivenbaum
e2615a8dc1 Import SocketIO code 2022-07-14 16:53:54 +02:00
theolivenbaum
73330185de Release 19.0.8 2022-07-12 13:43:12 +02:00
theolivenbaum
e1c5b7e3c2 Update main.js 2022-06-28 15:40:58 +02:00
theolivenbaum
a19e095f6e Fix wrong variable name 2022-06-27 16:04:32 +02:00
theolivenbaum
b7ed3d22f1 Update main.js 2022-06-27 14:53:21 +02:00
theolivenbaum
c8f944af4a Release 19.0.6 2022-06-27 14:35:16 +02:00
theolivenbaum
2f73bb8b34 Release 19.0.5 2022-06-21 10:48:40 +02:00
theolivenbaum
1f22be68d2 Drop net5.0 2022-06-09 10:23:29 +02:00
theolivenbaum
576140474e merge #624 2022-06-09 10:22:54 +02:00
theolivenbaum
68c9e80417 merge #673 2022-06-09 10:12:15 +02:00
theolivenbaum
4906babd78 Change to use ImageSharp 2022-06-08 21:28:38 +02:00
theolivenbaum
e0000f7aba Change to use ImageSharp 2022-06-08 21:28:30 +02:00
theolivenbaum
ff05ef20c8 Release 19.0.4 2022-06-08 20:52:35 +02:00
theolivenbaum
79ce1c42e7 Release 19.0.3 2022-06-08 20:20:57 +02:00
Gregor Biswanger
4e95bb3331 Static parameter for build commands method 2022-06-07 23:03:06 +02:00
Gregor Biswanger
58bfa336a8 Change to .NET 6 only 2022-06-07 22:59:26 +02:00
Gregor Biswanger
afa69280f5 Fixed merge conflicts 2022-06-07 22:55:00 +02:00
Gregor Biswanger
8621d8cea3 Merge branch 'master' into dev/electron-18-update 2022-06-07 22:48:13 +02:00
Gregor Biswanger
9106391f60 Merge pull request #698 from stackify/bad-master
#697 fixing conflicts in ElectronNET.CLI commands
2022-06-07 22:41:53 +02:00
Gregor Biswanger
490ef6231b .NET 6 support only 2022-06-07 22:40:44 +02:00
theolivenbaum
89833f42fc Release 19.0.2 2022-06-02 11:11:26 +02:00
theolivenbaum
252ab5050b Release 18.3.2 2022-06-02 11:10:38 +02:00
Daniel Gidman
2ff29e553d #697 fixing conflicts in ElectronNET.CLI commands 2022-05-31 13:49:49 -05:00
theolivenbaum
a1a5f6f9a6 Handle case where pipe breaks showing error message 2022-05-31 13:38:54 +02:00
theolivenbaum
3ea7e96324 Release 19.0.1 2022-05-27 10:10:28 +02:00
theolivenbaum
a00a8a0251 Release 18.3.0 2022-05-24 10:07:32 +02:00
theolivenbaum
e245d0d2f6 release also for 17.4.1 2022-04-23 17:02:54 +02:00
theolivenbaum
48a0d68313 Increase max message size to 100mb 2022-04-23 17:01:34 +02:00
theolivenbaum
4d5d6722a7 Check if version exists 2022-04-21 09:38:41 +02:00
theolivenbaum
d910eec8df Add releaser helper to automate updating versions 2022-04-21 09:36:22 +02:00
theolivenbaum
4f9b46c616 Electron Release 18.1.0 2022-04-21 09:16:05 +02:00
theolivenbaum
4308f2c6d6 Electron Release 17.4.1 2022-04-21 09:15:00 +02:00
theolivenbaum
87468ccd5d Update main.js 2022-04-20 13:05:25 +02:00
theolivenbaum
d863ff95f4 update to 18.0.4 2022-04-20 12:47:18 +02:00
theolivenbaum
3a24b69063 let user define own env variables to start 2022-04-20 12:36:51 +02:00
rafael-aero
d6c98759c5 handle also get nearest point 2022-04-13 20:53:33 +02:00
rafael-aero
6675571aaf handle fail on getdisplaymatching 2022-04-13 20:51:34 +02:00
rafael-aero
3f8766ff9e Build 17.4.0 2022-04-12 11:31:35 +02:00
rafael-aero
9b881b1b71 Roll back to electron 18.0.2
Roll back to electron 18.0.2
2022-04-12 10:41:28 +02:00
rafael-aero
339a319f3e fix race condition on electron socket initialization 2022-04-11 13:59:42 +02:00
rafael-aero
d929102e18 update to Electron 18.0.3 2022-04-10 22:37:43 +02:00
Gregor Biswanger
26595bf290 Refactor eslint hints 2022-04-06 22:34:56 +02:00
Gregor Biswanger
5ca65f1939 Update TypeScript 4.3.5 -> 4.6.3, replace typings to native socket.io 2022-04-06 22:33:54 +02:00
Gregor Biswanger
b4b355eeac Replace tslint with eslint 2022-04-06 22:33:06 +02:00
Gregor Biswanger
47774d2871 Update socket.io 2.4.0 -> 4.4.1, electron 13.1.5 -> 18.0.2, electron-updater 4.3.9 -> 4.6.5, replace tsint with eslint 2022-04-06 22:32:38 +02:00
Gregor Biswanger
43cbdc15b8 Merge branch 'yannikHoeflich-master' 2022-04-06 21:58:38 +02:00
Gregor Biswanger
540be39547 Merge fix: changed the processing of loadUrl at CreateWindowAsync #631 2022-04-06 21:58:20 +02:00
Gregor Biswanger
a7a8685341 Merge branch 'stackify-bug/644' 2022-04-06 19:20:13 +02:00
Gregor Biswanger
0575413768 Transpile new JavaScript host files 2022-04-06 19:19:46 +02:00
Gregor Biswanger
e8394277e7 Merge fix: Fix for #664, open for comment #644 2022-04-06 19:17:43 +02:00
Gregor Biswanger
5fe50b45bb Merge branch 'stackify-CrossPlatformNativeImage' 2022-04-06 19:03:35 +02:00
Gregor Biswanger
70ca42aeaf Merge fix: Conversion to use ImageSharp rather than System.Drawing.Common #658 2022-04-06 19:03:22 +02:00
Gregor Biswanger
f54ce1eb02 Merge branch 'stackify-feature/DI-MOC-Process' 2022-04-06 18:58:15 +02:00
Gregor Biswanger
aa9c2caf47 Merge fix: Support DI and Mocking better + Support launching app with file for win and linux #656 2022-04-06 18:58:02 +02:00
Gregor Biswanger
ba8e941cf1 Merge branch 'stackify-feature/dotnet-args' 2022-04-06 18:53:19 +02:00
Gregor Biswanger
f0003ae953 Merge fix: Support for additional dotnet publish flags #655 2022-04-06 18:52:58 +02:00
Gregor Biswanger
1f5d70be83 Merge branch 'schaveyt-feature/647-launching-app-w-file-win-linux' 2022-04-06 18:46:18 +02:00
Gregor Biswanger
1a1bd61e3e Merge fix: Support launching app with file for win and linux #648 2022-04-06 18:45:51 +02:00
Gregor Biswanger
709780fd04 Merge pull request #673 from MutatedGamer/parentOption
Add ability to set a window's parent using BrowserWindowOptions
2022-04-06 18:26:08 +02:00
Gregor Biswanger
9a17d22343 Merge branch 'stackify-NET6' 2022-04-06 18:10:31 +02:00
Gregor Biswanger
7222c9e6c5 Fix conflicts: Support for .NET 6 2022-04-06 18:10:18 +02:00
Gregor Biswanger
29b4f577a6 Merge pull request #634 from stackify/feature/RecentDocuments-Mac
Recent Document Support for MacOS
2022-04-06 16:35:00 +02:00
Gregor Biswanger
9698c80442 Merge pull request #633 from stackify/feature/DI-MOCK
Support DI and Mocking better.
2022-04-06 16:33:46 +02:00
Gregor Biswanger
4afa535c31 Merge pull request #626 from javierlarota/feature/ignore-cert-errors
Allow ignoring certificate errors
2022-04-06 16:30:00 +02:00
Gregor Biswanger
0de9699a52 Merge pull request #624 from bman46/master
Support Apple Silicon Natively
2022-04-06 16:28:14 +02:00
Gregor Biswanger
6f5fb16091 Merge pull request #595 from theolivenbaum/switch-to-new-socket-lib
Switch to async socket lib
2022-04-06 16:24:02 +02:00
Gregor Biswanger
891870abde Merge branch 'master' into switch-to-new-socket-lib 2022-04-06 16:23:47 +02:00
Gregor Biswanger
ab162d4829 Merge pull request #592 from Meberem/feature/log-dotnet-errors
Log errors in the dotnet process
2022-04-06 16:10:24 +02:00
rafael-aero
ec12dbd6ad Update electron to 18.0.2 2022-04-05 22:41:41 +02:00
rafael-aero
f05934acb8 Forgot to roll back to 18.0.1 2022-04-01 20:59:06 +02:00
rafael-aero
0632112a3a improve build command to try to read version from xml file 2022-04-01 19:03:09 +02:00
rafael-aero
793f714b9e Publish Electron 17.3.1 2022-04-01 18:37:16 +02:00
rafael-aero
e3fbce26d0 Remove default electron version parameter from CLI 2022-04-01 18:27:26 +02:00
rafael-aero
c45ea53a02 Update to Electron 18.0.1 2022-04-01 17:41:21 +02:00
rafael-aero
de56395946 Update to Electron 18.0.0 2022-03-29 10:13:20 +02:00
rafael-aero
b0262b36d0 Update electron to 17.3.0 2022-03-29 09:44:20 +02:00
rafael-aero
0ffecd5bc7 save projects 2022-03-25 12:12:35 +01:00
rafael-aero
b7196ff10d Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2022-03-25 12:11:10 +01:00
rafael-aero
93f1875f8b remove again SocketIOClient as package was updated 2022-03-25 12:11:08 +01:00
theolivenbaum
6ca5563dc1 Update build-nuget.yaml for Azure Pipelines 2022-03-25 12:03:54 +01:00
rafael-aero
e643d0db08 Update 2022-03-25 10:30:51 +01:00
rafael-aero
9c89711d59 Import SocketIOClient code until next version is released 2022-03-25 10:23:56 +01:00
rafael-aero
606b2a6481 Update main.js 2022-03-24 19:32:15 +01:00
rafael-aero
ef13ec9cc4 update electron to 17.2.0 2022-03-24 18:45:28 +01:00
rafael-aero
b58b4579f9 Add dotenv and electron-notarize dependencies 2022-03-24 11:46:17 +01:00
rafael-aero
13edd4c3ca fix multi thread usage missing lock 2022-03-23 12:18:52 +01:00
rafael-aero
967ccf385a Add support for random port assignment 2022-03-22 18:51:32 +01:00
MutatedGamer
4a44f3e150 Set parent in createBrowserWindow 2022-03-21 20:34:38 -07:00
MutatedGamer
d6e362c83c Add Parent property to BrowserWindowOptions 2022-03-21 20:34:25 -07:00
rafael-aero
df15d249de Update to 17.1.2 2022-03-10 08:38:32 +01:00
rafael-aero
a5bb3ad36b Update ElectronNET.API.csproj 2022-03-07 23:36:18 +01:00
rafael-aero
8f26ceed3d update socket.io 2022-03-07 23:13:16 +01:00
rafael-aero
7f282c1346 Update to 17.1.1 2022-03-07 22:06:48 +01:00
rafael-aero
8067f8e1ff Update to 17.1.0, remove soon to be deprecated nativeWindowOpen optiojn 2022-03-03 08:21:35 +01:00
Daniel Gidman
468c8ba2fc #644 Check for null before taking actions. Also localize references to window on window creation 2022-02-23 14:58:44 -06:00
Daniel Gidman
ab694e22fc Change IsReady logic to also wait for connection to be open. This is to prevent actions occurring before the app can act upon them. 2022-02-23 14:57:05 -06:00
Robert Muehsig
79a6ef322c Merge pull request #609 from AndreasJagiella-EH/master
Set PublishSingleFile default back to false for NET5 compatibility
2022-02-21 23:01:46 +01:00
Robert Muehsig
0ef5edfdf6 Merge pull request #613 from aguang-xyz/fix/npe-when-target-not-specified
Fix IndexOutOfRangeException in build command parsing logic
2022-02-21 22:55:01 +01:00
Robert Muehsig
7db609c699 Merge pull request #607 from gpgpublickey/build_adds_help_publish_parameters
Adds help regarding to modify publish parameters
2022-02-21 22:49:48 +01:00
Robert Muehsig
127408afdb Merge pull request #598 from tub5/tub5-readme-fix
Update README.md
2022-02-21 22:47:53 +01:00
rafael-aero
40eae5af3d update to 17.0.1 2022-02-15 14:15:32 +01:00
rafael-aero
26ba398428 Add new WCO height option 2022-02-10 23:00:33 +01:00
rafael-aero
56fe57db46 Update to 17.0.0 2022-02-10 09:55:56 +01:00
rafael-aero
c8552041fb Add debug messages for update methods 2022-02-10 00:00:51 +01:00
rafael-aero
13a3753214 emit prepare-for-update 2022-02-09 22:18:04 +01:00
rafael-aero
93ee1871ee update electron to 16.0.8 2022-01-30 20:43:39 +01:00
Daniel Gidman
86644e7366 #637 Conversion to use ImageSharp rather than System.Drawing.Common for cross platform compatibility.
Breaking Changes:

* `System.Drawing.Common` is dropped and `SixLabors.ImageSharp` is introduced.
* uses of `NativeImage.CreateFromBitmap(bitmap, options);` is no longer supported, will cause failed builds.

Unexpected Behaviors:

* uses ToDataUrl will always create png data urls, unexpected output may happen for those that manipulate this output expecting a different data url format.

Obsoletions:

* `CreateFromBitmapOptions` & `CreateFromBufferOptions` have been consolidated into `CreateOptions`. Implicit conversions added to ease transition.
* `ToBitmapOptions`, `ToDataUrlOptions`, `ToPngOptions` & `BitmapOptions` have been consolidated into `ImageOptions`. Implicit conversions added to ease transition.
2022-01-26 11:07:48 -06:00
Daniel Gidman
2331ef43b4 Support electronize as a dotnet 6 target tool 2022-01-25 14:08:40 -06:00
Daniel Gidman
b8845bb402 Include Process into DI Mocking and interfaces 2022-01-25 10:45:49 -06:00
Daniel Gidman
1767bcd5ad Merge commit '64e058b0b59a4fbbd6c0ec9de2ee1850a66684c4' into feature/DI-MOC-Process
# Conflicts:
#	ElectronNET.API/ServiceCollectionExtensions.cs
2022-01-25 10:41:42 -06:00
Daniel Gidman
5338749e4d Fixed extraction of arguments 2022-01-21 20:03:31 -06:00
Daniel Gidman
4790c4ebb2 Support for additional dotnet publish flags. 2022-01-21 16:51:30 -06:00
rafael-aero
d646b84c74 update 16.0.7 2022-01-13 11:49:41 +01:00
Todd Schavey
64e058b0b5 #647 make ProcessVersions Entity a record to ensure readonly access to props
This is to address a PR #648 review comment to ensure that only the external
users are not able to modify the instance values.
2022-01-04 12:11:52 -05:00
Todd Schavey
24a2005776 #647 update XML documentation to ElectronNET.API Process members 2022-01-03 00:21:48 -05:00
Todd Schavey
592148116b #647 correct to ElectronNET.API Process member for versions field 2022-01-02 23:11:01 -05:00
Todd Schavey
ba82b9a600 #647 add to ElectronNET.API Process member interfaces for various fields 2022-01-02 22:46:53 -05:00
Todd Schavey
562cccbfae #647 add to ElectronNET.API Process member interfaces for argv and type 2022-01-02 18:28:39 -05:00
Todd Schavey
1406fc1d79 #647 add initial Process class to ElectronNET.API 2022-01-02 16:46:14 -05:00
Todd Schavey
8e1e184d1e #647 process argv for open-file for win and linux 2021-12-28 21:40:53 -05:00
rafael-aero
9e37d4d857 fix serializtion 2021-12-26 11:00:51 +01:00
rafael-aero
060fb19a6d Update NativeImageJsonConverter.cs 2021-12-26 09:46:55 +01:00
rafael-aero
291faa48de Missing including new file 2021-12-26 09:27:45 +01:00
rafael-aero
4358178524 Add support for DesktopCapturer 2021-12-26 09:03:48 +01:00
Daniel Gidman
4b314940d7 Update ElectronNET.sln
removing the full path reference as suggested.

Co-authored-by: alborozd <alborozd@gmail.com>
2021-12-23 10:54:44 -06:00
rafael-aero
ed841558b8 always exit if .net process exited 2021-12-23 16:54:06 +01:00
rafael-aero
36751db618 fix missing pipe option for detached process 2021-12-23 10:09:08 +01:00
rafael-aero
f229d540a8 Add simple socket auth via stdin exchange 2021-12-23 09:24:29 +01:00
rafael-aero
546c617cd0 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-12-17 13:29:49 +01:00
rafael-aero
88e8051004 update electron and electron updater 2021-12-17 13:29:47 +01:00
theolivenbaum
21427f0b44 Merge pull request #5 from theolivenbaum/clipboard-image-support-macos
add support for images in clipboards on macos
2021-12-15 18:31:49 +01:00
Pius Friesch
159c1f46c1 add support for images in clipboards on macos 2021-12-15 17:58:38 +01:00
rafael-aero
8cb235527d Change again socket reconnect logic 2021-12-15 10:44:59 +01:00
theolivenbaum
4a3a5c6aa4 Merge pull request #4 from theolivenbaum/clipboard
Clipboard
2021-12-13 18:13:47 +01:00
Pius Friesch
82bf94b2a2 fix writing images to clipboard when writing multiple formats 2021-12-13 17:40:57 +01:00
Pius Friesch
17a7886d12 formatting 2021-12-13 17:33:00 +01:00
Pius Friesch
6be3019cb6 fix typescript, based on changes to js 2021-12-13 17:31:48 +01:00
rafael-aero
3460217021 refactor socket reconnect 2021-12-13 16:22:08 +01:00
rafael-aero
427592de46 Add background thread to reconnect socket 2021-12-13 14:43:04 +01:00
rafael-aero
8f820d033a Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-12-13 14:10:40 +01:00
rafael-aero
4118756711 change socket connect loop 2021-12-13 14:10:38 +01:00
Daniel Gidman
ffdf034f5f appveyor dedicated build 2021-12-09 14:01:55 -06:00
Daniel Gidman
946fbd7a72 Update appveyor image 2021-12-09 13:51:13 -06:00
Daniel Gidman
6b0205467b Support for .NET 6
Also included is the ability to target a specific project in the `electronize build/start` command using /dotnet-project
2021-12-09 13:11:24 -06:00
theolivenbaum
a28df5339d Merge pull request #3 from pfriesch/patch-1
Add Image to clipboard data
2021-12-09 17:50:54 +01:00
rafael-aero
f5a141a1c6 Update ElectronNET.API.csproj 2021-12-09 17:50:43 +01:00
Pius Friesch
b5e2b660f7 Add Image to clipboard data 2021-12-09 17:46:30 +01:00
javierlarota
431e401451 Feedback from code review. Improving logging of the domain names that will be ignored. 2021-12-09 04:22:35 +00:00
Daniel Gidman
02faeae603 Add support for Mac recent documents and clear recent documents commands on the Application Menu 2021-12-08 13:32:00 -06:00
Yannik Höflich
0d9483e325 Updated TryParseLoadUrl with UriBuilder for better readability 2021-12-08 17:30:44 +01:00
Daniel Gidman
1b14bb0fe5 Convert main static references off of Electron into interface implementation and expose the underlying Socket for low level interaction. 2021-12-07 11:52:43 -06:00
Brendan McShane
b08a0755e6 Revert automatic change by VS 2021-12-07 12:23:26 -05:00
Brendan McShane
7e89e27c26 Better way to check version
Checks to see if the dotnet 6 or greater is running.
2021-12-06 20:28:57 -05:00
Brendan McShane
e4deba2489 Add dotnet 6 check
Ensure that dotnet 6 is installed when compiling for MacOS ARM.
2021-12-06 20:17:46 -05:00
Brendan McShane
1d9e540fc2 Change back to dotnet 5 2021-12-06 20:17:08 -05:00
Yannik Höflich
c7d2dabbc3 changed the usage of loadUrl at CreateWindowAsync: adds protocol, host and port. You can also insert the port with {port} 2021-12-05 16:31:32 +01:00
theolivenbaum
2d940dbeee update to electron 16.0.4 2021-12-03 09:16:44 +01:00
javierlarota
d9d655cae8 Allow ignoring certificate errors when using an untrusted self-signed certificate for https communication with the AspCore backend.
We can ignore all cert errors or only cert errors from specific domain names configured in electron.manifest.json
2021-11-26 18:03:54 +00:00
theolivenbaum
1b7f722f31 Update Electron to 16.0.2, update electron-updater to 4.6.1 2021-11-25 08:06:49 +01:00
rafael-aero
b1c5c12004 fix null usage on ipc.js 2021-11-22 17:33:50 +01:00
rafael-aero
af0410998e update screenshot code 2021-11-22 11:38:16 +01:00
Brendan McShane
e0e8572cc1 Update README.md
Add notes about osx-arm64.
2021-11-20 21:35:02 -05:00
Brendan McShane
4ba8d9bf46 Add fix for Apple Silicon to build command 2021-11-20 18:25:46 -05:00
Brendan McShane
07d6fed712 Fix for build command 2021-11-20 18:24:41 -05:00
Brendan McShane
5dbe62bcba Add osx-arm64 support to electronize command
Updates the GetTargetPlatformInformationResult() function to add 'osx-arm64' target. 
Updates the 'default' case to automatically detect M1 mac.
2021-11-20 17:59:53 -05:00
Brendan McShane
438c8e1f14 Switch from dotnet 5.0 to dotnet 6.0
The 'osx-arm64' RID is only supported on .net versions greater than 6.0.
https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
2021-11-20 17:56:33 -05:00
rafael-aero
ffedbcc5df Add missing GetFileIcon method 2021-11-20 16:37:38 +01:00
rafael-aero
9aad72431c Update electron to 16.0.1 2021-11-18 20:08:31 +01:00
rafael-aero
4405eba2d5 Add support for dark mode splashscreen 2021-11-17 14:19:07 +01:00
rafael-aero
067300bfec update nuget packages 2021-11-16 14:02:17 +01:00
theolivenbaum
b2f5a0eb34 Update to Electron 16 2021-11-16 06:45:59 +01:00
theolivenbaum
cbc150db06 Update to Electron 15.3.2 2021-11-16 06:43:15 +01:00
theolivenbaum
cbac8541be Add transparent option to webpreferences 2021-11-13 11:13:35 +01:00
rafael-aero
2f9029e267 add launch settings to test build 2021-11-10 11:07:46 +01:00
rafael-aero
390135af8a Revert "move .NET bin output to under Helpers folder to be compliant with macOS bundle formt "
This reverts commit be1182d302.
2021-11-10 11:06:40 +01:00
theolivenbaum
be1182d302 move .NET bin output to under Helpers folder to be compliant with macOS bundle formt 2021-11-10 07:57:22 +01:00
theolivenbaum
54c86d9e2f Fix auto-updater on mac not working 2021-11-10 07:46:25 +01:00
rafael-aero
2cc6823604 Update electron to 15.3.1 2021-11-09 18:16:45 +01:00
rafael-aero
326efd353c Update sdk to 6.0.100 2021-11-09 18:16:32 +01:00
rafael-aero
bd96765db5 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-11-05 11:01:33 +01:00
rafael-aero
606bb019f7 fix race condition causing unobserved exception 2021-11-05 11:01:32 +01:00
theolivenbaum
a12a7e4287 Update main.js 2021-11-03 07:51:59 +01:00
rafael-aero
5bf9aa811d Update main.js 2021-11-02 18:20:59 +01:00
rafael-aero
5477bd7f36 Add setImmediate to see if this fixes the macOS update bug 2021-11-02 15:39:57 +01:00
rafael-aero
134a5b1365 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-10-29 10:54:45 +02:00
rafael-aero
23791fcc3e fix path detection 2021-10-29 10:54:42 +02:00
theolivenbaum
751c48c804 Update Vibrancy.cs 2021-10-27 22:06:52 +02:00
theolivenbaum
316cf0108e Update Vibrancy.cs 2021-10-27 21:57:24 +02:00
rafael-aero
4caa28dc87 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-10-27 14:10:09 +02:00
rafael-aero
ad46b1a7a2 remove listeners on quitAndInstall to try fix macOS update issue 2021-10-27 14:10:07 +02:00
theolivenbaum
2297669e6d Update main.js 2021-10-27 09:11:33 +02:00
theolivenbaum
ae92973814 Update main.js 2021-10-26 22:58:54 +02:00
theolivenbaum
5ebfa2b0bd Update main.js 2021-10-26 21:34:35 +02:00
rafael-aero
1494c2f436 Update main.js 2021-10-26 18:15:37 +02:00
rafael-aero
84f027cd8d remove listeners on the call to before-quit-for-update 2021-10-26 16:27:44 +02:00
rafael-aero
f213ca4f8c move code for fixPath here 2021-10-26 15:58:55 +02:00
rafael-aero
22fa3f2780 Revert "Add fixPath to fix linux process spawn"
This reverts commit 1e50f203d8.
2021-10-26 15:41:02 +02:00
rafael-aero
b5cc631daf Revert "Update main.js"
This reverts commit b5ff42a148.
2021-10-26 15:41:00 +02:00
rafael-aero
b5ff42a148 Update main.js 2021-10-26 15:35:06 +02:00
rafael-aero
1e50f203d8 Add fixPath to fix linux process spawn
As suggested in https://github.com/electron/electron-packager/issues/603
2021-10-25 13:35:02 +02:00
rafael-aero
852b140525 Update to 15.3.0 2021-10-22 11:09:17 +02:00
rafael-aero
7e5903f5bc update to electron 15.1.2 2021-10-12 13:11:29 +02:00
rafael-aero
62003ae5fc Update BuildCommand.cs 2021-10-11 19:36:41 +02:00
Grey Wang
5cd152c1ed Fix build command logic when target is not specified 2021-10-09 20:41:12 +13:00
rafael-aero
228a5cef31 set missing return value
https://github.com/electron/electron/issues/31321
2021-10-07 18:13:32 +02:00
rafael-aero
c28355094e Update build-nuget.yaml 2021-10-07 17:54:28 +02:00
rafael-aero
329df38765 Update to Electron 15.1.1 2021-10-07 17:52:15 +02:00
AndreasJagiella-EH
5274fec200 Set PublishSingleFile default back to false for NET5 compatibility 2021-10-04 14:54:02 +02:00
Cristian Giagante
9892a90038 Adds help regarding to modify publish parameters 2021-09-26 19:54:25 -03:00
theolivenbaum
1d1e60bc63 Missed updating the nuget package version 2021-09-22 09:06:41 +02:00
theolivenbaum
21b6b14df5 Update Node to v16.9.6 2021-09-22 08:56:58 +02:00
theolivenbaum
2445b59c4d Update Electron to v15.0.0 2021-09-22 08:55:04 +02:00
rafael-aero
9a8584795b update to net6.0 2021-09-17 18:16:31 +02:00
rafael-aero
e6ea9883fd code cleanup 2021-09-17 16:05:40 +02:00
rafael-aero
e1edc764d6 update electron to 14.0.1 2021-09-16 19:39:16 +02:00
rafael-aero
51013d5825 code cleanup 2021-09-15 11:14:45 +02:00
rafael-aero
664d5f7236 Add method to get window by id 2021-09-15 11:02:54 +02:00
rafael-aero
75d7924251 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-09-15 10:58:45 +02:00
rafael-aero
c2904f3f68 Change second instance activation to raise event instead of trying to blindly open any window 2021-09-15 10:58:43 +02:00
theolivenbaum
adef39f3ec Change flags to nullable 2021-09-10 10:53:49 +02:00
theolivenbaum
836eebf256 Update browserWindows.js 2021-09-10 10:13:23 +02:00
theolivenbaum
124d24a19c Update browserWindows.ts 2021-09-10 10:12:56 +02:00
theolivenbaum
67ea8c768e Update BrowserWindow.cs 2021-09-10 10:11:41 +02:00
theolivenbaum
8604b50224 Add method to destroy all windows manually 2021-09-08 08:57:05 +02:00
theolivenbaum
5559fc61b1 force-destroy all windows on before-quit-for-update 2021-09-08 08:47:16 +02:00
theolivenbaum
9be80abfcf Add method to destroy splashscreen 2021-09-07 19:19:49 +02:00
theolivenbaum
6a4a7eff1c Workaround for electron freeze bug 2021-09-07 17:48:12 +02:00
theolivenbaum
a637174b93 typo 2021-09-07 15:00:35 +02:00
theolivenbaum
dc2662e52e Add way to set flags for Electron before the app starts 2021-09-07 14:36:57 +02:00
theolivenbaum
801616cd53 Let users set the color of the titlebar instead of just enabling it 2021-09-06 15:54:32 +02:00
theolivenbaum
9693c82792 Add TitleBarOverlay option 2021-09-06 15:18:59 +02:00
theolivenbaum
a3fb411d8a always keep default values when creating window 2021-09-06 12:39:32 +02:00
theolivenbaum
172f6ded3f Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-09-06 11:45:01 +02:00
theolivenbaum
bbbc9e6f61 make splashscreen draggable 2021-09-06 11:44:57 +02:00
rafael-aero
236c31abe0 Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-09-03 15:28:34 +02:00
rafael-aero
374d92f3b1 don't throw in case the tray was destroyed between calls 2021-09-03 15:28:32 +02:00
theolivenbaum
ea40249a9c refactor Socket to use a task completion source instead of a getter with locks 2021-09-02 20:37:22 +02:00
theolivenbaum
7f5db58edd fix deadlock case on emit before any Socket use 2021-09-02 20:06:01 +02:00
theolivenbaum
d18700f64d missing static flag 2021-09-02 18:29:02 +02:00
theolivenbaum
47f4516ae2 Add flag to check if the socket is connected 2021-09-02 18:20:11 +02:00
theolivenbaum
bb8965fa91 remove semaphore in favor of unique events per window /view create request 2021-09-02 17:24:07 +02:00
theolivenbaum
c229d49765 remove debug message 2021-09-02 16:45:20 +02:00
theolivenbaum
4fae2aeef2 fix ipc data serialization 2021-09-02 16:45:03 +02:00
theolivenbaum
5f4b1628e5 fix display serialization, serialize only window id when sending ipc message 2021-09-02 16:34:20 +02:00
theolivenbaum
25af4a7314 Update to Electron 14 2021-09-02 16:18:56 +02:00
rafael-aero
14ee45b88f Another attempt 2021-09-01 22:37:58 +02:00
rafael-aero
badc9f26b6 Revert "fix closed behaviour"
This reverts commit 4e7cebe519.
2021-09-01 22:25:50 +02:00
rafael-aero
4e7cebe519 fix closed behaviour 2021-09-01 22:10:44 +02:00
rafael-aero
ec74c7989a Update ipc.js 2021-09-01 21:31:30 +02:00
rafael-aero
a2579b221f fix wrong Id being passed - needed browser id, not webcontent id 2021-09-01 21:30:47 +02:00
rafael-aero
1e7ff5b6d6 fix getting id 2021-09-01 20:57:41 +02:00
rafael-aero
eac14427df Add event handler with sender id 2021-09-01 20:42:49 +02:00
rafael-aero
794248a83c fix creation of windows not being thread safe 2021-09-01 20:02:17 +02:00
rafael-aero
9a938dc680 use concurrent dictionary instead of list 2021-09-01 18:59:15 +02:00
rafael-aero
2d68ca5270 Fix LogError call 2021-09-01 18:29:20 +02:00
rafael-aero
548609f69b add handler for errors on socket.on calls 2021-09-01 18:28:44 +02:00
rafael-aero
7b5bac2083 Fix property assignment 2021-09-01 14:08:30 +02:00
rafael-aero
5ba10136e2 Add excludedFromShownWindowsMenu and TrafficLightPosition 2021-09-01 14:07:45 +02:00
tub5
aba77b1361 Update README.md
Fixed versions on the README
2021-08-31 11:56:26 +01:00
rafael-aero
bd45e23768 remove recreate behaviour from activate event on mac, and emit event to handler instead 2021-08-30 13:22:07 +02:00
rafael-aero
35b18a9501 ignore process closing if going for an update 2021-08-26 17:04:16 +02:00
rafael-aero
89d41a2750 restore serialization settings where it makes sense 2021-08-26 16:08:11 +02:00
rafael-aero
efdaf0e341 remove defaultvaluehandling setting as this breaks some cases
(like X:0 on browser view set bounds)
2021-08-26 15:59:52 +02:00
rafael-aero
0728577c40 missing using 2021-08-26 14:23:32 +02:00
rafael-aero
224bc1ef65 Add supported OS platform annotations 2021-08-26 14:22:54 +02:00
rafael-aero
7ad6803671 improve reconnect logic by waiting for reconnect before emit 2021-08-26 10:31:06 +02:00
rafael-aero
81a8367dac improve reconnect logic 2021-08-26 10:19:24 +02:00
rafael-aero
1161f59836 Update BridgeConnector.cs 2021-08-26 10:08:42 +02:00
rafael-aero
e7c56274e6 Update BridgeConnector.cs 2021-08-26 09:55:24 +02:00
rafael-aero
44d979fef4 Use ILogger instead of Console.WriteLine 2021-08-26 09:55:14 +02:00
theolivenbaum
2f0229235b fix for socket not being thread-safe 2021-08-26 08:40:36 +02:00
rafael-aero
18d425b042 Merge branch 'master' into switch-to-new-socket-lib 2021-08-25 17:08:53 +02:00
rafael-aero
5e82ae4246 add socket events to emit console messages 2021-08-25 13:38:30 +02:00
rafael-aero
48d5497045 Revert "Update main.js"
This reverts commit be41cae3bd.
2021-08-25 13:33:50 +02:00
rafael-aero
be41cae3bd Update main.js 2021-08-25 13:24:44 +02:00
rafael-aero
64b91fc235 Update main.js 2021-08-25 13:04:23 +02:00
rafael-aero
efec886f73 Update main.js 2021-08-25 11:33:32 +02:00
rafael-aero
8b03a6b006 remove stdio handling for detached case 2021-08-25 11:27:46 +02:00
rafael-aero
144a0a0ddc change argument name, detach process on creation 2021-08-25 11:14:21 +02:00
rafael-aero
8bbe6a96af Fix serialization of array of objects 2021-08-25 10:34:36 +02:00
rafael-aero
e39e34234d Update ProcessHelper.cs 2021-08-25 09:54:00 +02:00
rafael-aero
67c592a060 kill child process when electronize cli is killed 2021-08-25 09:38:37 +02:00
rafael-aero
bad59463a9 pass electron process id to child 2021-08-25 09:17:50 +02:00
rafael-aero
94efaf835e Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET 2021-08-25 09:10:29 +02:00
rafael-aero
ac77643fc4 add variable to control kill behaviour 2021-08-25 09:10:27 +02:00
theolivenbaum
0393b0bd45 Merge branch 'master' into switch-to-new-socket-lib 2021-08-24 05:31:57 +02:00
theolivenbaum
953f1e2641 fix event names for when there are more than one window, view or webcontent Id 2021-08-24 05:31:46 +02:00
rafael-aero
fb99dbd5b5 add null return to avoid having to check for undefined 2021-08-23 18:28:00 +02:00
rafael-aero
fdbf7187b9 Update browserWindows.js 2021-08-23 15:30:47 +02:00
rafael-aero
9a680a41ac improve how we handle when window has been destroyed already 2021-08-23 14:59:41 +02:00
rafael-aero
f9693ce624 handle destroyed windows 2021-08-23 14:29:41 +02:00
rafael-aero
0090a7c239 fix wrong completed event name 2021-08-23 13:24:02 +02:00
rafael-aero
81431599ec Update ElectronNET.API.csproj 2021-08-23 13:01:38 +02:00
rafael-aero
31094f9d2b Remove unecessary JsonSerializer settings, fix default serializer 2021-08-23 11:57:42 +02:00
rafael-aero
bf48bc8227 replace remaining cases with OnResult, fix deserialization of json objects 2021-08-23 11:22:37 +02:00
rafael-aero
87d97efcfa Merge branch 'master' into switch-to-new-socket-lib 2021-08-21 09:17:43 +02:00
theolivenbaum
da9d9658f5 Update main.js 2021-08-21 09:17:20 +02:00
theolivenbaum
444c09fb4d Update main.js 2021-08-21 08:26:43 +02:00
rafael-aero
ca9bee7bf0 Merge branch 'master' into switch-to-new-socket-lib 2021-08-20 15:16:16 +02:00
rafael-aero
0aab352f86 remove yield call 2021-08-20 15:07:39 +02:00
rafael-aero
a8229f2fa9 add internal method to emit socket events synchronously, and use it for all exit, quit and relaunch methods 2021-08-20 15:06:58 +02:00
rafael-aero
9daaebcef6 Add timeout property for splashscreen 2021-08-20 14:56:47 +02:00
rafael-aero
67b59d95d4 fix quotes 2021-08-20 14:52:33 +02:00
rafael-aero
8f71480b3e Merge branch 'master' into switch-to-new-socket-lib 2021-08-20 14:49:56 +02:00
rafael-aero
133dcd6b65 Fix exit method 2021-08-20 14:49:49 +02:00
rafael-aero
d9a7411904 Merge branch 'master' into switch-to-new-socket-lib 2021-08-20 14:36:09 +02:00
rafael-aero
b42eba8a70 Handle non-zero exit codes from ASP.NET process 2021-08-20 14:36:02 +02:00
rafael-aero
e8e3649925 Merge branch 'master' into switch-to-new-socket-lib 2021-08-19 14:50:46 +02:00
rafael-aero
b6338ac7de log error messages from asp-net process 2021-08-19 14:50:30 +02:00
rafael-aero
b708b4b622 reset default values 2021-08-18 10:48:55 +02:00
rafael-aero
336c3b9400 cleanup for merge 2021-08-18 10:42:24 +02:00
rafael-aero
bd08938c49 Delete build-nuget.yaml 2021-08-18 10:32:41 +02:00
rafael-aero
cbe0637e84 Simplify repeated code with OnResult method, fix race condition with multiple calls to On/Off for the same event 2021-08-18 10:24:12 +02:00
rafael-aero
8063f49e4b run all continuations asyncronously 2021-08-17 16:28:07 +02:00
rafael-aero
d6b29f7350 avoid calling npm install if nothing changed 2021-08-09 17:43:54 +02:00
rafael-aero
237638a5b3 add command for simple build 2021-08-09 17:32:24 +02:00
Matt
b910807ced Log errors in the dotnet process 2021-08-04 17:33:09 +02:00
rafael-aero
7fe8f6e49e fix wrong object initializer 2021-07-21 17:04:29 +02:00
rafael-aero
c4ff481131 add debug option 2021-07-21 10:42:04 +02:00
rafael-aero
9107b161b3 Add prototype from-build-output command 2021-07-13 11:25:00 +02:00
rafael-aero
ec2261f1c5 Remove wrong ReleaseNoteInfo model 2021-07-13 09:08:31 +02:00
theolivenbaum
b03bc7c9eb Clean-up 2021-07-12 21:33:35 +02:00
theolivenbaum
e6214491cf Merge pull request #2 from theolivenbaum/remove-deprecated-socket-lib
Remove deprecated socket lib
2021-07-12 21:28:07 +02:00
theolivenbaum
95d614796e works 2021-07-12 21:27:40 +02:00
rafael-aero
126d39f4a5 wip 2021-07-12 19:50:39 +02:00
rafael-aero
8880e040f7 remove remaining .Result calls 2021-07-12 18:16:07 +02:00
rafael-aero
f200013165 add custom property handle for electronize start command 2021-07-12 17:05:26 +02:00
rafael-aero
82755e399d Add comments 2021-07-12 15:54:23 +02:00
rafael-aero
f07f2e9506 Update build-nuget.yaml 2021-07-12 15:53:02 +02:00
rafael-aero
83fd5a5d4b Add manual initialization methods 2021-07-12 15:52:30 +02:00
rafael-aero
6dee08379c Merge remote-tracking branch 'upstream/master' 2021-07-12 09:24:32 +02:00
rafael-aero
8f5a7856d5 use new Electron 12 default values 2021-06-28 16:30:24 +02:00
rafael-aero
f78573401a fix strange issue with capitalization of assembly name 2021-06-28 16:08:00 +02:00
rafael-aero
d8ba9d9372 change assembly name 2021-06-28 15:48:15 +02:00
rafael-aero
09cb7a640f Update EmbeddedFileHelper.cs 2021-06-28 15:43:55 +02:00
rafael-aero
2f3d2c00b6 print all resource names 2021-06-28 15:43:40 +02:00
rafael-aero
3b7b592ac8 fix name on resource path 2021-06-28 15:21:41 +02:00
rafael-aero
bcbe76211c Add option to set electron version 2021-06-28 15:04:26 +02:00
rafael-aero
505a5b2204 fix NPM install 2021-06-28 15:01:10 +02:00
rafael-aero
468a4fa35b fix package name 2021-06-28 14:35:59 +02:00
rafael-aero
94b5faafcd add publish to nuget 2021-06-28 14:31:33 +02:00
rafael-aero
f08711e41b Fix variables 2021-06-28 14:26:27 +02:00
theolivenbaum
1a6d50d77a Set up CI with Azure Pipelines
[skip ci]
2021-06-28 14:19:47 +02:00
rafael-aero
d188baaaff Merge remote-tracking branch 'MiniguyBrendan/master' 2021-06-28 14:11:08 +02:00
rafael-aero
916eecf117 Merge branch 'bug/578' 2021-06-28 14:08:45 +02:00
685 changed files with 19007 additions and 36233 deletions

84
.devops/build-nuget.yaml Normal file
View File

@@ -0,0 +1,84 @@
variables:
PackageVersion: 19.0.9.$(Build.BuildId)
projectAPI: './ElectronNET.API/ElectronNET.API.csproj'
projectCLI: './ElectronNET.CLI/ElectronNET.CLI.csproj'
trigger:
- master
pool:
vmImage: windows-latest
steps:
- checkout: self
submodules: true
fetchDepth: 10
- task: NuGetToolInstaller@1
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
packageType: sdk
version: 6.0.100
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: DotNetCoreCLI@2
displayName: 'restore nuget'
inputs:
command: 'restore'
projects: '$(projectAPI)'
- task: DotNetCoreCLI@2
displayName: 'restore nuget'
inputs:
command: 'restore'
projects: '$(projectCLI)'
- task: DotNetCoreCLI@2
inputs:
command: 'build'
projects: '$(projectAPI)'
arguments: '--configuration Release --force /property:Version=$(PackageVersion)'
- task: DotNetCoreCLI@2
inputs:
command: 'build'
projects: '$(projectCLI)'
arguments: '--configuration Release --force /property:Version=$(PackageVersion)'
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '$(projectAPI)'
configuration: 'Release'
versioningScheme: 'off'
buildProperties: 'Version=$(PackageVersion)'
arguments: -IncludeReferencedProjects
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '$(projectCLI)'
configuration: 'Release'
versioningScheme: 'off'
buildProperties: 'Version=$(PackageVersion)'
- task: NuGetCommand@2
displayName: 'push API to nuget'
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/h5.ElectronNET.API.$(PackageVersion).nupkg'
nuGetFeedType: 'external'
publishFeedCredentials: 'nuget-curiosity'
- task: NuGetCommand@2
displayName: 'push CLI to nuget'
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/h5.ElectronNET.CLI.$(PackageVersion).nupkg'
nuGetFeedType: 'external'
publishFeedCredentials: 'nuget-curiosity'

2
.github/FUNDING.yml vendored
View File

@@ -1,6 +1,6 @@
# These are supported funding model platforms
github: [GregorBiswanger, FlorianRappl]
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

BIN
.github/WikiLinks.exe vendored

Binary file not shown.

View File

@@ -1,51 +0,0 @@
name: CI
on: [push, pull_request]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
jobs:
# linux:
# runs-on: ubuntu-latest
# timeout-minutes: 10
# steps:
# - uses: actions/checkout@v4
# - name: Setup dotnet
# uses: actions/setup-dotnet@v4
# with:
# dotnet-version: |
# 6.0.x
# 8.0.x
# 10.0.x
# - name: Build
# run: ./build.sh
windows:
runs-on: windows-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
10.0.x
- name: Build
run: |
if ($env:GITHUB_REF -eq "refs/heads/main") {
.\build.ps1 -Target Publish
} elseif ($env:GITHUB_REF -eq "refs/heads/develop") {
.\build.ps1 -Target PrePublish
} else {
.\build.ps1
}

View File

@@ -1,59 +0,0 @@
name: Publish wiki
on:
push:
branches: [electronnet_core, main]
workflow_dispatch:
concurrency:
group: publish-wiki
cancel-in-progress: true
permissions:
contents: write
jobs:
publish-wiki:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Remove level 1 headings from Markdown files
shell: bash
run: |
find docs/ -name '*.md' -exec sed -i '1d' {} \;
- name: Move all files to root folder
shell: bash
run: |
mv docs/*/* docs/
- name: Delete unwanted files
shell: bash
run: |
# rm docs/*.xlsm
# rm docs/*.pptx
rm docs/*.shproj
- name: Stripping file extensions....
uses: softworkz/strip-markdown-extensions-from-links-action@main
with:
path: ./docs/
- name: Copy Changelog
shell: bash
run: |
cp Changelog.md docs/RelInfo/ 2>/dev/null || true
- name: Copy images to wiki/wiki folder
shell: bash
run: |
mkdir docs/wiki
cp docs/*.svg docs/wiki/ 2>/dev/null || true
cp docs/*.png docs/wiki/ 2>/dev/null || true
cp docs/*.jpg docs/wiki/ 2>/dev/null || true
cp docs/*.gif docs/wiki/ 2>/dev/null || true
cp docs/*.mp4 docs/wiki/ 2>/dev/null || true
- name: Commit and push changes
run: |
git config --global user.name "GitHub Action"
git config --global user.email "action@github.com"
git add -A
git commit -m "Automatically update Markdown files" || echo "No changes to commit"
- uses: Andrew-Chen-Wang/github-wiki-action@v4.4.0
with:
path: docs/
ignore: |
'**/*.xlsm'
'**/*.pptx'
'**/*.shproj'

6
.gitignore vendored
View File

@@ -44,7 +44,7 @@ dlldata.c
project.lock.json
project.fragment.lock.json
artifacts/
!/artifacts/.gitkeep
!/artifacts/readme.md
*_i.c
*_p.c
@@ -263,7 +263,3 @@ __pycache__/
# Mac Only settings file
.DS_Store
# Nuke build tool
.nuke/temp
/publish.cmd

View File

@@ -1,137 +0,0 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Host": {
"type": "string",
"enum": [
"AppVeyor",
"AzurePipelines",
"Bamboo",
"Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
"Jenkins",
"Rider",
"SpaceAutomation",
"TeamCity",
"Terminal",
"TravisCI",
"VisualStudio",
"VSCode"
]
},
"ExecutableTarget": {
"type": "string",
"enum": [
"Clean",
"Compile",
"Default",
"Package",
"PrePublish",
"Publish",
"PublishPackages",
"PublishPreRelease",
"PublishRelease",
"Restore",
"RunUnitTests"
]
},
"Verbosity": {
"type": "string",
"description": "",
"enum": [
"Verbose",
"Normal",
"Minimal",
"Quiet"
]
},
"NukeBuild": {
"properties": {
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
"Help": {
"type": "boolean",
"description": "Shows the help text for this build assembly"
},
"Host": {
"description": "Host for execution. Default is 'automatic'",
"$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
"Partition": {
"type": "string",
"description": "Partition to use on CI"
},
"Plan": {
"type": "boolean",
"description": "Shows the execution plan (HTML)"
},
"Profile": {
"type": "array",
"description": "Defines the profiles to load",
"items": {
"type": "string"
}
},
"Root": {
"type": "string",
"description": "Root directory during build execution"
},
"Skip": {
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
"$ref": "#/definitions/ExecutableTarget"
}
},
"Verbosity": {
"description": "Logging verbosity during build execution. Default is 'Normal'",
"$ref": "#/definitions/Verbosity"
}
}
}
},
"allOf": [
{
"properties": {
"CommonPropsFilePath": {
"type": "string",
"description": "common.props file path - to determine the configured version"
},
"Configuration": {
"type": "string",
"description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
"enum": [
"Debug",
"Release"
]
},
"ReleaseNotesFilePath": {
"type": "string",
"description": "ReleaseNotesFilePath - To determine the lates changelog version"
},
"Solution": {
"type": "string",
"description": "Path to a solution file that is automatically loaded"
}
}
},
{
"$ref": "#/definitions/NukeBuild"
}
]
}

View File

@@ -1,4 +0,0 @@
{
"$schema": "./build.schema.json",
"Solution": "src/ElectronNET.Lean.sln"
}

8
.travis.yml Normal file
View File

@@ -0,0 +1,8 @@
language: csharp
mono: none
dist: xenial
dotnet: 3.1
before_script:
- export PATH="$PATH:/home/travis/.dotnet/tools"
script:
- ./buildAll.sh

4
.vscode/launch.json vendored
View File

@@ -10,9 +10,9 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceRoot}/src/ElectronNET.CLI/bin/Debug/net8.0/dotnet-electronize.dll",
"program": "${workspaceRoot}/ElectronNET.CLI/bin/Debug/netcoreapp2.0/dotnet-electronize.dll",
"args": [],
"cwd": "${workspaceRoot}/src/ElectronNET.CLI",
"cwd": "${workspaceRoot}/ElectronNET.CLI",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
"console": "internalConsole",
"stopAtEntry": false,

37
.vscode/tasks.json vendored
View File

@@ -1,18 +1,21 @@
{
"version": "2.0.0",
"command": "dotnet",
"args": [],
"tasks": [
{
"label": "build",
"type": "shell",
"command": "dotnet",
"args": ["build", "${workspaceRoot}/src/ElectronNET.CLI/ElectronNET.CLI.csproj"],
"problemMatcher": "$msCompile",
"group": {
"_id": "build",
"isDefault": false
}
}
]
}
"version": "2.0.0",
"command": "dotnet",
"args": [],
"tasks": [
{
"label": "build",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"${workspaceRoot}/ElectronNET.CLI/ElectronNET.CLI.csproj"
],
"problemMatcher": "$msCompile",
"group": {
"_id": "build",
"isDefault": false
}
}
]
}

16
.vscode/tasks.json.old vendored Normal file
View File

@@ -0,0 +1,16 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
"${workspaceRoot}/ElectronNET.CLI/ElectronNET.CLI.csproj"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -1,85 +1,374 @@
# 0.1.0
# Not released
## ElectronNET.Core
# 18.6.1
- Updated `PrintToPDFOptions` to also allow specifying the `PageSize` with an object (#769)
- Updated splashscreen image to have 0 margin (#622)
- Updated the IPC API w.r.t. naming and consistency (#905) @agracio
- Updated the IPC bridge w.r.t. synchronization and thread-safety (#918) @agracio
- Updated serialization to use `System.Text.Json` replacing `Newtonsoft.Json` (#917) @Denny09310
- Fixed parameter handling for the `sendToIpcRenderer` function (#922) @softworkz
- Fixed synchronization on removing event handlers (#921) @softworkz
- Fixed creation of windows with `contextIsolation` enabled (#906) @NimbusFox
- Fixed single instance behavior using the `ElectronSingleInstance` property (#901)
- Fixed potential race conditions (#908) @softworkz
- Added option to use `ElectronSplashScreen` with an HTML file (#799)
- Added option to provide floating point value as aspect ratios with `SetAspectRatio` (#793)
- Added option to provide `TitleBarOverlay` as an object (#911) @Denny09310
- Added `TitleBarOverlay` property to `BrowserWindowOptions` (#909)
- Added `RoundedCorners` property to `BrowserWindowOptions`
- Added integration tests and robustness checks (#913) @softworkz
- Added .NET 10 as an explicit target
ElectronNET.CLI:
# 0.0.18
* New Feature: Support for additional dotnet publish flags (thanks [danatcofo](https://github.com/danatcofo)) [\#655](https://github.com/ElectronNET/Electron.NET/pull/655)
* New Feature: Support Apple Silicon Natively (thanks [bman46](https://github.com/bman46)) [\#624](https://github.com/ElectronNET/Electron.NET/pull/624)
## ElectronNET.Core
ElectronNET.API:
### Highlights
* New Feature: Support for .NET 6 (thanks [danatcofo](https://github.com/danatcofo)) [\#636](https://github.com/ElectronNET/Electron.NET/pull/636)
* New Feature: Switch to async socket lib (thanks [theolivenbaum](https://github.com/theolivenbaum)) [\#595](https://github.com/ElectronNET/Electron.NET/pull/595)
* New Feature: Conversion to use ImageSharp rather than System.Drawing.Common (thanks [danatcofo](https://github.com/danatcofo)) [\#658](https://github.com/ElectronNET/Electron.NET/pull/658)
* New Feature: Support DI and Mocking better + Support launching app with file for win and linux (thanks [danatcofo](https://github.com/danatcofo)) [\#656](https://github.com/ElectronNET/Electron.NET/pull/656)
* New Feature: Support launching app with file for win and linux (thanks [schaveyt](https://github.com/schaveyt)) [\#648](https://github.com/ElectronNET/Electron.NET/pull/648)
* New Feature: Add ability to set a window's parent using BrowserWindowOptions (thanks [MutatedGamer](https://github.com/MutatedGamer)) [\#673](https://github.com/ElectronNET/Electron.NET/pull/673)
* New Feature: changed the processing of loadUrl at CreateWindowAsync (thanks [yannikHoeflich](https://github.com/yannikHoeflich)) [\#631](https://github.com/ElectronNET/Electron.NET/pull/631)
* New Feature: Recent Document Support for MacOS (thanks [danatcofo](https://github.com/danatcofo)) [\#634](https://github.com/ElectronNET/Electron.NET/pull/634)
* New Feature: Support DI and Mocking better (thanks [danatcofo](https://github.com/danatcofo)) [\#633](https://github.com/ElectronNET/Electron.NET/pull/633)
* New Feature: Allow ignoring certificate errors (thanks [javierlarota](https://github.com/javierlarota)) [\#626](https://github.com/ElectronNET/Electron.NET/pull/626)
* New Feature: Log errors in the dotnet process (thanks [Meberem](https://github.com/Meberem)) [\#592](https://github.com/ElectronNET/Electron.NET/pull/592)
* Fixed bug: Error on reloading a window after a second window is closed #664 (thanks [danatcofo](https://github.com/danatcofo)) [\#668](https://github.com/ElectronNET/Electron.NET/pull/668)
- **Complete MSBuild Integration**: Eliminated CLI tool dependency, moved all build processes to MSBuild with deep Visual Studio integration
- **Modernized Architecture**: Restructured process lifecycle with .NET launching first and running Electron as child process for better control and reliability
- **Cross-Platform Development**: Build and debug Linux applications directly from Windows Visual Studio via WSL integration
- **Flexible Electron Versioning**: Removed version lock-in, users can now select any Electron version with build-time validation
- **Enhanced Debugging Experience**: ASP.NET-first debugging with Hot Reload support and improved process termination handling
- **Console App Support**: No longer requires ASP.NET - now works with simple console applications for file system or remote server HTML/JS
# Released
### Build System & Project Structure
# 13.5.1
- Eliminated electron.manifest.json configuration file, replaced with MSBuild project properties
- Introduced new package structure: ElectronNET.Core (main package), ElectronNET.Core.Api (API definitions), ElectronNET.Core.AspNet (ASP.NET integration)
- Added Runtime Identifier (RID) selection as part of project configuration
- Restructured build folder layout to use standard .NET format (bin\net8.0\win-x64) instead of bin\Desktop
- Implemented incremental build support for Electron assets to improve build performance
- Added custom MSBuild tasks for Electron-specific build operations
ElectronNET.CLI:
### Development Experience
* New Feature: Using exit code instead of seek for the term 'error' (thanks [TSrgy](https://github.com/TSrgy)) [\#562](https://github.com/ElectronNET/Electron.NET/pull/562)
* Fixed bug: Allow for property overrides to be passed in (thanks [danatcofo](https://github.com/danatcofo)) [\#531](https://github.com/ElectronNET/Electron.NET/pull/531)
Use `/p:propertyName=value` or `/property:propertyName=value` to pass in property overrides. This is equivalent to the `-p:` option documented here: [https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish)
* Fixed bug: Add ability to pass an argument for "Version" for both the "dotnet publish" and "electron-builder" commands (thanks [tub5](https://github.com/tub5)) [\#546](https://github.com/ElectronNET/Electron.NET/pull/546)
* Fixed bug: Version flag not persisting with the referenced executable (thanks [tub5](https://github.com/tub5)) [\#585](https://github.com/ElectronNET/Electron.NET/pull/585)
* Fixed bug: Changes PublishSingleFile default to false for NET5 compatibility (thanks [cristiangiagante](https://github.com/cristiangiagante)) [\#570](https://github.com/ElectronNET/Electron.NET/pull/570)
ElectronNET.API:
* New Feature: Native Electron 13.1.5 support, but not all new features (we search contributors)
* Breaking API Changes (from native Electron 13.1.5):
- `Shell.MoveItemToTrashAsync` renamed with `Shell.TrashItemAsync`
- The deprecated extension APIs have been removed: `BrowserWindow.GetAllExtensionsAsync()`, `BrowserWindow.RemoveExtension()`, `BrowserWindow.AddExtensionAsync()`. Use the session APIs instead: `Session.GetAllExtensionsAsync()`, `Session.RemoveExtension()`, `Session.LoadExtensionAsync()`.
* New Feature: singleInstance handle command line arguments [\#520](https://github.com/ElectronNET/Electron.NET/issues/520)
* New Feature: Add WebContents [insertCSS](https://www.electronjs.org/docs/api/web-contents#contentsinsertcsscss-options) functionality (thanks [nfichter](https://github.com/nfichter)) [\#559](https://github.com/ElectronNET/Electron.NET/pull/559)
* New Feature: Allow IpcMain to send IPC messages to BrowserViews (thanks [nfichter](https://github.com/nfichter)) [\#560](https://github.com/ElectronNET/Electron.NET/pull/560)
* New Feature: Add support for proxies that require basic username/password authentication (thanks [nfichter](https://github.com/nfichter)) [\#561](https://github.com/ElectronNET/Electron.NET/pull/561)
* New Feature: Add PostData to LoadURLOptions to allow http-posts in LoadURL calls (thanks [Funkrusha](https://github.com/Funkrusha)) [\#547](https://github.com/ElectronNET/Electron.NET/pull/547)
* Fixed bug: Fix splash screen interaction causing crashes, ghost dragging, and resizable behavior #540 (thanks [MiniguyBrendan](https://github.com/MiniguyBrendan)) [\#540](https://github.com/ElectronNET/Electron.NET/pull/540)
* Fixed bug: Vibrancy serialization fix (thanks [tantumalice](https://github.com/tantumalice)) [\#573](https://github.com/ElectronNET/Electron.NET/pull/573)
- Implemented unpackaged run-mode for development using regular .NET builds with unpackaged Electron configuration
- Added support for building Linux packages on Windows via WSL integration
- Enabled running and debugging Linux application outputs on Windows through WSL
- Integrated TypeScript compilation with ASP.NET tooling for consistent builds
- Added process orchestration supporting 8 different launch scenarios (packaged/unpackaged × console/ASP.NET × dotnet-first/electron-first)
# 11.5.1
### Debugging & Runtime
ElectronNET.CLI:
- Dramatically improved debugging experience with ASP.NET-first launch mode
- Added Hot Reload support for ASP.NET code during development
- Implemented proper process termination handling for all exit scenarios
- Minimized startup times through optimized build and launch procedures
* New Feature: Added new build and start commandline options for single exe (thanks [nathanwienand](https://github.com/nathanwienand)) [\#506](https://github.com/ElectronNET/Electron.NET/pull/506)
* New Feature: Set a description of the app in `electron.manifest.json` (thanks [BurtsevC](https://github.com/BurtsevC)) [\#433](https://github.com/ElectronNET/Electron.NET/pull/433)
* New Feature: Set a target for the start command (thanks [gabecook](https://github.com/gabecook)) [\#463](https://github.com/ElectronNET/Electron.NET/pull/463)
* New Feature: `electronize init` support for F# projects (thanks [kojo12228](https://github.com/kojo12228)) [\#457](https://github.com/ElectronNET/Electron.NET/pull/457)
* New Feature: Linux support for the buildAll.sh (thanks [duncanawoods](https://github.com/duncanawoods)) [\#465](https://github.com/ElectronNET/Electron.NET/pull/465)
* Fixed bug: ERR_UNKNOWN_URL_SCHEME by intercepting file:// protocol (thanks [duncanawoods](https://github.com/duncanawoods)) [\#467](https://github.com/ElectronNET/Electron.NET/pull/467)
### Technical Improvements
ElectronNET.API:
- Enhanced splash screen handling with automatic path resolution
- Improved ElectronHostHook integration as proper npm package dependency
- Updated to latest TypeScript version with ESLint configuration
- Added support for custom main.js files in projects
- Implemented version management through common.props file
- Added build-time Electron version compatibility validation
* New Feature: Native Electron 11.1.1 support, but not all new features (we search contributors)
* Breaking API Changes (from native Electron 11.0): - Removed: BrowserView.{destroy, fromId, fromWebContents, getAllViews} and id property of BrowserView
* New Feature: Upgrade to .NET 5 (thanks [scottkuhl](https://github.com/scottkuhl)) [\#509](https://github.com/ElectronNET/Electron.NET/pull/509)
* New Feature: Extension Method for adding the Electron static class members to the standard MS DI Containers, this is a QOL issue only. `services.AddElectron()` (thanks [danatcofo](https://github.com/danatcofo )) [\#528](https://github.com/ElectronNET/Electron.NET/pull/528)
* New Feature: SetMenu completed for the Dock (MacOS) (thanks [danatcofo](https://github.com/danatcofo )) [\#528](https://github.com/ElectronNET/Electron.NET/pull/528)
### Package & Distribution
Example for the Dock Menu
- Integrated MSBuild publishing mechanisms for creating Electron packages
- Added folder publishing support with improved parameter handling
- Implemented automated package.json generation from MSBuild properties
- Added GitHub release automation with proper versioning
- Reduced package sizes by eliminating unnecessary TypeScript dependencies
`Electron.Dock.SetMenu(new [] {
new MenuItem {
Label = "Dock Menu Item",
Click = () => {
// do something
}
},
});`
### Migration & Compatibility
Example for consuming the activate event (MacOs only)
- Maintained backward compatibility for existing ElectronHostHook implementations
- Removed ASP.NET requirement: Now works with simple console applications for file system or remote server HTML/JS scenarios
- Added support for both console and ASP.NET Core application types
- Preserved all existing Electron API functionality while modernizing architecture
- Added migration path for existing projects through updated package structure
`Electron.App.On("activate", obj => {
var hasWindows = (bool)obj;
// do something
});`
This represents a comprehensive modernization of Electron.NET, addressing the major pain points around debugging, build complexity, and platform limitations while maintaining full API compatibility.
* New Feature: On and Once implementations for the App and Tray to cover the plethora of events that are not mapped explicitly in those two modules. (thanks [danatcofo](https://github.com/danatcofo )) [\#528](https://github.com/ElectronNET/Electron.NET/pull/528)
* New Feature: Adding the `EnableRemoteModule` property to the WebPreferences object. As of Electron 10, this property defaulted to false and without it exposed you can't use the remote module within a window. (thanks [danatcofo](https://github.com/danatcofo )) [\#528](https://github.com/ElectronNET/Electron.NET/pull/528)
* New Feature: Adding a configurable default electron port. (thanks [aarong-av](https://github.com/aarong-av)) [\#505](https://github.com/ElectronNET/Electron.NET/pull/505)
* New Feature: Added support for launching the application with a file on MacOS (thanks [dlitty](https://github.com/dlitty)) [\#478](https://github.com/ElectronNET/Electron.NET/pull/478)
* Improved: Avoid Blocking Calls in App and AutoUpdater (thanks [freosc](https://github.com/freosc)) [\#474](https://github.com/ElectronNET/Electron.NET/pull/474)
* Fixed bug: Maintain references between socket.io connection events (thanks [danatcofo](https://github.com/danatcofo )) [\#468](https://github.com/ElectronNET/Electron.NET/pull/486)
* Fixed bug: Set default WebPreferences.DefaultFontSize (thanks [duncanawoods](https://github.com/duncanawoods)) [\#468](https://github.com/ElectronNET/Electron.NET/pull/468)
# 9.31.2
* Electron-Builder fixed for Windows builds.
# 9.31.1
ElectronNET.CLI:
* New Feature: Added config parameter (thanks [konstantingross](https://github.com/konstantingross)) [\#409](https://github.com/ElectronNET/Electron.NET/pull/409)
* New Feature: Set the configuration environment with the electron.manifest.json file.
* Fixed bug: Custom user path removed and replaced by the correct directory with VS macro (When ElectronNET.CLI is the Startup Project, press F5 (Debug) and the ElectronNET.WebApp starts correctly without error!) (thanks [konstantingross](https://github.com/konstantingross)) [\#409](https://github.com/ElectronNET/Electron.NET/pull/409)
ElectronNET.API:
* New Feature: Native Electron 9.0.3 support, but not all new features (we search contributors)
* New Feature: PowerMonitor API Support (thanks [gustavo-lara-molina](https://github.com/gustavo-lara-molina)) [\#399](https://github.com/ElectronNET/Electron.NET/pull/399) [\#423](https://github.com/ElectronNET/Electron.NET/pull/423)
* New Feature: NativeTheme API Support (thanks [konstantingross](https://github.com/konstantingross)) [\#402](https://github.com/ElectronNET/Electron.NET/pull/402)
* New Feature: Cookie API Support (thanks [freosc](https://github.com/freosc)) [\#413](https://github.com/ElectronNET/Electron.NET/pull/413)
* Changed Feature: Removed dock methods from App API and moved to Dock API (thanks [konstantingross](https://github.com/konstantingross)) [\#422](https://github.com/ElectronNET/Electron.NET/pull/422)
* App-Api Enhancement: MenuItems with Submenus need an submenu type workaround [\#412](https://github.com/ElectronNET/Electron.NET/issues/412)
* App-Api Enhancement: Added UserAgentFallback (thanks [Mandrakia](https://github.com/Mandrakia)) [\#406](https://github.com/ElectronNET/Electron.NET/pull/406)
* App-Api Enhancement: Summaries rewritten, new App.IsReady / App.HasSingleInstanceLock property, App.Ready event, App.Focus with force parameter method, many parameters changes (thanks [konstantingross](https://github.com/konstantingross)) [\#415](https://github.com/ElectronNET/Electron.NET/pull/415) [\#422](https://github.com/ElectronNET/Electron.NET/pull/422)
* App-Api Enhancement: New App.IsReady property and App.Ready event (thanks [konstantingross](https://github.com/konstantingross)) [\#415](https://github.com/ElectronNET/Electron.NET/pull/415)
* Shell-Api Enhancement: API fixes for Electron 9.0.0 / Added missing parameters / Summaries rewritten (thanks [konstantingross](https://github.com/konstantingross)) [\#417](https://github.com/ElectronNET/Electron.NET/pull/417) [\#418](https://github.com/ElectronNET/Electron.NET/pull/418)
* Notification-Api Enhancement: Added missing properties in Notifications (thanks [konstantingross](https://github.com/konstantingross)) [\#410](https://github.com/ElectronNET/Electron.NET/pull/410)
* BrowserWindows-Api Enhancement: Add missing API call for SetProgressBar options (thanks [konstantingross](https://github.com/konstantingross)) [\#416](https://github.com/ElectronNET/Electron.NET/pull/416)
* BrowserWindow Enhancement: Add BrowserWindow.GetNativeWindowHandle() (thanks [kdlslyv](https://github.com/kdlslyv)) [\#429](https://github.com/ElectronNET/Electron.NET/pull/429)
* HostHook-Api Enhancement: HostHook.CallAsync should use TaskCompletionSource.SetException instead of throwing exception (thanks [Fre V](https://github.com/freosc)) [\#430](https://github.com/ElectronNET/Electron.NET/pull/430)
* MacOS Enhancement: Application exit logic (thanks [dafergu2](https://github.com/dafergu2)) [\#405](https://github.com/ElectronNET/Electron.NET/pull/405)
* Fixed bug: ElectronNET.API.Entities.WebPreferences.ContextIsolation [DefaultValue(true)] [\#411](https://github.com/ElectronNET/Electron.NET/issues/411)
ElectronNET.WebApp (internal use):
* Improvement debugging and testing new API calls (without install ElectronNET.CLI) (thanks [konstantingross](https://github.com/konstantingross)) [\#425](https://github.com/ElectronNET/Electron.NET/pull/425)
* Fixed bug: Cannot find modules in ElectronHostHook (thanks [konstantingross](https://github.com/konstantingross)) [\#425](https://github.com/ElectronNET/Electron.NET/pull/425)
Thank you for donation [Phil Seeman](https://github.com/mpnow) ❤
# 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)
# 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
ElectronNET.CLI:
* Fixed electronize start for macos/linux - thanks @yamachu
* Skip NPM install on start when node_modules directory already exists
# 0.0.6
ElectronNET.CLI:
* nuget packages are now release bits and have the correct assembly version
* Version command
* better devCleanup.cmd
* Better Platform Support Issue - thanks to @Petermarcu
* Start Command should now work on OSX/Linux - thanks to @r105m
ElectronNET.API:
* Thread-Safe methods - thanks to @yeskunall
# 0.0.5
ElectronNET.API:
* The last nuget package didn't contain the actual webpreferences settings with defaults - hopefully now.
# 0.0.4
ElectronNET.CLI:
* dotnet electronize start fixed
ElectronNET.API:
* WebPreferences settings with default values
# 0.0.3
ElectronNET.CLI:
* Init with Debug profile
* Build for all platforms (well... for newest OSX/Linux/Windows)
ElectronNET.API:
* Moar XML documentation
* Hybrid support (e.g. running as normal website and electron app)
* Event bugfixing
# 0.0.2
ElectronNET.CLI:
* Added Init to Help page
* Added XML documentation to NuGet output
* Maybe fixed for https://github.com/GregorBiswanger/Electron.NET/issues/2
ElectronNET.API:
* Add XML documentation to NuGet output
* Implemented Notification-, Dialog- & Tray-API
# 0.0.1
* init everything and basic functionality

789
src/ElectronNET.API/API/App.cs → ElectronNET.API/App.cs Normal file → Executable file

File diff suppressed because it is too large Load Diff

474
ElectronNET.API/AutoUpdater.cs Executable file
View File

@@ -0,0 +1,474 @@
using ElectronNET.API.Entities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ElectronNET.API.Interfaces;
using ElectronNET.API;
namespace ElectronNET.API
{
/// <summary>
/// Enable apps to automatically update themselves. Based on electron-updater.
/// </summary>
public sealed class AutoUpdater : IAutoUpdater
{
/// <summary>
/// Whether to automatically download an update when it is found. (Default is true)
/// </summary>
public Task<bool> IsAutoDownloadEnabledAsync => BridgeConnector.OnResult<bool>("autoUpdater-autoDownload-get", "autoUpdater-autoDownload-get-reply");
/// <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 Task<bool> IsAutoInstallOnAppQuitEnabledAsync => BridgeConnector.OnResult<bool>("autoUpdater-autoInstallOnAppQuit-get", "autoUpdater-autoInstallOnAppQuit-get-reply");
/// <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 Task<bool> IsAllowPrereleaseEnabledAsync => BridgeConnector.OnResult<bool>("autoUpdater-allowPrerelease-get", "autoUpdater-allowPrerelease-get-reply");
/// <summary>
/// *GitHub provider only.*
/// Get all release notes (from current version to latest), not just the latest (Default is false).
/// </summary>
public Task<bool> IsFullChangeLogEnabledAsync => BridgeConnector.OnResult<bool>("autoUpdater-fullChangelog-get", "autoUpdater-fullChangelog-get-reply");
public Task<bool> IsAllowDowngradeEnabledAsync => BridgeConnector.OnResult<bool>("autoUpdater-allowDowngrade-get", "autoUpdater-allowDowngrade-get-reply");
/// <summary>
/// Whether to automatically download an update when it is found. (Default is true)
/// </summary>
public bool AutoDownload
{
set
{
BridgeConnector.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
{
set
{
BridgeConnector.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
{
set
{
BridgeConnector.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
{
set
{
BridgeConnector.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
{
set
{
BridgeConnector.Emit("autoUpdater-allowDowngrade-set", value);
}
}
/// <summary>
/// For test only.
/// </summary>
public Task<string> GetUpdateConfigPathAsync => BridgeConnector.OnResult<string>("autoUpdater-updateConfigPath-get", "autoUpdater-updateConfigPath-get-reply");
/// <summary>
/// The current application version
/// </summary>
public Task<SemVer> GetCurrentVersionAsync => BridgeConnector.OnResult<SemVer>("autoUpdater-updateConcurrentVersionfigPath-get", "autoUpdater-currentVersion-get-reply");
/// <summary>
/// Get the update channel. Not applicable for GitHub.
/// Doesnt return channel from the update configuration, only if was previously set.
/// </summary>
public Task<string> GetChannelAsync => BridgeConnector.OnResult<string>("autoUpdater-channel-get", "autoUpdater-channel-get-reply");
/// <summary>
/// The request headers.
/// </summary>
public Task<Dictionary<string, string>> GetRequestHeadersAsync => BridgeConnector.OnResult<Dictionary<string, string>>("autoUpdater-requestHeaders-get", "autoUpdater-requestHeaders-get-reply");
/// <summary>
/// The request headers.
/// </summary>
public Dictionary<string, string> RequestHeaders
{
set
{
BridgeConnector.Emit("autoUpdater-requestHeaders-set", value);
}
}
/// <summary>
/// Emitted when there is an error while updating.
/// </summary>
public event Action<string> OnError
{
add
{
if (_error == null)
{
BridgeConnector.On<string>("autoUpdater-error" + GetHashCode(), (message) =>
{
_error(message.ToString());
});
BridgeConnector.Emit("register-autoUpdater-error-event", GetHashCode());
}
_error += value;
}
remove
{
_error -= value;
if (_error == null)
BridgeConnector.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.On("autoUpdater-checking-for-update" + GetHashCode(), () =>
{
_checkingForUpdate();
});
BridgeConnector.Emit("register-autoUpdater-checking-for-update-event", GetHashCode());
}
_checkingForUpdate += value;
}
remove
{
_checkingForUpdate -= value;
if (_checkingForUpdate == null)
BridgeConnector.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.On<UpdateInfo>("autoUpdater-update-available" + GetHashCode(), (updateInfo) =>
{
_updateAvailable(updateInfo);
});
BridgeConnector.Emit("register-autoUpdater-update-available-event", GetHashCode());
}
_updateAvailable += value;
}
remove
{
_updateAvailable -= value;
if (_updateAvailable == null)
BridgeConnector.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.On<UpdateInfo>("autoUpdater-update-not-available" + GetHashCode(), (updateInfo) =>
{
_updateNotAvailable(updateInfo);
});
BridgeConnector.Emit("register-autoUpdater-update-not-available-event", GetHashCode());
}
_updateNotAvailable += value;
}
remove
{
_updateNotAvailable -= value;
if (_updateNotAvailable == null)
BridgeConnector.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.On<ProgressInfo>("autoUpdater-download-progress" + GetHashCode(), (progressInfo) =>
{
_downloadProgress(progressInfo);
});
BridgeConnector.Emit("register-autoUpdater-download-progress-event", GetHashCode());
}
_downloadProgress += value;
}
remove
{
_downloadProgress -= value;
if (_downloadProgress == null)
BridgeConnector.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.On<UpdateInfo>("autoUpdater-update-downloaded" + GetHashCode(), (updateInfo) =>
{
_updateDownloaded(updateInfo);
});
BridgeConnector.Emit("register-autoUpdater-update-downloaded-event", GetHashCode());
}
_updateDownloaded += value;
}
remove
{
_updateDownloaded -= value;
if (_updateDownloaded == null)
BridgeConnector.Off("autoUpdater-update-downloaded" + GetHashCode());
}
}
private event Action<UpdateInfo> _updateDownloaded;
private static AutoUpdater _autoUpdater;
private static readonly object _syncRoot = new();
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>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On<UpdateCheckResult>("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
{
try
{
BridgeConnector.Off("autoUpdaterCheckForUpdatesComplete" + guid);
BridgeConnector.Off("autoUpdaterCheckForUpdatesError" + guid);
taskCompletionSource.SetResult(updateCheckResult);
}
catch (Exception ex)
{
taskCompletionSource.SetException(ex);
}
});
BridgeConnector.On<string>("autoUpdaterCheckForUpdatesError" + guid, (error) =>
{
BridgeConnector.Off("autoUpdaterCheckForUpdatesComplete" + guid);
BridgeConnector.Off("autoUpdaterCheckForUpdatesError" + guid);
string message = "An error occurred in CheckForUpdatesAsync";
if (error != null && !string.IsNullOrEmpty(error.ToString()))
message = JsonConvert.SerializeObject(error);
taskCompletionSource.SetException(new Exception(message));
});
BridgeConnector.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>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On<UpdateCheckResult>("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
{
try
{
BridgeConnector.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
BridgeConnector.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
if (updateCheckResult == null)
taskCompletionSource.SetResult(null);
else
taskCompletionSource.SetResult(updateCheckResult);
}
catch (Exception ex)
{
taskCompletionSource.SetException(ex);
}
});
BridgeConnector.On<string>("autoUpdaterCheckForUpdatesAndNotifyError" + guid, (error) =>
{
BridgeConnector.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
BridgeConnector.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
string message = "An error occurred in autoUpdaterCheckForUpdatesAndNotify";
if (error != null)
message = JsonConvert.SerializeObject(error);
taskCompletionSource.SetException(new Exception(message));
});
BridgeConnector.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.EmitSync("prepare-for-update");
BridgeConnector.EmitSync("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>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On<string>("autoUpdaterDownloadUpdateComplete" + guid, (downloadedPath) =>
{
BridgeConnector.Off("autoUpdaterDownloadUpdateComplete" + guid);
taskCompletionSource.SetResult(downloadedPath.ToString());
});
BridgeConnector.Emit("autoUpdaterDownloadUpdate", guid);
return taskCompletionSource.Task;
}
/// <summary>
/// Feed URL.
/// </summary>
/// <returns>Feed URL.</returns>
public Task<string> GetFeedURLAsync()
{
var taskCompletionSource = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On<string>("autoUpdaterGetFeedURLComplete" + guid, (downloadedPath) =>
{
BridgeConnector.Off("autoUpdaterGetFeedURLComplete" + guid);
taskCompletionSource.SetResult(downloadedPath.ToString());
});
BridgeConnector.Emit("autoUpdaterGetFeedURL", guid);
return taskCompletionSource.Task;
}
}
}

View File

@@ -0,0 +1,551 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Nito.AsyncEx;
using SocketIOClient;
using SocketIOClient.Newtonsoft.Json;
namespace ElectronNET.API
{
internal static class BridgeConnector
{
internal static class EventTasks<T>
{
//Although SocketIO already manage event handlers, we need to manage this here as well for the OnResult calls,
//because SocketIO will simply replace the existing event handler on every call to On(key, ...) , which means there is
//a race condition between On / Off calls that can lead to tasks deadlocking forever without ever triggering their On handler
private static readonly Dictionary<string, TaskCompletionSource<T>> _taskCompletionSources = new();
private static readonly Dictionary<string, string> _eventKeys = new();
private static readonly object _lock = new();
/// <summary>
/// Get or add a new TaskCompletionSource<typeparamref name="T"/> for a given event key
/// </summary>
/// <param name="key"></param>
/// <param name="eventKey"></param>
/// <param name="taskCompletionSource"></param>
/// <param name="waitThisFirstAndThenTryAgain"></param>
/// <returns>Returns true if a new TaskCompletionSource<typeparamref name="T"/> was added to the dictionary</returns>
internal static bool TryGetOrAdd(string key, string eventKey, out TaskCompletionSource<T> taskCompletionSource, out Task waitThisFirstAndThenTryAgain)
{
lock (_lock)
{
if (!_taskCompletionSources.TryGetValue(key, out taskCompletionSource))
{
taskCompletionSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
_taskCompletionSources[key] = taskCompletionSource;
_eventKeys[key] = eventKey;
waitThisFirstAndThenTryAgain = null;
return true; //Was added, so we need to also register the socket events
}
if (_eventKeys.TryGetValue(key, out var existingEventKey) && existingEventKey == eventKey)
{
waitThisFirstAndThenTryAgain = null;
return false; //No need to register the socket events twice
}
waitThisFirstAndThenTryAgain = taskCompletionSource.Task; //Will need to try again after the previous existing one is done
taskCompletionSource = null;
return true; //Need to register the socket events, but must first await the previous task to complete
}
}
/// <summary>
/// Clean up the TaskCompletionSource<typeparamref name="T"/> from the dictionary if and only if it is the same as the passed argument
/// </summary>
/// <param name="key"></param>
/// <param name="eventKey"></param>
/// <param name="taskCompletionSource"></param>
internal static void DoneWith(string key, string eventKey, TaskCompletionSource<T> taskCompletionSource)
{
lock (_lock)
{
if (_taskCompletionSources.TryGetValue(key, out var existingTaskCompletionSource)
&& ReferenceEquals(existingTaskCompletionSource, taskCompletionSource))
{
_taskCompletionSources.Remove(key);
}
if (_eventKeys.TryGetValue(key, out var existingEventKey) && existingEventKey == eventKey)
{
_eventKeys.Remove(key);
}
}
}
}
private static SocketIO _socket;
private static readonly object _syncRoot = new();
private static readonly SemaphoreSlim _socketSemaphoreEmit = new(1, 1);
private static readonly SemaphoreSlim _socketSemaphoreHandlers = new(1, 1);
private static AsyncManualResetEvent _connectedSocketEvent = new AsyncManualResetEvent();
private static Dictionary<string, Action<SocketIOResponse>> _eventHandlers = new();
private static Task<SocketIO> _waitForConnection
{
get
{
EnsureSocketTaskIsCreated();
return GetSocket();
}
}
private static async Task<SocketIO> GetSocket()
{
await _connectedSocketEvent.WaitAsync();
return _socket;
}
public static bool IsConnected => _waitForConnection is Task task && task.IsCompletedSuccessfully;
public static void Emit(string eventString, params object[] args)
{
//We don't care about waiting for the event to be emitted, so this doesn't need to be async
Task.Run(() => EmitAsync(eventString, args));
}
private static async Task EmitAsync(string eventString, object[] args)
{
if (App.SocketDebug)
{
Log("Sending event {0}", eventString);
}
var socket = await _waitForConnection;
await _socketSemaphoreEmit.WaitAsync();
try
{
await socket.EmitAsync(eventString, args);
}
finally
{
_socketSemaphoreEmit.Release();
}
if (App.SocketDebug)
{
Log($"Sent event {eventString}");
}
}
/// <summary>
/// This method is only used on places where we need to be sure the event was sent on the socket, such as Quit, Exit, Relaunch and QuitAndInstall methods
/// </summary>
/// <param name="eventString"></param>
/// <param name="args"></param>
internal static void EmitSync(string eventString, params object[] args)
{
if (App.SocketDebug)
{
Log("Sending event {0}", eventString);
}
Task.Run(async () =>
{
var socket = await _waitForConnection;
try
{
await _socketSemaphoreEmit.WaitAsync();
await socket.EmitAsync(eventString, args);
}
finally
{
_socketSemaphoreEmit.Release();
}
}).Wait();
if (App.SocketDebug)
{
Log("Sent event {0}", eventString);
}
}
public static void Off(string eventString)
{
EnsureSocketTaskIsCreated();
_socketSemaphoreHandlers.Wait();
try
{
if (_eventHandlers.ContainsKey(eventString))
{
_eventHandlers.Remove(eventString);
}
_socket.Off(eventString);
}
finally
{
_socketSemaphoreHandlers.Release();
}
}
public static void On(string eventString, Action fn)
{
EnsureSocketTaskIsCreated();
_socketSemaphoreHandlers.Wait();
try
{
if (_eventHandlers.ContainsKey(eventString))
{
_eventHandlers.Remove(eventString);
}
_eventHandlers.Add(eventString, _ =>
{
try
{
fn();
}
catch (Exception E)
{
LogError(E, "Error running handler for event {0}", eventString);
}
});
_socket.On(eventString, _eventHandlers[eventString]);
}
finally
{
_socketSemaphoreHandlers.Release();
}
}
public static void On<T>(string eventString, Action<T> fn)
{
EnsureSocketTaskIsCreated();
_socketSemaphoreHandlers.Wait();
try
{
if (_eventHandlers.ContainsKey(eventString))
{
_eventHandlers.Remove(eventString);
}
_eventHandlers.Add(eventString, o =>
{
try
{
fn(o.GetValue<T>(0));
}
catch (Exception E)
{
LogError(E, "Error running handler for event {0}", eventString);
}
});
_socket.On(eventString, _eventHandlers[eventString]);
}
finally
{
_socketSemaphoreHandlers.Release();
}
}
private static void RehookHandlers(SocketIO newSocket)
{
_socketSemaphoreHandlers.Wait();
try
{
foreach (var kv in _eventHandlers)
{
newSocket.On(kv.Key, kv.Value);
}
}
finally
{
_socketSemaphoreHandlers.Release();
}
}
public static void Once<T>(string eventString, Action<T> fn)
{
On<T>(eventString, (o) =>
{
Off(eventString);
fn(o);
});
}
public static async Task<T> OnResult<T>(string triggerEvent, string completedEvent, params object[] args)
{
string eventKey = completedEvent;
if (args is object && args.Length > 0) // If there are arguments passed, we generate a unique event key with the arguments
// this allow us to wait for previous events first before registering new ones
{
var hash = new HashCode();
foreach (var obj in args)
{
hash.Add(obj);
}
eventKey = $"{eventKey}-{(uint)hash.ToHashCode()}";
}
if (EventTasks<T>.TryGetOrAdd(completedEvent, eventKey, out var taskCompletionSource, out var waitThisFirstAndThenTryAgain))
{
if (waitThisFirstAndThenTryAgain is object)
{
//There was a pending call with different parameters, so we need to wait that first and then call here again
try
{
await waitThisFirstAndThenTryAgain;
}
catch
{
//Ignore any exceptions here so we can set a new event below
//The exception will also be visible to the original first caller due to taskCompletionSource.Task
}
//Try again to set the event
return await OnResult<T>(triggerEvent, completedEvent, args);
}
else
{
//A new TaskCompletionSource was added, so we need to register the completed event here
On<T>(completedEvent, (result) =>
{
Off(completedEvent);
taskCompletionSource.SetResult(result);
EventTasks<T>.DoneWith(completedEvent, eventKey, taskCompletionSource);
});
await EmitAsync(triggerEvent, args);
}
}
return await taskCompletionSource.Task;
}
public static async Task<T> OnResult<T>(string triggerEvent, string completedEvent, CancellationToken cancellationToken, params object[] args)
{
string eventKey = completedEvent;
if (args is object && args.Length > 0) // If there are arguments passed, we generate a unique event key with the arguments
// this allow us to wait for previous events first before registering new ones
{
var hash = new HashCode();
foreach (var obj in args)
{
hash.Add(obj);
}
eventKey = $"{eventKey}-{(uint)hash.ToHashCode()}";
}
if (EventTasks<T>.TryGetOrAdd(completedEvent, eventKey, out var taskCompletionSource, out var waitThisFirstAndThenTryAgain))
{
if (waitThisFirstAndThenTryAgain is object)
{
//There was a pending call with different parameters, so we need to wait that first and then call here again
try
{
await Task.Run(() => waitThisFirstAndThenTryAgain, cancellationToken);
}
catch
{
//Ignore any exceptions here so we can set a new event below
//The exception will also be visible to the original first caller due to taskCompletionSource.Task
}
//Try again to set the event
return await OnResult<T>(triggerEvent, completedEvent, cancellationToken, args);
}
else
{
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
{
//A new TaskCompletionSource was added, so we need to register the completed event here
On<T>(completedEvent, (result) =>
{
Off(completedEvent);
taskCompletionSource.SetResult(result);
EventTasks<T>.DoneWith(completedEvent, eventKey, taskCompletionSource);
});
Emit(triggerEvent, args);
}
}
}
return await taskCompletionSource.Task;
}
internal static void Log(string formatString, params object[] args)
{
if (Logger is object)
{
Logger.LogInformation(formatString, args);
}
else
{
Console.WriteLine(formatString, args);
}
}
internal static void LogError(Exception E, string formatString, params object[] args)
{
if (Logger is object)
{
Logger.LogError(E, formatString, args);
}
else
{
Console.WriteLine(formatString, args);
Console.WriteLine(E.ToString());
}
}
private static Thread _backgroundMonitorThread;
private static void EnsureSocketTaskIsCreated()
{
if (_socket is null)
{
if (string.IsNullOrWhiteSpace(AuthKey))
{
throw new Exception("You must call Electron.ReadAuth() first thing on your main entry point.");
}
if (HybridSupport.IsElectronActive)
{
lock (_syncRoot)
{
if (_socket is null)
{
if (HybridSupport.IsElectronActive)
{
var socket = new SocketIO($"http://localhost:{BridgeSettings.SocketPort}", new SocketIOOptions()
{
EIO = 4,
Reconnection = true,
ReconnectionAttempts = int.MaxValue,
ReconnectionDelay = 500,
ReconnectionDelayMax = 2000,
RandomizationFactor = 0.5,
ConnectionTimeout = TimeSpan.FromSeconds(10),
Transport = SocketIOClient.Transport.TransportProtocol.WebSocket
});
socket.JsonSerializer = new CamelCaseNewtonsoftJsonSerializer();
_connectedSocketEvent.Reset();
socket.OnConnected += (_, __) =>
{
Task.Run(async () =>
{
await socket.EmitAsync("auth", AuthKey);
_connectedSocketEvent.Set();
Log("ElectronNET socket {1} connected on port {0}!", BridgeSettings.SocketPort, socket.Id);
});
};
socket.OnReconnectAttempt += (_, __) =>
{
_connectedSocketEvent.Reset();
Log("ElectronNET socket {1} is trying to reconnect on port {0}...", BridgeSettings.SocketPort, socket.Id);
};
socket.OnReconnectError += (_, ex) =>
{
_connectedSocketEvent.Reset();
Log("ElectronNET socket {1} failed to connect {0}", ex, socket.Id);
};
socket.OnReconnectFailed += (_, ex) =>
{
_connectedSocketEvent.Reset();
Log("ElectronNET socket {1} failed to reconnect {0}", ex, socket.Id);
};
socket.OnReconnected += (_, __) =>
{
_connectedSocketEvent.Set();
Log("ElectronNET socket {1} reconnected on port {0}...", BridgeSettings.SocketPort, socket.Id);
};
socket.OnDisconnected += (_, reason) =>
{
_connectedSocketEvent.Reset();
Log("ElectronNET socket {2} disconnected with reason {0}, trying to reconnect on port {1}!", reason, BridgeSettings.SocketPort, socket.Id);
};
socket.OnError += (_, msg) =>
{
//_connectedSocketEvent.Reset();
Log("ElectronNET socket {1} error: {0}...", msg, socket.Id);
};
_socket = socket;
Task.Run(async () =>
{
try
{
await socket.ConnectAsync();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
if (!App.TryRaiseOnSocketConnectFail())
{
Environment.Exit(0xDEAD);
}
}
});
RehookHandlers(socket);
}
else
{
throw new Exception("Missing Socket Port");
}
}
}
}
else
{
throw new Exception("Missing Socket Port");
}
}
}
internal static ILogger<App> Logger { private get; set; }
internal static string AuthKey { get; set; } = null;
private class CamelCaseNewtonsoftJsonSerializer : NewtonsoftJsonSerializer
{
public CamelCaseNewtonsoftJsonSerializer() : base()
{
OptionsProvider = () => new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
};
}
}
}
}

View File

@@ -0,0 +1,35 @@
namespace ElectronNET.API
{
/// <summary>
///
/// </summary>
public static class BridgeSettings
{
/// <summary>
/// Gets the socket port.
/// </summary>
/// <value>
/// The socket port.
/// </value>
public static string SocketPort { get; internal set; }
/// <summary>
/// Gets the web port.
/// </summary>
/// <value>
/// The web port.
/// </value>
public static string WebPort { get; internal set; }
/// <summary>
/// Manually set the port values instead of using the UseElectron extension method
/// </summary>
/// <param name="socketPort"></param>
/// <param name="webPort"></param>
public static void InitializePorts(int socketPort, int webPort)
{
SocketPort = socketPort.ToString();
WebPort = webPort.ToString();
}
}
}

View File

@@ -1,21 +1,25 @@
using ElectronNET.API.Entities;
using ElectronNET.API.Entities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
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.
/// 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: ApiBase
public class BrowserView
{
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
/// <summary>
/// Gets the identifier.
/// </summary>
public override int Id { get; protected set; }
/// <value>
/// The identifier.
/// </value>
public int Id { get; internal set; }
/// <summary>
/// Render and control web pages.
@@ -24,24 +28,24 @@ namespace ElectronNET.API
/// <summary>
/// Resizes and moves the view to the supplied bounds relative to the window.
///
/// (experimental)
/// </summary>
public Rectangle Bounds
public Task<Rectangle> GetBoundsAsync() => BridgeConnector.OnResult<Rectangle>("browserView-getBounds", "browserView-getBounds-reply" + Id, Id);
/// <summary>
/// Set the bounds of the current view inside the window
/// </summary>
/// <param name="value"></param>
public void SetBounds(Rectangle value)
{
get
{
return Task.Run(() => GetPropertyAsync<Rectangle>()).Result;
}
set
{
BridgeConnector.Socket.Emit("browserView-bounds-set", Id, value);
}
BridgeConnector.Emit("browserView-setBounds", Id, value);
}
/// <summary>
/// BrowserView
/// </summary>
internal BrowserView(int id)
internal BrowserView(int id)
{
Id = id;
@@ -56,18 +60,18 @@ namespace ElectronNET.API
/// <param name="options"></param>
public void SetAutoResize(AutoResizeOptions options)
{
BridgeConnector.Socket.Emit("browserView-setAutoResize", Id, options);
BridgeConnector.Emit("browserView-setAutoResize", Id, options);
}
/// <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);
BridgeConnector.Emit("browserView-setBackgroundColor", Id, color);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,22 @@
using ElectronNET.API.Entities;
using ElectronNET.API.Serialization;
using System.Text.Json;
using ElectronNET.API.Entities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Runtime.Versioning;
using System.Threading.Tasks;
// ReSharper disable InconsistentNaming
using ElectronNET.API.Interfaces;
namespace ElectronNET.API
{
/// <summary>
/// Perform copy and paste operations on the system clipboard.
/// </summary>
public sealed class Clipboard: ApiBase
public sealed class Clipboard : IClipboard
{
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
private static Clipboard _clipboard;
private static object _syncRoot = new object();
private static readonly object _syncRoot = new();
internal Clipboard()
{
}
internal Clipboard() { }
internal static Clipboard Instance
{
@@ -45,7 +42,7 @@ namespace ElectronNET.API
/// </summary>
/// <param name="type"></param>
/// <returns>The content in the clipboard as plain text.</returns>
public Task<string> ReadTextAsync(string type = "") => GetPropertyAsync<string>(type);
public Task<string> ReadTextAsync(string type = "") => BridgeConnector.OnResult<string>("clipboard-readText", "clipboard-readText-Completed", type);
/// <summary>
/// Writes the text into the clipboard as plain text.
@@ -54,7 +51,7 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void WriteText(string text, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-writeText", text, type);
BridgeConnector.Emit("clipboard-writeText", text, type);
}
/// <summary>
@@ -62,7 +59,7 @@ namespace ElectronNET.API
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public Task<string> ReadHTMLAsync(string type = "") => GetPropertyAsync<string>(type);
public Task<string> ReadHTMLAsync(string type = "") => BridgeConnector.OnResult<string>("clipboard-readHTML", "clipboard-readHTML-Completed", type);
/// <summary>
/// Writes markup to the clipboard.
@@ -71,7 +68,7 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void WriteHTML(string markup, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-writeHTML", markup, type);
BridgeConnector.Emit("clipboard-writeHTML", markup, type);
}
/// <summary>
@@ -79,7 +76,8 @@ namespace ElectronNET.API
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public Task<string> ReadRTFAsync(string type = "") => GetPropertyAsync<string>(type);
public Task<string> ReadRTFAsync(string type = "") => BridgeConnector.OnResult<string>("clipboard-readRTF", "clipboard-readRTF-Completed", type);
/// <summary>
/// Writes the text into the clipboard in RTF.
@@ -88,7 +86,7 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void WriteRTF(string text, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-writeRTF", text, type);
BridgeConnector.Emit("clipboard-writeHTML", text, type);
}
/// <summary>
@@ -97,7 +95,9 @@ namespace ElectronNET.API
/// be empty strings when the bookmark is unavailable.
/// </summary>
/// <returns></returns>
public Task<ReadBookmark> ReadBookmarkAsync() => GetPropertyAsync<ReadBookmark>();
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("macos")]
public Task<ReadBookmark> ReadBookmarkAsync() => BridgeConnector.OnResult<ReadBookmark>("clipboard-readBookmark", "clipboard-readBookmark-Completed");
/// <summary>
/// Writes the title and url into the clipboard as a bookmark.
@@ -109,9 +109,11 @@ namespace ElectronNET.API
/// <param name="title"></param>
/// <param name="url"></param>
/// <param name="type"></param>
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("macos")]
public void WriteBookmark(string title, string url, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-writeBookmark", title, url, type);
BridgeConnector.Emit("clipboard-writeBookmark", title, url, type);
}
/// <summary>
@@ -120,16 +122,18 @@ namespace ElectronNET.API
/// find pasteboard whenever the application is activated.
/// </summary>
/// <returns></returns>
public Task<string> ReadFindTextAsync() => GetPropertyAsync<string>();
[SupportedOSPlatform("macos")]
public Task<string> ReadFindTextAsync() => BridgeConnector.OnResult<string>("clipboard-readFindText", "clipboard-readFindText-Completed");
/// <summary>
/// macOS: Writes the text into the find pasteboard as plain text. This method uses
/// synchronous IPC when called from the renderer process.
/// </summary>
/// <param name="text"></param>
[SupportedOSPlatform("macos")]
public void WriteFindText(string text)
{
BridgeConnector.Socket.Emit("clipboard-writeFindText", text);
BridgeConnector.Emit("clipboard-writeFindText", text);
}
/// <summary>
@@ -138,7 +142,7 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void Clear(string type = "")
{
BridgeConnector.Socket.Emit("clipboard-clear", type);
BridgeConnector.Emit("clipboard-clear", type);
}
/// <summary>
@@ -146,7 +150,7 @@ namespace ElectronNET.API
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public Task<string[]> AvailableFormatsAsync(string type = "") => GetPropertyAsync<string[]>(type);
public Task<string[]> AvailableFormatsAsync(string type = "") => BridgeConnector.OnResult<string[]>("clipboard-availableFormats", "clipboard-availableFormats-Completed", type);
/// <summary>
/// Writes data to the clipboard.
@@ -155,7 +159,7 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void Write(Data data, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-write", data, type);
BridgeConnector.Emit("clipboard-write", JObject.FromObject(data, _jsonSerializer), type);
}
/// <summary>
@@ -163,8 +167,8 @@ namespace ElectronNET.API
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public Task<NativeImage> ReadImageAsync(string type = "") => GetPropertyAsync<NativeImage>(type);
public Task<NativeImage> ReadImageAsync(string type = "") => BridgeConnector.OnResult<NativeImage>("clipboard-readImage", "clipboard-readImage-Completed", type);
/// <summary>
/// Writes an image to the clipboard.
/// </summary>
@@ -172,7 +176,14 @@ namespace ElectronNET.API
/// <param name="type"></param>
public void WriteImage(NativeImage image, string type = "")
{
BridgeConnector.Socket.Emit("clipboard-writeImage", JsonSerializer.Serialize(image, ElectronJson.Options), type);
BridgeConnector.Emit("clipboard-writeImage", JsonConvert.SerializeObject(image), type);
}
private static readonly JsonSerializer _jsonSerializer = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
}
}
}

View File

@@ -8,9 +8,7 @@ namespace ElectronNET.API
/// </summary>
public sealed class CommandLine
{
internal CommandLine()
{
}
private CommandLine() { }
internal static CommandLine Instance
{
@@ -33,7 +31,7 @@ namespace ElectronNET.API
private static CommandLine _commandLine;
private static object _syncRoot = new object();
private static readonly object _syncRoot = new();
/// <summary>
/// Append a switch (with optional value) to Chromium's command line.
@@ -45,7 +43,7 @@ namespace ElectronNET.API
/// </remarks>
public void AppendSwitch(string the_switch, string value = "")
{
BridgeConnector.Socket.Emit("appCommandLineAppendSwitch", the_switch, value);
BridgeConnector.Emit("appCommandLineAppendSwitch", the_switch, value);
}
/// <summary>
@@ -59,7 +57,7 @@ namespace ElectronNET.API
/// </remarks>
public void AppendArgument(string value)
{
BridgeConnector.Socket.Emit("appCommandLineAppendArgument", value);
BridgeConnector.Emit("appCommandLineAppendArgument", value);
}
/// <summary>
@@ -68,19 +66,7 @@ namespace ElectronNET.API
/// <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.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<bool>("appCommandLineHasSwitchCompleted", tcs.SetResult);
BridgeConnector.Socket.Emit("appCommandLineHasSwitch", switchName);
return await tcs.Task.ConfigureAwait(false);
}
}
public Task<bool> HasSwitchAsync(string switchName, CancellationToken cancellationToken = default) => BridgeConnector.OnResult<bool>("appCommandLineHasSwitch", "appCommandLineHasSwitchCompleted", cancellationToken, switchName);
/// <summary>
/// The command-line switch value.
@@ -91,18 +77,6 @@ namespace ElectronNET.API
/// <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.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<string>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<string>("appCommandLineGetSwitchValueCompleted", tcs.SetResult);
BridgeConnector.Socket.Emit("appCommandLineGetSwitchValue", switchName);
return await tcs.Task.ConfigureAwait(false);
}
}
public Task<string> GetSwitchValueAsync(string switchName, CancellationToken cancellationToken = default) => BridgeConnector.OnResult<string>("appCommandLineGetSwitchValue", "appCommandLineGetSwitchValueCompleted", cancellationToken, switchName);
}
}
}

150
ElectronNET.API/Cookies.cs Normal file
View File

@@ -0,0 +1,150 @@
using System;
using System.Threading.Tasks;
using ElectronNET.API.Entities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
namespace ElectronNET.API
{
/// <summary>
/// Query and modify a session's cookies.
/// </summary>
public class Cookies
{
/// <summary>
/// Gets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>
public int Id { get; private set; }
internal Cookies(int id)
{
Id = id;
}
/// <summary>
/// Emitted when a cookie is changed because it was added, edited, removed, or expired.
/// </summary>
public event Action<Cookie, CookieChangedCause, bool> OnChanged
{
add
{
if (_changed == null)
{
BridgeConnector.On<CookieRemovedResponse>("webContents-session-cookies-changed" + Id, (args) =>
{
_changed(args.cookie, args.cause, args.removed);
});
BridgeConnector.Emit("register-webContents-session-cookies-changed", Id);
}
_changed += value;
}
remove
{
_changed -= value;
if (_changed == null)
BridgeConnector.Off("webContents-session-cookies-changed" + Id);
}
}
private event Action<Cookie, CookieChangedCause, bool> _changed;
/// <summary>
/// Sends a request to get all cookies matching filter, and resolves a callack with the response.
/// </summary>
/// <param name="filter">
/// </param>
/// <returns>A task which resolves an array of cookie objects.</returns>
public Task<Cookie[]> GetAsync(CookieFilter filter)
{
var taskCompletionSource = new TaskCompletionSource<Cookie[]>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On<Cookie[]>("webContents-session-cookies-get-completed" + guid, (cookies) =>
{
BridgeConnector.Off("webContents-session-cookies-get-completed" + guid);
taskCompletionSource.SetResult(cookies);
});
BridgeConnector.Emit("webContents-session-cookies-get", Id, JObject.FromObject(filter, _jsonSerializer), guid);
return taskCompletionSource.Task;
}
/// <summary>
///
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
public Task SetAsync(CookieDetails details)
{
var taskCompletionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On("webContents-session-cookies-set-completed" + guid, () =>
{
BridgeConnector.Off("webContents-session-cookies-set-completed" + guid);
taskCompletionSource.SetResult(null);
});
BridgeConnector.Emit("webContents-session-cookies-set", Id, JObject.FromObject(details, _jsonSerializer), guid);
return taskCompletionSource.Task;
}
/// <summary>
/// Removes the cookies matching url and name
/// </summary>
/// <param name="url">The URL associated with the cookie.</param>
/// <param name="name">The name of cookie to remove.</param>
/// <returns>A task which resolves when the cookie has been removed</returns>
public Task RemoveAsync(string url, string name)
{
var taskCompletionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On("webContents-session-cookies-remove-completed" + guid, () =>
{
BridgeConnector.Off("webContents-session-cookies-remove-completed" + guid);
taskCompletionSource.SetResult(null);
});
BridgeConnector.Emit("webContents-session-cookies-remove", Id, url, name, guid);
return taskCompletionSource.Task;
}
/// <summary>
/// Writes any unwritten cookies data to disk.
/// </summary>
/// <returns>A task which resolves when the cookie store has been flushed</returns>
public Task FlushStoreAsync()
{
var taskCompletionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.On("webContents-session-cookies-flushStore-completed" + guid, () =>
{
BridgeConnector.Off("webContents-session-cookies-flushStore-completed" + guid);
taskCompletionSource.SetResult(null);
});
BridgeConnector.Emit("webContents-session-cookies-flushStore", Id, guid);
return taskCompletionSource.Task;
}
private static readonly JsonSerializer _jsonSerializer = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
}
}

View File

@@ -0,0 +1,38 @@
using System.Threading.Tasks;
using ElectronNET.API.Entities;
using Newtonsoft.Json;
namespace ElectronNET.API
{
public sealed class DesktopCapturer
{
private static readonly object _syncRoot = new();
private static DesktopCapturer _desktopCapturer;
internal DesktopCapturer() { }
internal static DesktopCapturer Instance
{
get
{
if (_desktopCapturer == null)
{
lock (_syncRoot)
{
if (_desktopCapturer == null)
{
_desktopCapturer = new DesktopCapturer();
}
}
}
return _desktopCapturer;
}
}
public async Task<DesktopCapturerSource[]> GetSourcesAsync(SourcesOption option)
{
return await BridgeConnector.OnResult<DesktopCapturerSource[]>("desktop-capturer-get-sources", "desktop-capturer-get-sources-result", option);
}
}
}

View File

@@ -1,21 +1,25 @@
using ElectronNET.API.Entities;
using ElectronNET.API.Entities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Text.Json;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using System.Web;
using ElectronNET.API.Interfaces;
namespace ElectronNET.API
{
/// <summary>
/// Display native system dialogs for opening and saving files, alerting, etc.
/// </summary>
public sealed class Dialog
public sealed class Dialog : IDialog
{
private static Dialog _dialog;
private static object _syncRoot = new object();
private static readonly object _syncRoot = new();
internal Dialog()
{
}
internal Dialog() { }
internal static Dialog Instance
{
@@ -25,7 +29,7 @@ namespace ElectronNET.API
{
lock (_syncRoot)
{
if (_dialog == null)
if(_dialog == null)
{
_dialog = new Dialog();
}
@@ -46,16 +50,25 @@ namespace ElectronNET.API
/// <returns>An array of file paths chosen by the user</returns>
public Task<string[]> ShowOpenDialogAsync(BrowserWindow browserWindow, OpenDialogOptions options)
{
var tcs = new TaskCompletionSource<string[]>();
var guid = Guid.NewGuid().ToString();
var taskCompletionSource = new TaskCompletionSource<string[]>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<string[]>("showOpenDialogComplete" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("showOpenDialog",
browserWindow,
options,
guid);
BridgeConnector.On<string[]>("showOpenDialogComplete" + guid, (filePaths) =>
{
BridgeConnector.Off("showOpenDialogComplete" + guid);
return tcs.Task;
var list = new List<string>();
foreach (var item in filePaths)
{
list.Add(HttpUtility.UrlDecode(item));
}
taskCompletionSource.SetResult(list.ToArray());
});
BridgeConnector.Emit("showOpenDialog", browserWindow, options, guid);
return taskCompletionSource.Task;
}
/// <summary>
@@ -66,16 +79,19 @@ namespace ElectronNET.API
/// <returns>Returns String, the path of the file chosen by the user, if a callback is provided it returns an empty string.</returns>
public Task<string> ShowSaveDialogAsync(BrowserWindow browserWindow, SaveDialogOptions options)
{
var tcs = new TaskCompletionSource<string>();
var guid = Guid.NewGuid().ToString();
var taskCompletionSource = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<string>("showSaveDialogComplete" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("showSaveDialog",
browserWindow,
options,
guid);
BridgeConnector.On<string>("showSaveDialogComplete" + guid, (filename) =>
{
BridgeConnector.Off("showSaveDialogComplete" + guid);
return tcs.Task;
taskCompletionSource.SetResult(filename);
});
BridgeConnector.Emit("showSaveDialog", browserWindow, options, guid);
return taskCompletionSource.Task;
}
/// <summary>
@@ -89,7 +105,7 @@ namespace ElectronNET.API
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
public async Task<MessageBoxResult> ShowMessageBoxAsync(string message)
{
return await this.ShowMessageBoxAsync(null, new MessageBoxOptions(message)).ConfigureAwait(false);
return await ShowMessageBoxAsync(null, new MessageBoxOptions(message));
}
/// <summary>
@@ -103,7 +119,7 @@ namespace ElectronNET.API
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
public async Task<MessageBoxResult> ShowMessageBoxAsync(MessageBoxOptions messageBoxOptions)
{
return await this.ShowMessageBoxAsync(null, messageBoxOptions).ConfigureAwait(false);
return await ShowMessageBoxAsync(null, messageBoxOptions);
}
/// <summary>
@@ -116,7 +132,7 @@ namespace ElectronNET.API
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
public async Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, string message)
{
return await this.ShowMessageBoxAsync(browserWindow, new MessageBoxOptions(message)).ConfigureAwait(false);
return await ShowMessageBoxAsync(browserWindow, new MessageBoxOptions(message));
}
/// <summary>
@@ -129,39 +145,30 @@ namespace ElectronNET.API
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
public Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions)
{
var tcs = new TaskCompletionSource<MessageBoxResult>();
var taskCompletionSource = new TaskCompletionSource<MessageBoxResult>(TaskCreationOptions.RunContinuationsAsynchronously);
var guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<JsonElement>("showMessageBoxComplete" + guid, (args) =>
BridgeConnector.On<MessageBoxResponse>("showMessageBoxComplete" + guid, (args) =>
{
// args is [response:int, checkboxChecked:boolean]
var arr = args.EnumerateArray();
var e = arr.GetEnumerator();
e.MoveNext();
var response = e.Current.GetInt32();
e.MoveNext();
var checkbox = e.Current.GetBoolean();
BridgeConnector.Off("showMessageBoxComplete" + guid);
tcs.SetResult(new MessageBoxResult
taskCompletionSource.SetResult(new MessageBoxResult
{
Response = response,
CheckboxChecked = checkbox
Response = args.response,
CheckboxChecked = args.@checked
});
});
if (browserWindow == null)
if (browserWindow is null)
{
BridgeConnector.Socket.Emit("showMessageBox", messageBoxOptions, guid);
}
else
BridgeConnector.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer), guid);
} else
{
BridgeConnector.Socket.Emit("showMessageBox",
browserWindow,
messageBoxOptions,
guid);
BridgeConnector.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer), JObject.FromObject(messageBoxOptions, _jsonSerializer), guid);
}
return tcs.Task;
return taskCompletionSource.Task;
}
/// <summary>
@@ -176,7 +183,7 @@ namespace ElectronNET.API
/// <param name="content">The text content to display in the error box.</param>
public void ShowErrorBox(string title, string content)
{
BridgeConnector.Socket.Emit("showErrorBox", title, content);
BridgeConnector.Emit("showErrorBox", title, content);
}
/// <summary>
@@ -186,6 +193,8 @@ namespace ElectronNET.API
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("macos")]
public Task ShowCertificateTrustDialogAsync(CertificateTrustDialogOptions options)
{
return ShowCertificateTrustDialogAsync(null, options);
@@ -199,20 +208,29 @@ namespace ElectronNET.API
/// <param name="browserWindow"></param>
/// <param name="options"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("macos")]
public Task ShowCertificateTrustDialogAsync(BrowserWindow browserWindow, CertificateTrustDialogOptions options)
{
var tcs = new TaskCompletionSource<object>();
var taskCompletionSource = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
string guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once("showCertificateTrustDialogComplete" + guid, () => tcs.SetResult(null));
BridgeConnector.Socket.Emit("showCertificateTrustDialog",
browserWindow,
options,
guid);
BridgeConnector.On("showCertificateTrustDialogComplete" + guid, () =>
{
BridgeConnector.Off("showCertificateTrustDialogComplete" + guid);
taskCompletionSource.SetResult(null);
});
return tcs.Task;
BridgeConnector.Emit("showCertificateTrustDialog", browserWindow, options, guid);
return taskCompletionSource.Task;
}
private static readonly JsonSerializer _jsonSerializer = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
}
}

View File

@@ -1,20 +1,24 @@
using ElectronNET.API.Entities;
using ElectronNET.API.Extensions;
using ElectronNET.API.Serialization;
using System.Collections.Generic;
using System.Text.Json;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using ElectronNET.API.Entities;
using ElectronNET.API.Extensions;
using ElectronNET.API.Interfaces;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
namespace ElectronNET.API
{
/// <summary>
/// Control your app in the macOS dock.
/// </summary>
public sealed class Dock
[SupportedOSPlatform("macos")]
public sealed class Dock : IDock
{
private static Dock _dock;
private static object _syncRoot = new object();
private static readonly object _syncRoot = new();
internal Dock()
{
@@ -49,19 +53,11 @@ namespace ElectronNET.API
/// <param name="type">Can be critical or informational. The default is informational.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Return an ID representing the request.</returns>
public async Task<int> BounceAsync(DockBounceType type, CancellationToken cancellationToken = default)
public Task<int> BounceAsync(DockBounceType type, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<int>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<int>("dock-bounce-completed", tcs.SetResult);
BridgeConnector.Socket.Emit("dock-bounce", type.GetDescription());
return await tcs.Task
.ConfigureAwait(false);
}
return BridgeConnector.OnResult<int>("dock-bounce", "dock-bounce-completed", cancellationToken, type.GetDescription());
}
/// <summary>
@@ -70,7 +66,7 @@ namespace ElectronNET.API
/// <param name="id">Id of the request.</param>
public void CancelBounce(int id)
{
BridgeConnector.Socket.Emit("dock-cancelBounce", id);
BridgeConnector.Emit("dock-cancelBounce", id);
}
/// <summary>
@@ -79,7 +75,7 @@ namespace ElectronNET.API
/// <param name="filePath"></param>
public void DownloadFinished(string filePath)
{
BridgeConnector.Socket.Emit("dock-downloadFinished", filePath);
BridgeConnector.Emit("dock-downloadFinished", filePath);
}
/// <summary>
@@ -88,7 +84,7 @@ namespace ElectronNET.API
/// <param name="text"></param>
public void SetBadge(string text)
{
BridgeConnector.Socket.Emit("dock-setBadge", text);
BridgeConnector.Emit("dock-setBadge", text);
}
/// <summary>
@@ -96,19 +92,10 @@ namespace ElectronNET.API
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The badge string of the dock.</returns>
public async Task<string> GetBadgeAsync(CancellationToken cancellationToken = default)
public Task<string> GetBadgeAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<string>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<string>("dock-getBadge-completed", tcs.SetResult);
BridgeConnector.Socket.Emit("dock-getBadge");
return await tcs.Task
.ConfigureAwait(false);
}
return BridgeConnector.OnResult<string>("dock-getBadge", "dock-getBadge-completed", cancellationToken);
}
/// <summary>
@@ -116,7 +103,7 @@ namespace ElectronNET.API
/// </summary>
public void Hide()
{
BridgeConnector.Socket.Emit("dock-hide");
BridgeConnector.Emit("dock-hide");
}
/// <summary>
@@ -124,7 +111,7 @@ namespace ElectronNET.API
/// </summary>
public void Show()
{
BridgeConnector.Socket.Emit("dock-show");
BridgeConnector.Emit("dock-show");
}
/// <summary>
@@ -133,19 +120,10 @@ namespace ElectronNET.API
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Whether the dock icon is visible.</returns>
public async Task<bool> IsVisibleAsync(CancellationToken cancellationToken = default)
public Task<bool> IsVisibleAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<bool>("dock-isVisible-completed", tcs.SetResult);
BridgeConnector.Socket.Emit("dock-isVisible");
return await tcs.Task
.ConfigureAwait(false);
}
return BridgeConnector.OnResult<bool>("dock-isVisible", "dock-isVisible-completed", cancellationToken);
}
/// <summary>
@@ -154,15 +132,8 @@ namespace ElectronNET.API
/// <value>
/// The menu items.
/// </value>
public IReadOnlyCollection<MenuItem> MenuItems
{
get
{
return _items.AsReadOnly();
}
}
private List<MenuItem> _items = new List<MenuItem>();
public IReadOnlyCollection<MenuItem> MenuItems { get { return _items.AsReadOnly(); } }
private readonly List<MenuItem> _items = new();
/// <summary>
/// Sets the application's dock menu.
@@ -170,12 +141,11 @@ namespace ElectronNET.API
public void SetMenu(MenuItem[] menuItems)
{
menuItems.AddMenuItemsId();
BridgeConnector.Socket.Emit("dock-setMenu", new[] { menuItems });
BridgeConnector.Emit("dock-setMenu", JArray.FromObject(menuItems, _jsonSerializer));
_items.AddRange(menuItems);
BridgeConnector.Socket.Off("dockMenuItemClicked");
BridgeConnector.Socket.On<string>("dockMenuItemClicked", (id) =>
{
BridgeConnector.Off("dockMenuItemClicked");
BridgeConnector.On<string>("dockMenuItemClicked", (id) => {
MenuItem menuItem = _items.GetMenuItem(id);
menuItem?.Click();
});
@@ -185,20 +155,7 @@ namespace ElectronNET.API
/// TODO: Menu (macOS) still to be implemented
/// Gets the application's dock menu.
/// </summary>
public async Task<Menu> GetMenu(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<Menu>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
{
BridgeConnector.Socket.Once<Menu>("dock-getMenu-completed", tcs.SetResult);
BridgeConnector.Socket.Emit("dock-getMenu");
return await tcs.Task
.ConfigureAwait(false);
}
}
public Task<Menu> GetMenu(CancellationToken cancellationToken = default) => BridgeConnector.OnResult<Menu>("dock-getMenu", "dock-getMenu-completed", cancellationToken);
/// <summary>
/// Sets the image associated with this dock icon.
@@ -206,9 +163,13 @@ namespace ElectronNET.API
/// <param name="image"></param>
public void SetIcon(string image)
{
BridgeConnector.Socket.Emit("dock-setIcon", image);
BridgeConnector.Emit("dock-setIcon", image);
}
private static readonly JsonSerializer _jsonSerializer = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore
};
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ElectronNET.API
{
public static partial class Electron
{
/// <summary>
/// Experimental code, use with care
/// </summary>
public static class Experimental
{
/// <summary>
/// Starts electron from C#, use during development to avoid having to fully publish / build your app on every compile cycle
/// You will need to run the CLI at least once (and once per update) to bootstrap all required files
/// </summary>
/// <param name="webPort"></param>
/// <param name="projectPath"></param>
/// <param name="extraElectronArguments"></param>
/// <param name="clearCache"></param>
/// <exception cref="DirectoryNotFoundException"></exception>
/// <exception cref="Exception"></exception>
public static async Task<int> StartElectronForDevelopment(int webPort, string projectPath = null, string[] extraElectronArguments = null, bool clearCache = false)
{
string aspCoreProjectPath;
if (!string.IsNullOrEmpty(projectPath))
{
if (Directory.Exists(projectPath))
{
aspCoreProjectPath = projectPath;
}
else
{
throw new DirectoryNotFoundException(projectPath);
}
}
else
{
aspCoreProjectPath = Directory.GetCurrentDirectory();
}
string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
var mainFileJs = Path.Combine(tempPath, "main.js");
if (!File.Exists(mainFileJs))
{
throw new Exception("You need to run once the electronize-h5 start command to bootstrap the necessary files");
}
var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");
bool runNpmInstall = false;
if (!Directory.Exists(nodeModulesDirPath))
{
runNpmInstall = true;
}
var packagesJson = Path.Combine(tempPath, "package.json");
var packagesPrevious = Path.Combine(tempPath, "package.json.previous");
if (!runNpmInstall)
{
if (File.Exists(packagesPrevious))
{
if (File.ReadAllText(packagesPrevious) != File.ReadAllText(packagesJson))
{
runNpmInstall = true;
}
}
else
{
runNpmInstall = true;
}
}
if (runNpmInstall)
{
throw new Exception("You need to run once the electronize-h5 start command to bootstrap the necessary files");
}
string arguments = "";
if (extraElectronArguments is object)
{
arguments = string.Join(' ', extraElectronArguments);
}
if (clearCache)
{
arguments += " --clear-cache=true";
}
BridgeConnector.AuthKey = Guid.NewGuid().ToString().Replace("-", "");
var socketPort = FreeTcpPort();
arguments += $" --development=true --devauth={BridgeConnector.AuthKey} --devport={socketPort}";
string path = Path.Combine(tempPath, "node_modules", ".bin");
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
ProcessHelper.Execute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
}
else
{
ProcessHelper.Execute(@"./electron ""../../main.js"" " + arguments, path);
}
BridgeSettings.InitializePorts(socketPort, webPort);
await Task.Delay(500);
return socketPort;
}
/// <summary>
/// Return a free local TCP port
/// </summary>
/// <returns></returns>
public static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
}
}
}

139
ElectronNET.API/Electron.cs Normal file
View File

@@ -0,0 +1,139 @@
using Microsoft.Extensions.Logging;
using System.Runtime.Versioning;
using System;
using System.Collections.Generic;
namespace ElectronNET.API
{
/// <summary>
/// The Electron.NET API
/// </summary>
public static partial class Electron
{
private static ILoggerFactory loggerFactory;
/// <summary>
/// Reads the auth key from the command line. This method must be called first thing.
/// </summary>
/// <exception cref="Exception"></exception>
public static void ReadAuth()
{
if (!string.IsNullOrEmpty(BridgeConnector.AuthKey))
{
throw new Exception($"Don't call ReadAuth twice or from with {nameof(Experimental)}.{nameof(Experimental.StartElectronForDevelopment)}");
}
var line = Console.ReadLine();
if(line.StartsWith("Auth="))
{
BridgeConnector.AuthKey = line.Substring("Auth=".Length);
}
else
{
throw new Exception("The call to Electron.ReadAuth must be the first thing your app entry point does");
}
}
/// <summary>
/// Sets the logger factory to be used by Electron, if any
/// </summary>
public static ILoggerFactory LoggerFactory
{
private get => loggerFactory; set
{
loggerFactory = value;
BridgeConnector.Logger = value.CreateLogger<App>();
}
}
/// <summary>
/// Communicate asynchronously from the main process to renderer processes.
/// </summary>
public static IpcMain IpcMain { get { return IpcMain.Instance; } }
/// <summary>
/// Control your application's event lifecycle.
/// </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>
public static WindowManager WindowManager { get { return WindowManager.Instance; } }
/// <summary>
/// Create native application menus and context menus.
/// </summary>
public static Menu Menu { get { return Menu.Instance; } }
/// <summary>
/// Display native system dialogs for opening and saving files, alerting, etc.
/// </summary>
public static Dialog Dialog { get { return Dialog.Instance; } }
/// <summary>
/// Create OS desktop notifications
/// </summary>
public static Notification Notification { get { return Notification.Instance; } }
/// <summary>
/// Add icons and context menus to the systems notification area.
/// </summary>
public static Tray Tray { get { return Tray.Instance; } }
/// <summary>
/// Detect keyboard events when the application does not have keyboard focus.
/// </summary>
public static GlobalShortcut GlobalShortcut { get { return GlobalShortcut.Instance; } }
/// <summary>
/// Manage files and URLs using their default applications.
/// </summary>
public static Shell Shell { get { return Shell.Instance; } }
/// <summary>
/// Retrieve information about screen size, displays, cursor position, etc.
/// </summary>
public static Screen Screen { get { return Screen.Instance; } }
/// <summary>
/// Access information about media sources that can be used to capture audio and video from the desktop using the navigator.mediaDevices.getUserMedia API.
/// </summary>
public static DesktopCapturer DesktopCapturer { get { return DesktopCapturer.Instance; } }
/// <summary>
/// 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; } }
/// <summary>
/// Allows you to execute native Lock and Unlock process.
/// </summary>
public static PowerMonitor PowerMonitor { get { return PowerMonitor.Instance; } }
/// <summary>
/// Read and respond to changes in Chromium's native color theme.
/// </summary>
public static NativeTheme NativeTheme { get { return NativeTheme.Instance; } }
/// <summary>
/// Control your app in the macOS dock.
/// </summary>
[SupportedOSPlatform("macos")]
public static Dock Dock { get { return Dock.Instance; } }
}
}

View File

@@ -0,0 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageOutputPath>..\artifacts</PackageOutputPath>
<PackageId>ElectronNET.API</PackageId>
<Authors>Gregor Biswanger, Robert Muehsig</Authors>
<Company />
<Product>Electron.NET</Product>
<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 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>
<PackageIcon>PackageIcon.png</PackageIcon>
<Version>99.0.0.0</Version>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<None Include="PackageIcon.png" Pack="true" PackagePath="\" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(OS)' == 'Windows_NT'">
<Exec Command="$(ProjectDir)devCleanup.cmd" IgnoreExitCode="true" />
</Target>
<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.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="SocketIOClient" Version="3.0.6" />
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
</ItemGroup>
</Project>

View File

@@ -18,7 +18,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Gets or sets the scalefactor
/// </summary>
public float ScaleFactor { get; set; } = 1.0f;
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
/// <summary>
/// Gets or sets the buffer
@@ -28,6 +28,6 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Gets or sets the dataURL
/// </summary>
public string DataUrl { get; set; }
public string DataUrl { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
[Obsolete("Use ImageOptions instead.")]
public class BitmapOptions
{
/// <summary>
/// Gets or sets the scale factor
/// </summary>
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
/// <summary>
/// Utility conversion for obsolete class
/// </summary>
public static implicit operator ImageOptions(BitmapOptions o) => new() {ScaleFactor = o.ScaleFactor};
}
}

View File

@@ -1,4 +1,8 @@
namespace ElectronNET.API.Entities
using System;
using System.Collections.Generic;
using System.Text;
namespace ElectronNET.API.Entities
{
/// <summary>
///

View File

@@ -1,7 +1,7 @@
using ElectronNET.Converter;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.ComponentModel;
using System.Text.Json.Serialization;
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
@@ -37,62 +37,62 @@ namespace ElectronNET.API.Entities
/// window's size will include window frame's size and be slightly larger. Default
/// is false.
/// </summary>
public bool UseContentSize { get; set; }
public bool? UseContentSize { get; set; }
/// <summary>
/// Show window in the center of the screen.
/// </summary>
public bool Center { get; set; }
public bool? Center { get; set; }
/// <summary>
/// Window's minimum width. Default is 0.
/// </summary>
public int MinWidth { get; set; }
public int? MinWidth { get; set; }
/// <summary>
/// Window's minimum height. Default is 0.
/// </summary>
public int MinHeight { get; set; }
public int? MinHeight { get; set; }
/// <summary>
/// Window's maximum width. Default is no limit.
/// </summary>
public int MaxWidth { get; set; }
public int? MaxWidth { get; set; }
/// <summary>
/// Window's maximum height. Default is no limit.
/// </summary>
public int MaxHeight { get; set; }
public int? MaxHeight { get; set; }
/// <summary>
/// Whether window is resizable. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Resizable { get; set; } = true;
public bool? Resizable { get; set; } = true;
/// <summary>
/// Whether window is movable. This is not implemented on Linux. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Movable { get; set; } = true;
public bool? Movable { get; set; } = true;
/// <summary>
/// Whether window is minimizable. This is not implemented on Linux. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Minimizable { get; set; } = true;
public bool? Minimizable { get; set; } = true;
/// <summary>
/// Whether window is maximizable. This is not implemented on Linux. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Maximizable { get; set; } = true;
public bool? Maximizable { get; set; } = true;
/// <summary>
/// Whether window is closable. This is not implemented on Linux. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Closable { get; set; } = true;
public bool? Closable { get; set; } = true;
/// <summary>
/// Whether the window can be focused. Default is true. On Windows setting
@@ -101,35 +101,35 @@ namespace ElectronNET.API.Entities
/// always stay on top in all workspaces.
/// </summary>
[DefaultValue(true)]
public bool Focusable { get; set; } = true;
public bool? Focusable { get; set; } = true;
/// <summary>
/// Whether the window should always stay on top of other windows. Default is false.
/// </summary>
public bool AlwaysOnTop { get; set; }
public bool? AlwaysOnTop { get; set; }
/// <summary>
/// Whether the window should show in fullscreen. When explicitly set to false the
/// fullscreen button will be hidden or disabled on macOS.Default is false.
/// </summary>
public bool Fullscreen { get; set; }
public bool? Fullscreen { get; set; }
/// <summary>
/// Whether the window can be put into fullscreen mode. On macOS, also whether the
/// maximize/zoom button should toggle full screen mode or maximize window.Default
/// is true.
/// </summary>
public bool Fullscreenable { get; set; }
public bool? Fullscreenable { get; set; }
/// <summary>
/// Whether to show the window in taskbar. Default is false.
/// </summary>
public bool SkipTaskbar { get; set; }
public bool? SkipTaskbar { get; set; }
/// <summary>
/// The kiosk mode. Default is false.
/// </summary>
public bool Kiosk { get; set; }
public bool? Kiosk { get; set; }
/// <summary>
/// Default window title. Default is "Electron.NET".
@@ -146,40 +146,40 @@ namespace ElectronNET.API.Entities
/// Whether window should be shown when created. Default is true.
/// </summary>
[DefaultValue(true)]
public bool Show { get; set; } = true;
public bool? Show { get; set; } = true;
/// <summary>
/// Specify false to create a . Default is true.
/// </summary>
[DefaultValue(true)]
public bool Frame { get; set; } = true;
public bool? Frame { get; set; } = true;
/// <summary>
/// Whether this is a modal window. This only works when the window is a child
/// window.Default is false.
/// Whether this is a modal window. This only works when <see cref="Parent"/> is
/// also specified. Default is false.
/// </summary>
public bool Modal { get; set; }
public bool? Modal { get; set; }
/// <summary>
/// Whether the web view accepts a single mouse-down event that simultaneously
/// activates the window.Default is false.
/// activates the window. Default is false.
/// </summary>
public bool AcceptFirstMouse { get; set; }
public bool? AcceptFirstMouse { get; set; }
/// <summary>
/// Whether to hide cursor when typing. Default is false.
/// </summary>
public bool DisableAutoHideCursor { get; set; }
public bool? DisableAutoHideCursor { get; set; }
/// <summary>
/// Auto hide the menu bar unless the Alt key is pressed. Default is false.
/// </summary>
public bool AutoHideMenuBar { get; set; }
public bool? AutoHideMenuBar { get; set; }
/// <summary>
/// Enable the window to be resized larger than screen. Default is false.
/// </summary>
public bool EnableLargerThanScreen { get; set; }
public bool? EnableLargerThanScreen { get; set; }
/// <summary>
/// Window's background color as Hexadecimal value, like #66CD00 or #FFF or
@@ -191,18 +191,18 @@ namespace ElectronNET.API.Entities
/// Whether window should have a shadow. This is only implemented on macOS. Default
/// is true.
/// </summary>
public bool HasShadow { get; set; }
public bool? HasShadow { get; set; }
/// <summary>
/// Forces using dark theme for the window, only works on some GTK+3 desktop
/// environments.Default is false.
/// </summary>
public bool DarkTheme { get; set; }
public bool? DarkTheme { get; set; }
/// <summary>
/// Makes the window transparent. Default is false.
/// Makes the window . Default is false.
/// </summary>
public bool Transparent { get; set; }
public bool? Transparent { get; set; }
/// <summary>
/// The type of window, default is normal window.
@@ -213,25 +213,22 @@ namespace ElectronNET.API.Entities
/// The style of window title bar. Default is default. Possible values are:
/// 'default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover'
/// </summary>
public TitleBarStyle TitleBarStyle { get; set; }
/// <summary>
/// Configures the window's title bar overlay when using a frameless window.
/// Can be either:
/// - false: No title bar overlay.
/// - true: Enables the default title bar overlay.
/// - An object defining custom overlay options (such as height, color, etc.).
///
/// Default is false.
/// </summary>
[JsonConverter(typeof(TitleBarOverlayConverter))]
public TitleBarOverlay TitleBarOverlay { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public TitleBarStyle? TitleBarStyle { get; set; }
/// <summary>
/// Shows the title in the tile bar in full screen mode on macOS for all
/// titleBarStyle options.Default is false.
/// </summary>
public bool FullscreenWindowTitle { get; set; }
public bool? FullscreenWindowTitle { get; set; }
/// <summary>
/// Activate the Window Controls Overlay on Windows, when combined with <see cref="TitleBarStyle"/> = <see cref="TitleBarStyle.hidden"/>
/// </summary>
[SupportedOSPlatform("win")]
[SupportedOSPlatform("macos")]
[DefaultValue(null)]
public TitleBarOverlayConfig TitleBarOverlay { get; set; }
/// <summary>
/// Use WS_THICKFRAME style for frameless windows on Windows, which adds standard
@@ -239,23 +236,15 @@ namespace ElectronNET.API.Entities
/// animations. Default is true.
/// </summary>
[DefaultValue(true)]
public bool ThickFrame { get; set; } = true;
/// <summary>
/// Whether frameless window should have rounded corners. Default is true. Setting this
/// property to false will prevent the window from being fullscreenable on macOS. On
/// Windows versions older than Windows 11 Build 22000 this property has no effect, and
/// frameless windows will not have rounded corners.
/// </summary>
[DefaultValue(true)]
public bool RoundedCorners { get; set; } = true;
public bool? ThickFrame { get; set; } = true;
/// <summary>
/// Add a type of vibrancy effect to the window, only on macOS. Can be
/// appearance-based, light, dark, titlebar, selection, menu, popover, sidebar,
/// medium-light or ultra-dark.
/// </summary>
public Vibrancy Vibrancy { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public Vibrancy? Vibrancy { get; set; }
/// <summary>
/// Controls the behavior on macOS when option-clicking the green stoplight button
@@ -264,7 +253,7 @@ namespace ElectronNET.API.Entities
/// it to zoom to the width of the screen.This will also affect the behavior when
/// calling maximize() directly.Default is false.
/// </summary>
public bool ZoomToPageWidth { get; set; }
public bool? ZoomToPageWidth { get; set; }
/// <summary>
/// Tab group name, allows opening the window as a native tab on macOS 10.12+.
@@ -290,9 +279,19 @@ namespace ElectronNET.API.Entities
/// These will only be used if the Proxy field is also set.
/// </summary>
public string ProxyCredentials { get; set; }
/// <summary>
/// The window to use as the created window's parent.
/// </summary>
[DefaultValue(null)]
public BrowserWindow Parent { get; set; }
/// <summary>
/// Set a custom position for the traffic light buttons in frameless windows.
/// </summary>
[DefaultValue(null)]
[SupportedOSPlatform("macos")]
public Point TrafficLightPosition { get; set; }
}
}

View File

@@ -8,7 +8,7 @@
/// <summary>
/// Percentage of CPU used since the last call to getCPUUsage. First call returns 0.
/// </summary>
public double PercentCPUUsage { get; set; }
public int PercentCPUUsage { get; set; }
/// <summary>
/// The number of average idle cpu wakeups per second since the last call to

View File

@@ -1,4 +1,8 @@
namespace ElectronNET.API.Entities
using System;
using System.Collections.Generic;
using System.Text;
namespace ElectronNET.API.Entities
{
/// <summary>
/// Provide metadata about the current loaded Chrome extension

View File

@@ -1,14 +1,12 @@
namespace ElectronNET.API.Entities
{
namespace ElectronNET.API.Entities {
/// <summary>
///
/// </summary>
public class Cookie
{
public class Cookie {
/// <summary>
/// The name of the cookie.
/// </summary>
public string Name { get; set; }
public string Name { get; set;}
/// <summary>
/// The value of the cookie.
@@ -28,7 +26,7 @@
/// <summary>
/// (optional) - The path of the cookie.
/// </summary>
public string Path { get; set; }
public string Path { get; set; }
/// <summary>
/// (optional) - Whether the cookie is marked as secure.
@@ -38,7 +36,7 @@
/// <summary>
/// (optional) - Whether the cookie is marked as HTTP only.
/// </summary>
public bool HttpOnly { get; set; }
public bool HttpOnly { get; set; }
/// <summary>
/// (optional) - Whether the cookie is a session cookie or a persistent cookie with an expiration date.
@@ -50,4 +48,4 @@
/// </summary>
public long ExpirationDate { get; set; }
}
}
}

View File

@@ -1,17 +1,19 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ElectronNET.API.Entities
{
/// <summary>
/// The cause of the change
/// </summary>
public enum CookieChangedCause
[JsonConverter(typeof(StringEnumConverter))]
public enum CookieChangedCause
{
/// <summary>
///The cookie was changed directly by a consumer's action.
/// </summary>
[JsonPropertyName("explicit")]
[JsonProperty("explicit")]
@explicit,
/// <summary>
@@ -32,7 +34,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// The cookie was overwritten with an already-expired expiration date.
/// </summary>
[JsonPropertyName("expired_overwrite")]
[JsonProperty("expired_overwrite")]
expiredOverwrite
}
}
}

View File

@@ -1,12 +1,10 @@
using System.ComponentModel;
namespace ElectronNET.API.Entities
{
namespace ElectronNET.API.Entities {
/// <summary>
///
/// </summary>
public class CookieDetails
{
public class CookieDetails {
/// <summary>
/// The URL to associate the cookie with. The callback will be rejected if the URL is invalid.
/// </summary>
@@ -21,7 +19,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// (optional) - The value of the cookie. Empty by default if omitted.
/// </summary>
[DefaultValue("")]
[DefaultValue("")]
public string Value { get; set; }
/// <summary>
@@ -33,13 +31,13 @@ namespace ElectronNET.API.Entities
/// <summary>
/// (optional) - The path of the cookie. Empty by default if omitted.
/// </summary>
[DefaultValue("")]
[DefaultValue("")]
public string Path { get; set; }
/// <summary>
/// (optional) - Whether the cookie is marked as secure. Defaults to false.
/// </summary>
[DefaultValue(false)]
[DefaultValue(false)]
public bool Secure { get; set; }
/// <summary>
@@ -55,4 +53,4 @@ namespace ElectronNET.API.Entities
[DefaultValue(0)]
public long ExpirationDate { get; set; }
}
}
}

View File

@@ -1,9 +1,13 @@
namespace ElectronNET.API.Entities
using System;
using System.Collections.Generic;
using System.Text;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
public class CookieFilter
public class CookieFilter
{
/// <summary>
/// (optional) - Retrieves cookies which are associated with url.Empty implies retrieving cookies of all URLs.
@@ -34,5 +38,6 @@
/// (optional) - Filters out session or persistent cookies.
/// </summary>
public bool Session { get; set; }
}
}
}

View File

@@ -0,0 +1,10 @@
namespace ElectronNET.API.Entities
{
public class CookieRemovedResponse
{
public Cookie cookie {get;set;}
public CookieChangedCause cause { get; set; }
public bool removed { get; set; }
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
[Obsolete("Use CreateOptions instead")]
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; } = NativeImage.DefaultScaleFactor;
/// <summary>
/// Utility conversion for obsolete class
/// </summary>
public static implicit operator CreateOptions(CreateFromBitmapOptions o) => new()
{Width = o.Width, Height = o.Height, ScaleFactor = o.ScaleFactor};
}
}

View File

@@ -0,0 +1,31 @@
using System;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
[Obsolete("Use CreateOptions instead")]
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; } = NativeImage.DefaultScaleFactor;
/// <summary>
/// Utility conversion for obsolete class
/// </summary>
public static implicit operator CreateOptions(CreateFromBufferOptions o) => new()
{Width = o.Width, Height = o.Height, ScaleFactor = o.ScaleFactor};
}
}

View File

@@ -1,9 +1,9 @@
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// Options for creating a new <see cref="NativeImage"/>
/// </summary>
public class CreateFromBufferOptions
public class CreateOptions
{
/// <summary>
/// Gets or sets the width
@@ -18,6 +18,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Gets or sets the scalefactor
/// </summary>
public float ScaleFactor { get; set; } = 1.0f;
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
}
}

View File

@@ -34,5 +34,7 @@
/// The title of the url at text.
/// </summary>
public string Bookmark { get; set; }
public NativeImage? Image { get; set; }
}
}
}

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
namespace ElectronNET.API.Entities
{
public sealed class DesktopCapturerSource
{
public string Id { get; set; }
public string Name { get; set; }
public NativeImage Thumbnail { get; set; }
[JsonProperty("display_id")]
public string DisplayId { get; set; }
public NativeImage AppIcon { get; set; }
}
}

View File

@@ -0,0 +1,65 @@
namespace ElectronNET.API.Entities
{
public class DisplayChanged
{
public Display display { get; set; }
public string[] metrics { get; set; }
}
/// <summary>
///
/// </summary>
public class Display
{
/// <summary>
/// Gets or sets the bounds.
/// </summary>
/// <value>
/// The bounds.
/// </value>
public Rectangle Bounds { get; set; }
/// <summary>
/// Unique identifier associated with the display.
/// </summary>
public string Id { get; set; }
/// <summary>
/// Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees.
/// </summary>
public float Rotation { get; set; }
/// <summary>
/// Output device's pixel scale factor.
/// </summary>
public float ScaleFactor { get; set; }
/// <summary>
/// Gets or sets the size.
/// </summary>
/// <value>
/// The size.
/// </value>
public Size Size { get; set; }
/// <summary>
/// Can be available, unavailable, unknown.
/// </summary>
public string TouchSupport { get; set; }
/// <summary>
/// Gets or sets the work area.
/// </summary>
/// <value>
/// The work area.
/// </value>
public Rectangle WorkArea { get; set; }
/// <summary>
/// Gets or sets the size of the work area.
/// </summary>
/// <value>
/// The size of the work area.
/// </value>
public Size WorkAreaSize { get; set; }
}
}

View File

@@ -1,4 +1,10 @@
namespace ElectronNET.API.Entities
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ElectronNET.API.Entities
{
/// <summary>
/// Docs: https://electronjs.org/docs/api/structures/extension

View File

@@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace ElectronNET.API.Entities
{
@@ -11,43 +10,43 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Canvas.
/// </summary>
[JsonPropertyName("2d_canvas")]
[JsonProperty("2d_canvas")]
public string Canvas { get; set; }
/// <summary>
/// Flash.
/// </summary>
[JsonPropertyName("flash_3d")]
[JsonProperty("flash_3d")]
public string Flash3D { get; set; }
/// <summary>
/// Flash Stage3D.
/// </summary>
[JsonPropertyName("flash_stage3d")]
[JsonProperty("flash_stage3d")]
public string FlashStage3D { get; set; }
/// <summary>
/// Flash Stage3D Baseline profile.
/// </summary>
[JsonPropertyName("flash_stage3d_baseline")]
[JsonProperty("flash_stage3d_baseline")]
public string FlashStage3dBaseline { get; set; }
/// <summary>
/// Compositing.
/// </summary>
[JsonPropertyName("gpu_compositing")]
[JsonProperty("gpu_compositing")]
public string GpuCompositing { get; set; }
/// <summary>
/// Multiple Raster Threads.
/// </summary>
[JsonPropertyName("multiple_raster_threads")]
[JsonProperty("multiple_raster_threads")]
public string MultipleRasterThreads { get; set; }
/// <summary>
/// Native GpuMemoryBuffers.
/// </summary>
[JsonPropertyName("native_gpu_memory_buffers")]
[JsonProperty("native_gpu_memory_buffers")]
public string NativeGpuMemoryBuffers { get; set; }
/// <summary>
@@ -58,19 +57,19 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Video Decode.
/// </summary>
[JsonPropertyName("video_decode")]
[JsonProperty("video_decode")]
public string VideoDecode { get; set; }
/// <summary>
/// Video Encode.
/// </summary>
[JsonPropertyName("video_encode")]
[JsonProperty("video_encode")]
public string VideoEncode { get; set; }
/// <summary>
/// VPx Video Decode.
/// </summary>
[JsonPropertyName("vpx_decode")]
[JsonProperty("vpx_decode")]
public string VpxDecode { get; set; }
/// <summary>

View File

@@ -1,13 +1,13 @@
namespace ElectronNET.API.Entities
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
public class BitmapOptions
public class ImageOptions
{
/// <summary>
/// Gets or sets the scale factor
/// </summary>
public float ScaleFactor { get; set; } = 1.0f;
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
}
}
}

View File

@@ -9,10 +9,10 @@
/// Path for the pkcs12 file.
/// </summary>
public string Certificate { get; set; }
/// <summary>
/// Passphrase for the certificate.
/// </summary>
public string Password { get; set; }
public string Password {get; set; }
}
}
}

View File

@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ElectronNET.API.Entities
{
@@ -21,7 +21,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// One of the following: "tasks" | "frequent" | "recent" | "custom"
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public JumpListCategoryType Type { get; set; }
}
}
}

View File

@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ElectronNET.API.Entities
{
@@ -52,8 +52,7 @@ namespace ElectronNET.API.Entities
/// <summary>
/// One of the following: "task" | "separator" | "file"
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public JumpListItemType Type { get; set; }
}
}

View File

@@ -1,8 +1,7 @@
namespace ElectronNET.API.Entities
using System;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
public class JumpListSettings
{
/// <summary>
@@ -16,6 +15,6 @@
/// in the Jump List. These items must not be re-added to the Jump List in the next call to <see cref="App.SetJumpList"/>, Windows will
/// not display any custom category that contains any of the removed items.
/// </summary>
public JumpListItem[] RemovedItems { get; set; } = new JumpListItem[0];
public JumpListItem[] RemovedItems { get; set; } = Array.Empty<JumpListItem>();
}
}

View File

@@ -1,5 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Text.Json.Serialization;
using System.ComponentModel;
namespace ElectronNET.API.Entities
{
@@ -19,11 +21,13 @@ namespace ElectronNET.API.Entities
/// Define the action of the menu item, when specified the click property will be
/// ignored.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public MenuRole Role { get; set; }
/// <summary>
/// Can be normal, separator, submenu, checkbox or radio.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public MenuType Type { get; set; }
@@ -97,5 +101,3 @@ namespace ElectronNET.API.Entities
public string Position { get; set; }
}
}

View File

@@ -158,6 +158,17 @@
/// <summary>
/// Only macOS: The submenu is a “Services” menu
/// </summary>
services
services,
/// <summary>
/// Only macOS: the submenue for "Recent Documents"
/// </summary>
recentdocuments,
/// <summary>
/// Only macOS: the menu to clear the recent document list
/// </summary>
clearrecentdocuments,
}
}

View File

@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ElectronNET.API.Entities
{
@@ -13,6 +13,7 @@ namespace ElectronNET.API.Entities
/// displays the same icon as "info", unless you set an icon using the "icon"
/// option. On macOS, both "warning" and "error" display the same warning icon.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public MessageBoxType Type { get; set; }
/// <summary>
@@ -98,5 +99,3 @@ namespace ElectronNET.API.Entities
}
}
}

View File

@@ -1,5 +1,11 @@
namespace ElectronNET.API.Entities
{
internal class MessageBoxResponse
{
public int response { get; set; }
public bool @checked { get; set; }
}
/// <summary>
///
/// </summary>

View File

@@ -1,12 +1,15 @@
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
using System.IO;
using System.Linq;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
namespace ElectronNET.API.Entities
{
@@ -16,14 +19,19 @@ namespace ElectronNET.API.Entities
[JsonConverter(typeof(NativeImageJsonConverter))]
public class NativeImage
{
/// <summary>
///
/// </summary>
public const float DefaultScaleFactor = 1.0f;
private readonly Dictionary<float, Image> _images = new Dictionary<float, Image>();
private bool _isTemplateImage;
private static readonly Dictionary<string, float> ScaleFactorPairs = new Dictionary<string, float>
private static readonly Dictionary<string, float> ScaleFactorPairs = new()
{
{ "@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 }
{"@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}
};
private static float? ExtractDpiFromFilePath(string filePath)
@@ -34,11 +42,9 @@ namespace ElectronNET.API.Entities
.Select(p => p.Value)
.FirstOrDefault();
}
private static Image BytesToImage(byte[] bytes)
{
var ms = new MemoryStream(bytes);
return Image.FromStream(ms);
return Image.Load(new MemoryStream(bytes));
}
/// <summary>
@@ -52,30 +58,35 @@ namespace ElectronNET.API.Entities
/// <summary>
///
/// </summary>
public static NativeImage CreateFromBitmap(Bitmap bitmap, CreateFromBitmapOptions options = null)
public static NativeImage CreateFromImage(Image image, CreateFromBitmapOptions options = null)
{
if (options is null)
{
options = new CreateFromBitmapOptions();
}
return new NativeImage(bitmap, options.ScaleFactor);
return new NativeImage(image, options.ScaleFactor);
}
/// <summary>
///
/// </summary>
public static NativeImage CreateFromImage(Image image, CreateOptions options = null)
=> new (image, options?.ScaleFactor ?? DefaultScaleFactor);
/// <summary>
/// Creates a NativeImage from a byte array.
/// </summary>
public static NativeImage CreateFromBuffer(byte[] buffer, CreateFromBufferOptions options = null)
public static NativeImage CreateFromBuffer(byte[] buffer, CreateOptions options = null)
{
if (options is null)
{
options = new CreateFromBufferOptions();
}
var ms = new MemoryStream(buffer);
var image = Image.FromStream(ms);
var image = Image.Load(new MemoryStream(buffer));
return new NativeImage(image, options.ScaleFactor);
return new NativeImage(image, options?.ScaleFactor ?? DefaultScaleFactor);
}
/// <summary>
@@ -84,7 +95,7 @@ namespace ElectronNET.API.Entities
/// <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 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);
@@ -102,7 +113,7 @@ namespace ElectronNET.API.Entities
/// <param name="path">The path of the image</param>
public static NativeImage CreateFromPath(string path)
{
var images = new Dictionary<float, Image>();
var images = new Dictionary<float,Image>();
if (Regex.IsMatch(path, "(@.+?x)"))
{
var dpi = ExtractDpiFromFilePath(path);
@@ -111,14 +122,14 @@ namespace ElectronNET.API.Entities
throw new Exception($"Invalid scaling factor for '{path}'.");
}
images[dpi.Value] = Image.FromFile(path);
images[dpi.Value] = Image.Load(path);
}
else
{
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
var extension = Path.GetExtension(path);
// Load as 1x dpi
images[1.0f] = Image.FromFile(path);
images[1.0f] = Image.Load(path);
foreach (var scale in ScaleFactorPairs)
{
@@ -128,7 +139,7 @@ namespace ElectronNET.API.Entities
var dpi = ExtractDpiFromFilePath(fileName);
if (dpi != null)
{
images[dpi.Value] = Image.FromFile(fileName);
images[dpi.Value] = Image.Load(fileName);
}
}
}
@@ -147,9 +158,9 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Creates a NativeImage from a bitmap and scale factor
/// </summary>
public NativeImage(Image bitmap, float scaleFactor = 1.0f)
public NativeImage(Image image, float scaleFactor = DefaultScaleFactor)
{
_images.Add(scaleFactor, bitmap);
_images.Add(scaleFactor, image);
}
/// <summary>
@@ -197,7 +208,7 @@ namespace ElectronNET.API.Entities
if (options.Buffer.Length > 0)
{
_images[options.ScaleFactor] =
CreateFromBuffer(options.Buffer, new CreateFromBufferOptions { ScaleFactor = options.ScaleFactor })
CreateFromBuffer(options.Buffer, new CreateOptions {ScaleFactor = options.ScaleFactor})
.GetScale(options.ScaleFactor);
}
else if (!string.IsNullOrEmpty(options.DataUrl))
@@ -215,7 +226,7 @@ namespace ElectronNET.API.Entities
var image = GetScale(scaleFactor);
if (image != null)
{
return image.Width / image.Height;
return (float)image.Width / image.Height;
}
return 0f;
@@ -224,9 +235,9 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Returns a byte array that contains the image's raw bitmap pixel data.
/// </summary>
public byte[] GetBitmap(BitmapOptions options)
public byte[] GetBitmap(float scaleFactor)
{
return ToBitmap(new ToBitmapOptions { ScaleFactor = options.ScaleFactor });
return ToBitmap(scaleFactor).ToArray();
}
/// <summary>
@@ -234,26 +245,14 @@ namespace ElectronNET.API.Entities
/// </summary>
public byte[] GetNativeHandle()
{
return ToBitmap(new ToBitmapOptions());
return ToBitmap().ToArray();
}
/// <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;
}
=> _images.TryGetValue(scaleFactor, out var image) ? image.Size() : null;
/// <summary>
/// Checks to see if the NativeImage instance is empty.
@@ -279,177 +278,127 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Outputs a bitmap based on the scale factor
/// </summary>
public byte[] ToBitmap(ToBitmapOptions options)
public MemoryStream ToBitmap(float scaleFactor = 1.0f)
{
return ImageToBytes(ImageFormat.Bmp, options.ScaleFactor);
var ms = new MemoryStream();
_images[scaleFactor].SaveAsBmp(ms);
return ms;
}
/// <summary>
/// Outputs a data URL based on the scale factor
/// Outputs a PNG based on the scale factor
/// </summary>
public string ToDataURL(ToDataUrlOptions options)
public string ToDataURL(ImageOptions options)
=> _images.TryGetValue(options.ScaleFactor, out var image)
? $"data:image/png;base64,{image.ToBase64String(PngFormat.Instance)}"
: null;
public MemoryStream ToPng(float scaleFactor = 1.0f)
{
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}";
var ms = new MemoryStream();
_images[scaleFactor].SaveAsPng(ms);
return ms;
}
/// <summary>
/// Outputs a JPEG for the default scale factor
/// </summary>
public byte[] ToJPEG(int quality)
public MemoryStream ToJpeg(int quality, float scaleFactor = 1.0f)
{
return ImageToBytes(ImageFormat.Jpeg, 1.0f, quality);
var ms = new MemoryStream();
_images[scaleFactor].SaveAsJpeg(ms, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder() { Quality = quality });
return ms;
}
/// <summary>
/// Outputs a PNG for the specified scale factor
/// Outputs a data URL based on the scale factor
/// </summary>
public byte[] ToPNG(ToPNGOptions options)
public string ToDataURL(float scaleFactor = 1.0f)
{
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))
if (!_images.TryGetValue(scaleFactor, out var image))
{
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();
throw new KeyNotFoundException($"Missing scaleFactor = {scaleFactor}");
}
return null;
return image.ToBase64String(PngFormat.Instance);
}
private Image Resize(int? width, int? height, float scaleFactor = 1.0f)
{
if (!_images.ContainsKey(scaleFactor) || (width is null && height is null))
if (!_images.TryGetValue(scaleFactor, out var image) || (width is null && height is null))
{
return null;
throw new KeyNotFoundException($"Missing scaleFactor = {scaleFactor}");
}
if (width is null && height is null)
{
throw new ArgumentNullException("Missing width or height");
}
var image = _images[scaleFactor];
using (var g = Graphics.FromImage(image))
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);
return image.Clone(c => c.Resize(new SixLabors.ImageSharp.Processing.ResizeOptions
{
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;
}
Size = new(width.Value, height.Value),
Sampler = KnownResamplers.Triangle,
}));
}
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))
if (!_images.TryGetValue(scaleFactor, out 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;
throw new KeyNotFoundException($"Missing scaleFactor = {scaleFactor}");
}
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);
return image.Clone(c => c.Crop(new SixLabors.ImageSharp.Rectangle(x.Value, y.Value, width.Value, height.Value)));
}
private ImageCodecInfo GetEncoder(ImageFormat format)
internal Dictionary<float,string> GetAllScaledImages()
{
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>();
var dict = new Dictionary<float,string>();
try
{
foreach (var (scale, image) in _images)
{
dict.Add(scale, Convert.ToBase64String(ImageToBytes(null, scale)));
dict.Add(scale, image.ToBase64String(PngFormat.Instance));
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
BridgeConnector.LogError(ex, "Error getting scaled images");
}
return dict;
}
internal Image GetScale(float scaleFactor)
{
if (_images.ContainsKey(scaleFactor))
if (_images.TryGetValue(scaleFactor, out var image))
{
return _images[scaleFactor];
return image;
}
return null;
}
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
using System.IO;
using Newtonsoft.Json;
using SixLabors.ImageSharp;
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<string, string>>(reader);
var newDictionary = new Dictionary<float, Image>();
foreach (var item in dict)
{
if (float.TryParse(item.Key, out var size))
{
var bytes = Convert.FromBase64String(item.Value);
newDictionary.Add(size, Image.Load(new MemoryStream(bytes)));
}
}
return new NativeImage(newDictionary);
}
public override bool CanConvert(Type objectType) => objectType == typeof(NativeImage);
}
}

View File

@@ -1,8 +1,11 @@
namespace ElectronNET.API.Entities
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
[SupportedOSPlatform("macos")]
public class NotificationAction
{
/// <summary>

View File

@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Text.Json.Serialization;
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
@@ -17,6 +18,8 @@ namespace ElectronNET.API.Entities
/// <summary>
/// A subtitle for the notification, which will be displayed below the title.
/// </summary>
[SupportedOSPlatform("macos")]
public string SubTitle { get; set; }
/// <summary>
@@ -38,38 +41,46 @@ namespace ElectronNET.API.Entities
/// <summary>
/// Whether or not to add an inline reply option to the notification.
/// </summary>
[SupportedOSPlatform("macos")]
public bool HasReply { get; set; }
/// <summary>
/// The timeout duration of the notification. Can be 'default' or 'never'.
/// </summary>
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("linux")]
public string TimeoutType { get; set; }
/// <summary>
/// The placeholder to write in the inline reply input field.
/// </summary>
[SupportedOSPlatform("macos")]
public string ReplyPlaceholder { get; set; }
/// <summary>
/// The name of the sound file to play when the notification is shown.
/// </summary>
[SupportedOSPlatform("macos")]
public string Sound { get; set; }
/// <summary>
/// The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
/// </summary>
[SupportedOSPlatform("linux")]
public string Urgency { get; set; }
/// <summary>
/// Actions to add to the notification. Please read the available actions and
/// limitations in the NotificationAction documentation.
/// </summary>
[SupportedOSPlatform("macos")]
public NotificationAction Actions { get; set; }
/// <summary>
/// A custom title for the close button of an alert. An empty string will cause the
/// default localized text to be used.
/// </summary>
[SupportedOSPlatform("macos")]
public string CloseButtonText { get; set; }
/// <summary>
@@ -86,7 +97,7 @@ namespace ElectronNET.API.Entities
/// <value>
/// The show identifier.
/// </value>
[JsonInclude]
[JsonProperty]
internal string ShowID { get; set; }
/// <summary>
@@ -101,7 +112,7 @@ namespace ElectronNET.API.Entities
/// <value>
/// The click identifier.
/// </value>
[JsonInclude]
[JsonProperty]
internal string ClickID { get; set; }
/// <summary>
@@ -118,7 +129,7 @@ namespace ElectronNET.API.Entities
/// <value>
/// The close identifier.
/// </value>
[JsonInclude]
[JsonProperty]
internal string CloseID { get; set; }
/// <summary>
@@ -127,6 +138,7 @@ namespace ElectronNET.API.Entities
/// The string the user entered into the inline reply field
/// </summary>
[JsonIgnore]
[SupportedOSPlatform("macos")]
public Action<string> OnReply { get; set; }
/// <summary>
@@ -135,13 +147,14 @@ namespace ElectronNET.API.Entities
/// <value>
/// The reply identifier.
/// </value>
[JsonInclude]
[JsonProperty]
internal string ReplyID { get; set; }
/// <summary>
/// macOS only - The index of the action that was activated
/// </summary>
[JsonIgnore]
[SupportedOSPlatform("macos")]
public Action<string> OnAction { get; set; }
/// <summary>
@@ -150,7 +163,7 @@ namespace ElectronNET.API.Entities
/// <value>
/// The action identifier.
/// </value>
[JsonInclude]
[JsonProperty]
internal string ActionID { get; set; }
/// <summary>

View File

@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace ElectronNET.API.Entities
{
@@ -13,7 +13,7 @@ namespace ElectronNET.API.Entities
/// detach.Defaults to last used dock state.In undocked mode it's possible to dock
/// back.In detach mode it's not.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public DevToolsMode Mode { get; set; }
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
@@ -33,11 +34,13 @@ namespace ElectronNET.API.Entities
/// Contains which features the dialog should use. The following values are supported:
/// 'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory'
/// </summary>
[JsonProperty("properties", ItemConverterType = typeof(StringEnumConverter))]
public OpenDialogProperty[] Properties { get; set; }
/// <summary>
/// Message to display above input boxes.
/// </summary>
[SupportedOSPlatform("macos")]
public string Message { get; set; }
/// <summary>
@@ -57,5 +60,4 @@ namespace ElectronNET.API.Entities
/// </example>
public FileFilter[] Filters { get; set; }
}
}
}

View File

@@ -0,0 +1,95 @@
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
public enum OpenDialogProperty
{
/// <summary>
/// The open file
/// </summary>
openFile,
/// <summary>
/// The open directory
/// </summary>
openDirectory,
/// <summary>
/// The multi selections
/// </summary>
multiSelections,
/// <summary>
/// The show hidden files
/// </summary>
showHiddenFiles,
/// <summary>
/// The create directory
/// </summary>
[SupportedOSPlatform("macos")]
createDirectory,
/// <summary>
/// The prompt to create
/// </summary>
[SupportedOSPlatform("windows")]
promptToCreate,
/// <summary>
/// The no resolve aliases
/// </summary>
[SupportedOSPlatform("macos")]
noResolveAliases,
/// <summary>
/// Treat packages, such as .app folders, as a directory instead of a file.
/// </summary>
[SupportedOSPlatform("macos")]
treatPackageAsDirectory,
/// <summary>
/// Don't add the item being opened to recent documents list
/// </summary>
[SupportedOSPlatform("windows")]
dontAddToRecent
}
/// <summary>
///
/// </summary>
public enum SaveDialogProperty
{
/// <summary>
/// The show hidden files
/// </summary>
showHiddenFiles,
/// <summary>
/// The create directory
/// </summary>
[SupportedOSPlatform("macos")]
createDirectory,
/// <summary>
/// Treat packages, such as .app folders, as a directory instead of a file.
/// </summary>
[SupportedOSPlatform("macos")]
treatPackageAsDirectory,
/// <summary>
/// Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.
/// </summary>
[SupportedOSPlatform("linux")]
showOverwriteConfirmation,
/// <summary>
/// Don't add the item being opened to recent documents list
/// </summary>
[SupportedOSPlatform("windows")]
dontAddToRecent
}
}

View File

@@ -1,4 +1,6 @@
using System.ComponentModel;
using System;
using System.ComponentModel;
using System.Runtime.Versioning;
namespace ElectronNET.API.Entities
{
@@ -11,11 +13,13 @@ namespace ElectronNET.API.Entities
/// <see langword="true"/> to bring the opened application to the foreground. The default is <see langword="true"/>.
/// </summary>
[DefaultValue(true)]
[SupportedOSPlatform("macos")]
public bool Activate { get; set; } = true;
/// <summary>
/// The working directory.
/// </summary>
[SupportedOSPlatform("windows")]
public string WorkingDirectory { get; set; }
}
}

View File

@@ -20,14 +20,5 @@
/// The y.
/// </value>
public int Y { get; set; }
/// <summary>
/// Convert this <see cref="Point"/> to <see cref="System.Drawing.Point"/>.
/// </summary>
/// <param name="point">The point.</param>
public static implicit operator System.Drawing.Point(Point point)
{
return new System.Drawing.Point(point.X, point.Y);
}
}
}

View File

@@ -67,7 +67,7 @@ namespace ElectronNET.API.Entities
/// true for landscape, false for portrait.
/// </summary>
public bool Landscape { get; set; }
/// <summary>
/// The scale factor of the web page
/// </summary>
@@ -102,5 +102,6 @@ namespace ElectronNET.API.Entities
/// Dpi
/// </summary>
public PrintDpi Dpi { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
namespace ElectronNET.API.Entities
{
/// <summary>
///
/// </summary>
public class PrintToPDFOptions
{
/// <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>
/// Specify page size of the generated PDF. Can be A3, A4, A5, Legal, Letter,
/// Tabloid or an Object containing height and width in microns.
/// </summary>
public string PageSize { get; set; }
/// <summary>
/// Whether to print CSS backgrounds.
/// </summary>
public bool PrintBackground { get; set; }
/// <summary>
/// Whether to print selection only.
/// </summary>
public bool PrintSelectionOnly { get; set; }
/// <summary>
/// true for landscape, false for portrait.
/// </summary>
public bool Landscape { get; set; }
}
}

View File

@@ -14,7 +14,7 @@ namespace ElectronNET.API.Entities
/// Name
/// </summary>
public string Description { get; set; }
/// <summary>
/// Status
/// </summary>
@@ -24,5 +24,6 @@ namespace ElectronNET.API.Entities
/// Is default
/// </summary>
public bool IsDefault { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
namespace ElectronNET.API.Entities
{
/// <summary>
/// Process metrics information.
///
/// </summary>
public class ProcessMetric
{
@@ -21,9 +21,11 @@
public CPUUsage Cpu { get; set; }
/// <summary>
/// Creation time for this process in milliseconds since Unix epoch. Can exceed Int32 range and may contain fractional milliseconds.
/// Creation time for this process. The time is represented as number of milliseconds since epoch.
/// Since the <see cref="PId"/> can be reused after a process dies, it is useful to use both the <see cref="PId"/>
/// and the <see cref="CreationTime"/> to uniquely identify a process.
/// </summary>
public double CreationTime { get; set; }
public int CreationTime { get; set; }
/// <summary>
/// Memory information for the process.
@@ -36,20 +38,9 @@
public bool Sandboxed { get; set; }
/// <summary>
/// One of the following values:
/// One of the following values:
/// untrusted | low | medium | high | unknown
/// </summary>
public string IntegrityLevel { get; set; }
/// <summary>
/// The name of the process.
/// Examples for utility: Audio Service, Content Decryption Module Service, Network Service, Video Capture, etc.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The non-localized name of the process.
/// </summary>
public string ServiceName { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More