mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-02-05 13:54:47 +00:00
Compare commits
406 Commits
legacy/mai
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8009348941 | ||
|
|
b3b124bde1 | ||
|
|
21226e1ef0 | ||
|
|
7174118a3e | ||
|
|
092789a5ec | ||
|
|
bff3fffcbd | ||
|
|
456135a562 | ||
|
|
300f52510c | ||
|
|
d85a64f515 | ||
|
|
53698d1d44 | ||
|
|
04a224aa4f | ||
|
|
891da140b7 | ||
|
|
17f761d184 | ||
|
|
9f6489891e | ||
|
|
c8f1cdf59f | ||
|
|
6c95dfd476 | ||
|
|
b180fc2ea8 | ||
|
|
682a1c38ed | ||
|
|
809b0a6be7 | ||
|
|
ae3f755648 | ||
|
|
7e6760a428 | ||
|
|
29fdbb5315 | ||
|
|
36bba6a49f | ||
|
|
44a010e0ed | ||
|
|
25770db138 | ||
|
|
1c99ab02cc | ||
|
|
73c56e2450 | ||
|
|
30037fce69 | ||
|
|
69048d5565 | ||
|
|
d9c8e04b5c | ||
|
|
368ef412bb | ||
|
|
cb20fbad25 | ||
|
|
89cdf2f55b | ||
|
|
1c62c1f132 | ||
|
|
d3e3188681 | ||
|
|
4f95043309 | ||
|
|
13f1203ccc | ||
|
|
9d0378798b | ||
|
|
1d6ef7a250 | ||
|
|
2d6d4e2320 | ||
|
|
df8e269d5c | ||
|
|
bdfbcd5b77 | ||
|
|
19e785f53f | ||
|
|
0b453177b5 | ||
|
|
8ed7f27722 | ||
|
|
321b8cd9e5 | ||
|
|
b326f863d8 | ||
|
|
f148fe6a14 | ||
|
|
515d325731 | ||
|
|
f32a40fe17 | ||
|
|
c53a5a9163 | ||
|
|
8d4cdddc46 | ||
|
|
70e8f85123 | ||
|
|
5a7cbd972f | ||
|
|
33da428c45 | ||
|
|
f1b4766360 | ||
|
|
e070759645 | ||
|
|
49eaa5e129 | ||
|
|
b3f5a3c52b | ||
|
|
0d732ce99e | ||
|
|
218b99808b | ||
|
|
7f507a6d86 | ||
|
|
81b3793966 | ||
|
|
1baa5c6200 | ||
|
|
5f76804065 | ||
|
|
70ffebf39d | ||
|
|
0a54735f35 | ||
|
|
1ac371b3da | ||
|
|
e854451043 | ||
|
|
331c2f548c | ||
|
|
b00adcbd38 | ||
|
|
ed6d24dbb1 | ||
|
|
2c82206c62 | ||
|
|
d0eb0880b1 | ||
|
|
0321804128 | ||
|
|
f548ff08d4 | ||
|
|
bbc7c79d5a | ||
|
|
2389ae32bd | ||
|
|
42fecbdc98 | ||
|
|
95e02e2655 | ||
|
|
153625ba51 | ||
|
|
c97f914e7a | ||
|
|
d95b41fbae | ||
|
|
2b2b26e13b | ||
|
|
9bb2adca78 | ||
|
|
88d2daacb1 | ||
|
|
c90f003519 | ||
|
|
daa9f399e9 | ||
|
|
6246b44d68 | ||
|
|
347c1ef0e4 | ||
|
|
7c8eeef225 | ||
|
|
44a820e285 | ||
|
|
8ccc7bfdd0 | ||
|
|
cf185fd2fb | ||
|
|
4ee11aaeae | ||
|
|
f1063bbe98 | ||
|
|
7c39d28f81 | ||
|
|
e52bf69dee | ||
|
|
46d395ad12 | ||
|
|
c0e3a595c3 | ||
|
|
65db66b4e9 | ||
|
|
ce8a86baf5 | ||
|
|
7eaf84a021 | ||
|
|
90f5f5dbe2 | ||
|
|
e09ef35be4 | ||
|
|
dae521180f | ||
|
|
c81ed54fff | ||
|
|
276ce8f4dc | ||
|
|
20212cdca7 | ||
|
|
0acdc65271 | ||
|
|
c92a54fbda | ||
|
|
4de7760556 | ||
|
|
3821ca60ea | ||
|
|
59887cce5f | ||
|
|
77834d0f2e | ||
|
|
6761119241 | ||
|
|
41d9f0afc7 | ||
|
|
1d554fda60 | ||
|
|
2f4d37d823 | ||
|
|
1815951092 | ||
|
|
aa483ebaa4 | ||
|
|
9b4e0e4504 | ||
|
|
d05191d1e2 | ||
|
|
ef41329a91 | ||
|
|
edafa8ccdb | ||
|
|
55c035323b | ||
|
|
2e5c6200a6 | ||
|
|
be518a7a10 | ||
|
|
9e9558b837 | ||
|
|
5f6e4a9e9d | ||
|
|
b89c08ee96 | ||
|
|
8ff875435b | ||
|
|
bfad0cd45a | ||
|
|
91ed116cb1 | ||
|
|
54eac4b521 | ||
|
|
ac05ded844 | ||
|
|
5434b0ec8e | ||
|
|
20acd31f1a | ||
|
|
f53d071bd9 | ||
|
|
2cf3095450 | ||
|
|
0ec791da9d | ||
|
|
0580942a59 | ||
|
|
8e8d88c48f | ||
|
|
61476e3ca4 | ||
|
|
9488576d8f | ||
|
|
ff1b802838 | ||
|
|
c98ad58290 | ||
|
|
a30239e3a6 | ||
|
|
17f24749cd | ||
|
|
7558037b91 | ||
|
|
e4485fd483 | ||
|
|
1a964b405e | ||
|
|
dfcb2345f3 | ||
|
|
3f10d6b5dd | ||
|
|
90c3eb2c88 | ||
|
|
dbf76a1d6d | ||
|
|
8e7892ebd4 | ||
|
|
30b547b8d3 | ||
|
|
30b4d92291 | ||
|
|
6c9027faf3 | ||
|
|
c712027ea3 | ||
|
|
7889057022 | ||
|
|
68c50f1c1e | ||
|
|
1006355bb7 | ||
|
|
12c5391164 | ||
|
|
8ba24c0f2f | ||
|
|
bb7ae8d711 | ||
|
|
385dcfbf52 | ||
|
|
515430ff96 | ||
|
|
a6d67a4dfe | ||
|
|
946b2af81a | ||
|
|
1e483e9cc4 | ||
|
|
5305e17ba9 | ||
|
|
442084a3e5 | ||
|
|
cd205edabb | ||
|
|
10bf461b51 | ||
|
|
5b0ab76d38 | ||
|
|
349762bd5e | ||
|
|
0b49467186 | ||
|
|
6fa65aa149 | ||
|
|
816e9c0fe9 | ||
|
|
c81b0e537f | ||
|
|
b89e3caa17 | ||
|
|
e8c5de63c9 | ||
|
|
d7b9174853 | ||
|
|
5ba4ab24d5 | ||
|
|
c6ff957d9a | ||
|
|
c37f98dcd6 | ||
|
|
0188051d6c | ||
|
|
3eb8507985 | ||
|
|
546668a2c0 | ||
|
|
68feffba02 | ||
|
|
12d2fcb484 | ||
|
|
979cf72d4c | ||
|
|
14bf7fdcd8 | ||
|
|
f89f2e7591 | ||
|
|
9a0a494bc5 | ||
|
|
41a2b075c9 | ||
|
|
adc1e81743 | ||
|
|
d8062aae00 | ||
|
|
0522bc425b | ||
|
|
168eceac8c | ||
|
|
4736bc640c | ||
|
|
18b1317fc5 | ||
|
|
dfe04f14d0 | ||
|
|
9d6861ffcd | ||
|
|
d8b0d0443d | ||
|
|
71ced8db56 | ||
|
|
fc69598b09 | ||
|
|
60a278c41f | ||
|
|
9d25795b7a | ||
|
|
5b597cc12c | ||
|
|
707c0f5a7b | ||
|
|
bb59bc8365 | ||
|
|
423ea57af7 | ||
|
|
8dcc3721eb | ||
|
|
dc27511aa5 | ||
|
|
dd465baebf | ||
|
|
04210955a3 | ||
|
|
4129cc17a6 | ||
|
|
bc0f601dd8 | ||
|
|
95fd7aa665 | ||
|
|
402147b8ef | ||
|
|
ed7cc434ea | ||
|
|
c5fb5f62d9 | ||
|
|
84989cda25 | ||
|
|
84b3c59353 | ||
|
|
c1e7b84ec6 | ||
|
|
9bb7dcfa62 | ||
|
|
c0e711940d | ||
|
|
d03458094b | ||
|
|
14962e1983 | ||
|
|
d79b73e960 | ||
|
|
21ae89bc70 | ||
|
|
7927a95cb8 | ||
|
|
758e6a41e3 | ||
|
|
61421ddd66 | ||
|
|
98d085f112 | ||
|
|
cf0b12ed0a | ||
|
|
4c3065c64b | ||
|
|
2a6d2117e9 | ||
|
|
93f457dd0f | ||
|
|
6001a3c481 | ||
|
|
4671b9b32a | ||
|
|
de7f98136e | ||
|
|
87668f5606 | ||
|
|
ea688026d0 | ||
|
|
b6b9292478 | ||
|
|
408f83e401 | ||
|
|
689a002dc2 | ||
|
|
f919289628 | ||
|
|
2c544a83e9 | ||
|
|
2b393079ae | ||
|
|
79d3d3f0b1 | ||
|
|
688d6d83cc | ||
|
|
7bcc5c9878 | ||
|
|
0cfadb36f5 | ||
|
|
568c785412 | ||
|
|
2944e69b21 | ||
|
|
8df9eff3bc | ||
|
|
14f43f4574 | ||
|
|
d96eebd5ee | ||
|
|
23fac3263f | ||
|
|
935de8a1a5 | ||
|
|
c2ba55e333 | ||
|
|
be1887c930 | ||
|
|
1852802667 | ||
|
|
5bdabd94ba | ||
|
|
2bc2b4bb70 | ||
|
|
771b1109f7 | ||
|
|
56258d1be8 | ||
|
|
88766adaf6 | ||
|
|
341ebe2bb1 | ||
|
|
0c5cc3ba9d | ||
|
|
bb5779a941 | ||
|
|
0dd263e2b8 | ||
|
|
0a0e26a9dd | ||
|
|
7b812bfae7 | ||
|
|
82814d91d9 | ||
|
|
fcb589d58e | ||
|
|
c914bb8f14 | ||
|
|
bf3e149d43 | ||
|
|
6060e355bd | ||
|
|
868451408c | ||
|
|
bef7a42fbb | ||
|
|
50b49068d8 | ||
|
|
cf87904210 | ||
|
|
0b05b2f5a4 | ||
|
|
1ea4c1343d | ||
|
|
5d5e0b848c | ||
|
|
2d626ab319 | ||
|
|
2e051762dd | ||
|
|
96063bbe7d | ||
|
|
471289813a | ||
|
|
d0d214cd24 | ||
|
|
43ce20d60f | ||
|
|
40d6558613 | ||
|
|
ae12eb49ee | ||
|
|
2a26b46f91 | ||
|
|
78b59f62c9 | ||
|
|
667a1b290e | ||
|
|
c5d9ba0e43 | ||
|
|
f81424978e | ||
|
|
7fcb2f05bd | ||
|
|
69129a6f02 | ||
|
|
bcde1032af | ||
|
|
3a42c479dd | ||
|
|
c6c73a7c8a | ||
|
|
d1db928222 | ||
|
|
b06d20450b | ||
|
|
3811b7ea20 | ||
|
|
9275f2a765 | ||
|
|
feddf5f8f4 | ||
|
|
e4ce61c965 | ||
|
|
1e93d91e66 | ||
|
|
77efea50ed | ||
|
|
5ea368bb16 | ||
|
|
0dca0e90f9 | ||
|
|
c0c3aaebdc | ||
|
|
14722e1f63 | ||
|
|
d6e39fef24 | ||
|
|
74b80b3177 | ||
|
|
0f3f29eae3 | ||
|
|
f634dc45ed | ||
|
|
c6b9de2afa | ||
|
|
9a615ca7e0 | ||
|
|
f9601a6e3e | ||
|
|
8daf4d1498 | ||
|
|
c01ef407af | ||
|
|
dc019adb10 | ||
|
|
f7de17f1ee | ||
|
|
ca748384cf | ||
|
|
4c880cb627 | ||
|
|
e46ba98c8d | ||
|
|
4b9fe4656e | ||
|
|
fdb8be46b7 | ||
|
|
e361367a95 | ||
|
|
7ca40bcaec | ||
|
|
1864c21c10 | ||
|
|
0775b91dd4 | ||
|
|
f55dbc14c0 | ||
|
|
6472f34a75 | ||
|
|
91714f5807 | ||
|
|
6182320003 | ||
|
|
5125ee0109 | ||
|
|
21c17dc82b | ||
|
|
dbcd4ac940 | ||
|
|
286978c523 | ||
|
|
96ae77ceb4 | ||
|
|
a893ccd646 | ||
|
|
2edad2d329 | ||
|
|
7be796f77b | ||
|
|
19da7f47b1 | ||
|
|
d22532488e | ||
|
|
30558dea5f | ||
|
|
464eaca593 | ||
|
|
df3bd122df | ||
|
|
eabcc3a6b6 | ||
|
|
2b5435381f | ||
|
|
0d63383899 | ||
|
|
f31fe19652 | ||
|
|
0a80367e3e | ||
|
|
34761456ad | ||
|
|
e4e96bbcc4 | ||
|
|
1253df3d9a | ||
|
|
b8b634beb3 | ||
|
|
94dc82ec62 | ||
|
|
53ccf4d302 | ||
|
|
bf0bdc8386 | ||
|
|
73a3e331dc | ||
|
|
a15db713ad | ||
|
|
4be5cef3ef | ||
|
|
e2d03d6818 | ||
|
|
0dc8369fb3 | ||
|
|
77b7141513 | ||
|
|
dbf85c6f14 | ||
|
|
c67f117bc7 | ||
|
|
9746edb936 | ||
|
|
23f4d39a30 | ||
|
|
05ac4a1886 | ||
|
|
33ac4edbe3 | ||
|
|
e5f9bae64f | ||
|
|
437404d6cc | ||
|
|
1ae2f1de93 | ||
|
|
6bfd0c33af | ||
|
|
6311d55a75 | ||
|
|
7b522c1779 | ||
|
|
b1c08f5865 | ||
|
|
a3f19055b9 | ||
|
|
ef9a95d9e9 | ||
|
|
2367035acd | ||
|
|
3470a70572 | ||
|
|
1365918efd | ||
|
|
e909de54af | ||
|
|
a2514ed5bc | ||
|
|
b453278803 | ||
|
|
a244382383 | ||
|
|
a82e714ef8 | ||
|
|
b339485fdc | ||
|
|
551635867d | ||
|
|
941b8cf5c2 | ||
|
|
06b01f75da | ||
|
|
e4b1f6586e | ||
|
|
0657a274d4 | ||
|
|
e3acc79c4f | ||
|
|
73c1d1cd46 |
@@ -1,84 +0,0 @@
|
||||
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'
|
||||
137
.github/CONTRIBUTING.md
vendored
Normal file
137
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
# Contributing
|
||||
|
||||
## Project Scope
|
||||
|
||||
The Electron.NET project ultimately tries to provide a framework for developing cross-platform client applications on the basis of .NET and Electron. Anything that is related to this goal will be considered. The project aims to be as close to Electron with .NET as a basis as possible. If your contribution does not reflect that goal, the chances of accepting it are limited.
|
||||
|
||||
## Code License
|
||||
|
||||
This is an open source project falling under the [MIT License](../LICENSE). By using, distributing, or contributing to this project, you accept and agree that all code within the Electron.NET project and its libraries are licensed under MIT license.
|
||||
|
||||
## Becoming a Contributor
|
||||
|
||||
Usually appointing someone as a contributor follows this process:
|
||||
|
||||
1. An individual contributes actively via discussions (reporting bugs, giving feedback to existing or opening new issues) and / or pull requests
|
||||
2. The individual is either directly asked, invited or asks for contributor rights on the project
|
||||
3. The individual uses the contribution rights to sustain or increase the active contributions
|
||||
|
||||
Every contributor might have to sign the contributor's license agreement (CLA) to establish a legal trust between the project and its contributors.
|
||||
|
||||
## Working on Electron.NET
|
||||
|
||||
### Issue Discussion
|
||||
|
||||
Discussion of issues should be placed transparently in the issue tracker here on GitHub.
|
||||
|
||||
* [General issues, bugs, new features](https://github.com/ElectronNET/Electron.NET/issues)
|
||||
* [General discussions, help, exchange of ideas](https://github.com/ElectronNET/Electron.NET/discussions)
|
||||
|
||||
### Modifying the code
|
||||
|
||||
Electron.NET and its libraries uses features from the latest versions of C# (e.g., C# 10). You will therefore need a C# compiler that is up for the job.
|
||||
|
||||
1. Fork and clone the repo.
|
||||
2. First try to build the ElectronNET.Core library and see if you get the tests running.
|
||||
3. You will be required to resolve some dependencies via NuGet.
|
||||
|
||||
The build system of Electron.NET uses NUKE.
|
||||
|
||||
### Code Conventions
|
||||
|
||||
Most parts in the Electron.NET project are fairly straight forward. Among these are:
|
||||
|
||||
* Always use statement blocks for control statements, e.g., in a for-loop, if-condition, ...
|
||||
* You may use a simple (throw) statement in case of enforcing contracts on argument
|
||||
* Be explicit about modifiers (some files follow an older convention of the code base, but we settled on the explicit style)
|
||||
|
||||
### Development Workflow
|
||||
|
||||
1. If no issue already exists for the work you'll be doing, create one to document the problem(s) being solved and self-assign.
|
||||
2. Otherwise please let us know that you are working on the problem. Regular status updates (e.g. "still in progress", "no time anymore", "practically done", "pull request issued") are highly welcome.
|
||||
3. Create a new branch—please don't work in the `main` branch directly. It is reserved for releases. We recommend naming the branch to match the issue being addressed (`feature/#777` or `issue-777`).
|
||||
4. Add failing tests for the change you want to make. Tests are crucial and should be taken from W3C (or other specification).
|
||||
5. Fix stuff. Always go from edge case to edge case.
|
||||
6. All tests should pass now. Also your new implementation should not break existing tests.
|
||||
7. Update the documentation to reflect any changes. (or document such changes in the original issue)
|
||||
8. Push to your fork or push your issue-specific branch to the main repository, then submit a pull request against `develop`.
|
||||
|
||||
Just to illustrate the git workflow for Electron.NET a little bit more we've added the following graphs.
|
||||
|
||||
Initially, Electron.NET starts at the `main` branch. This branch should contain the latest stable (or released) version.
|
||||
|
||||
Here we now created a new branch called `develop`. This is the development branch.
|
||||
|
||||
Now active work is supposed to be done. Therefore a new branch should be created. Let's create one:
|
||||
|
||||
```sh
|
||||
git checkout -b feature/#777
|
||||
```
|
||||
|
||||
There may be many of these feature branches. Most of them are also pushed to the server for discussion or synchronization.
|
||||
|
||||
```sh
|
||||
git push -u origin feature/#777
|
||||
```
|
||||
|
||||
Now feature branches may be closed when they are done. Here we simply merge with the feature branch(es). For instance the following command takes the `feature/#777` branch from the server and merges it with the `develop` branch.
|
||||
|
||||
```sh
|
||||
git checkout develop
|
||||
git pull
|
||||
git pull origin feature/#777
|
||||
git push
|
||||
```
|
||||
|
||||
Finally, we may have all the features that are needed to release a new version of Electron.NET. Here we tag the release. For instance for the 1.0 release we use `v1.0`.
|
||||
|
||||
```sh
|
||||
git checkout main
|
||||
git merge develop
|
||||
git tag v1.0
|
||||
```
|
||||
|
||||
(The last part is automatically performed by our CI system. Don't tag manually.)
|
||||
|
||||
### Versioning
|
||||
|
||||
The rules of [semver](http://semver.org/) don't necessarily apply here, but we will try to stay quite close to them.
|
||||
|
||||
Prior to version 1.0.0 we use the following scheme:
|
||||
|
||||
1. MINOR versions for reaching a feature milestone potentially combined with dramatic API changes
|
||||
2. PATCH versions for refinements (e.g. performance improvements, bug fixes)
|
||||
|
||||
After releasing version 1.0.0 the scheme changes to become:
|
||||
|
||||
1. MAJOR versions at maintainers' discretion following significant changes to the codebase (e.g., API changes)
|
||||
2. MINOR versions for backwards-compatible enhancements (e.g., performance improvements)
|
||||
3. PATCH versions for backwards-compatible bug fixes (e.g., spec compliance bugs, support issues)
|
||||
|
||||
#### Code style
|
||||
|
||||
Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.** In general most of the [C# coding guidelines from Microsoft](https://msdn.microsoft.com/en-us/library/ff926074.aspx) are followed. This project prefers type inference with `var` to explicitly stating (redundant) information.
|
||||
|
||||
It is also important to keep a certain `async`-flow and to always use `ConfigureAwait(false)` in conjunction with an `await` expression.
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
We always try to remain backwards compatible beyond the currently supported versions of .NET.
|
||||
|
||||
For instance, in December 2025 there have been activity to remove .NET 6 support from the codebase. We rejected this. Key points:
|
||||
|
||||
1. We have absolutely no need to drop `.net6` support. It doesn't hurt us in any way.
|
||||
2. Many are still using `.net6`, including Electron.NET (non-Core) users. It doesn't make sense to force them to update two things at the same time (.NET + Electron.NET).
|
||||
3. We MUST NOT and NEVER update `Microsoft.Build.Utilities.Core`. This will make Electron.NET stop working on older Visual Studio and MSBuild versions. There's are also no reasons to update it in the first place.
|
||||
|
||||
It's important to note that the Microsoft label of "Out of support" on .NET has almost no practical meaning. We've rarely (if ever) seen any bugs fixed in the same .NET version which mattered. The bugs that all new .NET versions have are much worse than mature .NET versions which are declared as "out of support". Keep in mind that the LTS matters most for active development / ongoing supported projects. If, e.g., a TV has been released a decade ago it most likely won't be patched. Still, you might want to deploy applications to it, which then naturally would involve being based on "out of support" versions of the framework.
|
||||
|
||||
TL;DR: Unless there is a technical reason (e.g., a crucial new API not being available) we should not drop "out of support" .NET versions. At the time of writing (December 2025) the minimum supported .NET version remains at `.net6`.
|
||||
|
||||
## Timeline
|
||||
|
||||
**All of this information is related to ElectronNET.Core pre-v1!**
|
||||
|
||||
We pretty much release whenever we have something new (i.e., do fixes such as a 0.1.1, or add new features, such as a 0.2.0) quite quickly.
|
||||
|
||||
We will go for a 1.0.0 release of this as early as ~mid of January 2026 (unless we find some critical things or want to extend the beta phase for ElectronNET.Core). This should be sufficient time to get some user input and have enough experience to call it stable.
|
||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,6 +1,6 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
github: [GregorBiswanger, FlorianRappl]
|
||||
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
Normal file
BIN
.github/WikiLinks.exe
vendored
Normal file
Binary file not shown.
43
.github/workflows/Build and Publish.yml
vendored
Normal file
43
.github/workflows/Build and Publish.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Build and Publish
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
|
||||
|
||||
concurrency:
|
||||
group: build-publish-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
Integration-Tests:
|
||||
uses: ./.github/workflows/integration-tests.yml
|
||||
name: '1'
|
||||
|
||||
Publish:
|
||||
needs: [Integration-Tests]
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
name: '2 / Publish'
|
||||
|
||||
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
|
||||
}
|
||||
39
.github/workflows/PR Validation.yml
vendored
Normal file
39
.github/workflows/PR Validation.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: PR Validation
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
concurrency:
|
||||
group: pr-validation-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
Whitespace-Check:
|
||||
uses: ./.github/workflows/trailing-whitespace-check.yml
|
||||
secrets: inherit
|
||||
name: '1'
|
||||
|
||||
Tests:
|
||||
needs: Whitespace-Check
|
||||
uses: ./.github/workflows/integration-tests.yml
|
||||
secrets: inherit
|
||||
name: '2'
|
||||
|
||||
build:
|
||||
needs: [Whitespace-Check, Tests]
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
name: '3 / Build'
|
||||
|
||||
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.ps1
|
||||
220
.github/workflows/integration-tests.yml
vendored
Normal file
220
.github/workflows/integration-tests.yml
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: integration-tests-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: ${{ matrix.os }} API-${{ matrix.electronVersion }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-24.04, windows-2022, windows-2025, macos-14, macos-15-intel, macos-26]
|
||||
electronVersion: ['30.4.0', '38.2.2']
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
rid: linux-x64
|
||||
- os: ubuntu-24.04
|
||||
rid: linux-x64
|
||||
- os: windows-2022
|
||||
rid: win-x64
|
||||
- os: windows-2025
|
||||
rid: win-x64
|
||||
- os: macos-14
|
||||
rid: osx-arm64
|
||||
- os: macos-15-intel
|
||||
rid: osx-x64
|
||||
- os: macos-26
|
||||
rid: osx-arm64
|
||||
|
||||
env:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
DOTNET_NOLOGO: 1
|
||||
CI: true
|
||||
ELECTRON_ENABLE_LOGGING: 1
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Random delay (0-20 seconds)
|
||||
shell: bash
|
||||
run: |
|
||||
DELAY=$((RANDOM % 21))
|
||||
echo "Waiting for $DELAY seconds..."
|
||||
sleep $DELAY
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} -p:ElectronVersion=${{ matrix.electronVersion }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --no-restore -c Release -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} -p:ElectronVersion=${{ matrix.electronVersion }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
|
||||
|
||||
- name: Install Linux GUI dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
set -e
|
||||
sudo apt-get update
|
||||
. /etc/os-release
|
||||
if [ "$VERSION_ID" = "24.04" ]; then ALSA_PKG=libasound2t64; else ALSA_PKG=libasound2; fi
|
||||
echo "Using ALSA package: $ALSA_PKG"
|
||||
sudo apt-get install -y xvfb \
|
||||
libgtk-3-0 libnss3 libgdk-pixbuf-2.0-0 libdrm2 libgbm1 libxss1 libxtst6 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libx11-xcb1 "$ALSA_PKG"
|
||||
|
||||
- name: Run tests (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
mkdir -p test-results
|
||||
xvfb-run -a dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj \
|
||||
-c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} -p:ElectronVersion=${{ matrix.electronVersion }} \
|
||||
--logger "trx;LogFileName=${{ matrix.os }}-electron-${{ matrix.electronVersion }}.trx" \
|
||||
--logger "console;verbosity=detailed" \
|
||||
--results-directory test-results
|
||||
|
||||
- name: Run tests (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force -Path test-results | Out-Null
|
||||
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} -p:ElectronVersion=${{ matrix.electronVersion }} --logger "trx;LogFileName=${{ matrix.os }}-electron-${{ matrix.electronVersion }}.trx" --logger "console;verbosity=detailed" --results-directory test-results
|
||||
|
||||
- name: Run tests (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
mkdir -p test-results
|
||||
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} -p:ElectronVersion=${{ matrix.electronVersion }} --logger "trx;LogFileName=${{ matrix.os }}-electron-${{ matrix.electronVersion }}.trx" --logger "console;verbosity=detailed" --results-directory test-results
|
||||
|
||||
- name: Upload raw test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}-electron-${{ matrix.electronVersion }}
|
||||
path: test-results/*.trx
|
||||
retention-days: 7
|
||||
|
||||
summary:
|
||||
name: Test Results
|
||||
runs-on: ubuntu-24.04
|
||||
if: always()
|
||||
needs: [tests]
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
checks: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Download all test results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: test-results
|
||||
|
||||
- name: Setup .NET (for CTRF conversion)
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: Install CTRF TRX→CTRF converter (dotnet tool)
|
||||
run: |
|
||||
dotnet new tool-manifest
|
||||
dotnet tool install DotnetCtrfJsonReporter --local
|
||||
|
||||
- name: Convert TRX → CTRF and clean names (filePath=OS|Electron X.Y.Z)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p ctrf
|
||||
shopt -s globstar nullglob
|
||||
conv=0
|
||||
for trx in test-results/**/*.trx; do
|
||||
base="$(basename "$trx" .trx)" # e.g. ubuntu-22.04-electron-30.4.0
|
||||
os="${base%%-electron-*}"
|
||||
electron="${base#*-electron-}"
|
||||
label="$os|Electron $electron"
|
||||
outdir="ctrf/${label}"
|
||||
mkdir -p "$outdir"
|
||||
out="${outdir}/ctrf-report.json"
|
||||
|
||||
dotnet tool run DotnetCtrfJsonReporter -p "$trx" -d "$outdir" -f "ctrf-report.json"
|
||||
|
||||
jq --arg fp "$label" '.results.tests |= map(.filePath = $fp)' "$out" > "${out}.tmp" && mv "${out}.tmp" "$out"
|
||||
|
||||
echo "Converted & normalized $trx -> $out"
|
||||
conv=$((conv+1))
|
||||
done
|
||||
echo "Processed $conv TRX file(s)"
|
||||
|
||||
- name: Publish Test Report
|
||||
if: always()
|
||||
uses: ctrf-io/github-test-reporter@v1
|
||||
with:
|
||||
report-path: 'ctrf/**/*.json'
|
||||
summary: true
|
||||
pull-request: false
|
||||
status-check: false
|
||||
status-check-name: 'Integration Tests'
|
||||
use-suite-name: true
|
||||
update-comment: true
|
||||
always-group-by: true
|
||||
overwrite-comment: true
|
||||
exit-on-fail: true
|
||||
group-by: 'suite'
|
||||
upload-artifact: true
|
||||
fetch-previous-results: true
|
||||
summary-report: false
|
||||
summary-delta-report: true
|
||||
github-report: true
|
||||
test-report: false
|
||||
test-list-report: false
|
||||
failed-report: true
|
||||
failed-folded-report: false
|
||||
skipped-report: true
|
||||
suite-folded-report: true
|
||||
suite-list-report: false
|
||||
file-report: true
|
||||
previous-results-report: true
|
||||
insights-report: true
|
||||
flaky-report: true
|
||||
flaky-rate-report: true
|
||||
fail-rate-report: false
|
||||
slowest-report: false
|
||||
report-order: 'summary-delta-report,failed-report,skipped-report,suite-folded-report,file-report,previous-results-report,github-report'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- name: Save PR Number
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Write PR Number to File
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "$PR_NUMBER" > pr_number.txt
|
||||
shell: bash
|
||||
|
||||
- name: Upload PR Number Artifact
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr_number
|
||||
path: pr_number.txt
|
||||
|
||||
- name: Summary
|
||||
run: echo "All matrix test jobs completed."
|
||||
81
.github/workflows/pr-comment.yml
vendored
Normal file
81
.github/workflows/pr-comment.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
name: Create PR Comments
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [ "PR Validation" ]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
pr-comment:
|
||||
name: Post Test Result as PR comment
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion != 'cancelled'
|
||||
|
||||
steps:
|
||||
- name: Download CTRF artifact
|
||||
uses: dawidd6/action-download-artifact@v8
|
||||
with:
|
||||
github_token: ${{ github.token }}
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: ctrf-report
|
||||
path: ctrf
|
||||
|
||||
- name: Download PR Number Artifact
|
||||
uses: dawidd6/action-download-artifact@v8
|
||||
with:
|
||||
github_token: ${{ github.token }}
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: pr_number
|
||||
path: pr_number
|
||||
|
||||
- name: Read PR Number
|
||||
run: |
|
||||
set -Eeuo pipefail
|
||||
FILE='pr_number/pr_number.txt'
|
||||
|
||||
# Ensure file exists
|
||||
if [ ! -f "$FILE" ] || [ -L "$FILE" ]; then
|
||||
echo "Error: $FILE is missing or is not a regular file." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Chec file size
|
||||
if [ "$(wc -c < "$FILE" | tr -d ' ')" -gt 200 ]; then
|
||||
echo "Error: $FILE is too large." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Read first line
|
||||
PR_NUMBER=""
|
||||
IFS= read -r PR_NUMBER < "$FILE" || true
|
||||
|
||||
# Validate whether it's a number
|
||||
if ! [[ "$PR_NUMBER" =~ ^[0-9]{1,10}$ ]]; then
|
||||
echo "Error: PR_NUMBER is not a valid integer on the first line." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'PR_NUMBER=%s\n' "$PR_NUMBER" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Post PR Comment
|
||||
uses: ctrf-io/github-test-reporter@v1
|
||||
with:
|
||||
report-path: 'ctrf/**/*.json'
|
||||
issue: ${{ env.PR_NUMBER }}
|
||||
|
||||
summary: true
|
||||
pull-request: true
|
||||
use-suite-name: true
|
||||
update-comment: true
|
||||
always-group-by: true
|
||||
overwrite-comment: true
|
||||
upload-artifact: false
|
||||
|
||||
pull-request-report: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
59
.github/workflows/publish-wiki.yml
vendored
Normal file
59
.github/workflows/publish-wiki.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
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'
|
||||
49
.github/workflows/retry-test-jobs.yml
vendored
Normal file
49
.github/workflows/retry-test-jobs.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Tests auto-rerun
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [ "PR Validation", "Build and Publish" ]
|
||||
types: [ completed ]
|
||||
|
||||
jobs:
|
||||
rerun-failed-matrix-jobs-once:
|
||||
if: >
|
||||
${{
|
||||
github.event.workflow_run.conclusion == 'failure' &&
|
||||
github.event.workflow_run.run_attempt == 1
|
||||
}}
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Decide whether to rerun (only if matrix jobs failed)
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
run: |
|
||||
echo "Inspecting jobs of workflow run $RUN_ID in $REPO"
|
||||
|
||||
jobs_json="$(gh api -R $REPO repos/$REPO/actions/runs/$RUN_ID/jobs)"
|
||||
|
||||
echo "Jobs and conclusions:"
|
||||
echo "$jobs_json" | jq '.jobs[] | {name: .name, conclusion: .conclusion}'
|
||||
|
||||
failed_matrix_jobs=$(echo "$jobs_json" | jq -r '
|
||||
[ .jobs[]
|
||||
| select(.conclusion == "failure"
|
||||
and (.name | contains(" API-")))
|
||||
]
|
||||
| length // 0
|
||||
')
|
||||
failed_matrix_jobs=${failed_matrix_jobs:-0}
|
||||
|
||||
if [ "${failed_matrix_jobs}" -gt 0 ]; then
|
||||
echo "Detected failing Integration Tests jobs – re-running failed jobs for this run."
|
||||
gh run rerun -R "$REPO" "$RUN_ID" --failed
|
||||
else
|
||||
echo "Only non-matrix jobs (like Test Results) failed – not auto-rerunning."
|
||||
fi
|
||||
84
.github/workflows/trailing-whitespace-check.yml
vendored
Normal file
84
.github/workflows/trailing-whitespace-check.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: Whitespace Check
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
check-whitespace:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check for trailing whitespace
|
||||
run: |
|
||||
echo "Checking for trailing whitespace in changed files..."
|
||||
|
||||
# Get the base branch
|
||||
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
|
||||
|
||||
# Get list of changed files (excluding deleted files)
|
||||
CHANGED_FILES=$(git diff --name-only --diff-filter=d "$BASE_SHA" "$HEAD_SHA")
|
||||
|
||||
if [ -z "$CHANGED_FILES" ]; then
|
||||
echo "No files to check."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# File patterns to check (text files)
|
||||
PATTERNS="\.cs$|\.csproj$|\.sln$|\.ts$|\.html$|\.css$|\.scss$"
|
||||
|
||||
# Directories and file patterns to exclude
|
||||
EXCLUDE_PATTERNS="(^|\/)(\.|node_modules|bin|obj|artifacts|packages|\.vs|\.nuke\/temp)($|\/)"
|
||||
|
||||
ERRORS_FOUND=0
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
while IFS= read -r file; do
|
||||
# Skip if file doesn't exist (shouldn't happen with --diff-filter=d, but just in case)
|
||||
if [ ! -f "$file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if file matches patterns to check
|
||||
if ! echo "$file" | grep -qE "$PATTERNS"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if file should be excluded
|
||||
if echo "$file" | grep -qE "$EXCLUDE_PATTERNS"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Find trailing whitespace lines, excluding XML doc placeholder lines that are exactly "/// " (one space)
|
||||
MATCHES=$(grep -n '[[:space:]]$' "$file" | grep -vE '^[0-9]+:[[:space:]]*/// $' || true)
|
||||
|
||||
if [ -n "$MATCHES" ]; then
|
||||
echo "❌ Trailing whitespace found in: $file"
|
||||
echo "$MATCHES" | head -10
|
||||
TOTAL=$(echo "$MATCHES" | wc -l)
|
||||
if [ "$TOTAL" -gt 10 ]; then
|
||||
echo " ... and $(($TOTAL - 10)) more lines"
|
||||
fi
|
||||
echo "1" >> "$TEMP_FILE"
|
||||
fi
|
||||
done <<< "$CHANGED_FILES"
|
||||
|
||||
ERRORS_FOUND=$(wc -l < "$TEMP_FILE" 2>/dev/null || echo "0")
|
||||
rm -f "$TEMP_FILE"
|
||||
|
||||
if [ "$ERRORS_FOUND" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "❌ Found trailing whitespace in $ERRORS_FOUND file(s)."
|
||||
echo "Please remove trailing whitespace from the files listed above."
|
||||
exit 1
|
||||
else
|
||||
echo "✅ No trailing whitespace found in changed files."
|
||||
exit 0
|
||||
fi
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -44,7 +44,7 @@ dlldata.c
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
!/artifacts/readme.md
|
||||
!/artifacts/.gitkeep
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
@@ -263,3 +263,7 @@ __pycache__/
|
||||
|
||||
# Mac Only settings file
|
||||
.DS_Store
|
||||
|
||||
# Nuke build tool
|
||||
.nuke/temp
|
||||
/publish.cmd
|
||||
|
||||
137
.nuke/build.schema.json
Normal file
137
.nuke/build.schema.json
Normal file
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"$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"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
.nuke/parameters.json
Normal file
4
.nuke/parameters.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "./build.schema.json",
|
||||
"Solution": "src/ElectronNET.Lean.sln"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
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
4
.vscode/launch.json
vendored
@@ -10,9 +10,9 @@
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceRoot}/ElectronNET.CLI/bin/Debug/netcoreapp2.0/dotnet-electronize.dll",
|
||||
"program": "${workspaceRoot}/src/ElectronNET.CLI/bin/Debug/net8.0/dotnet-electronize.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}/ElectronNET.CLI",
|
||||
"cwd": "${workspaceRoot}/src/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
37
.vscode/tasks.json
vendored
@@ -1,21 +1,18 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
16
.vscode/tasks.json.old
vendored
16
.vscode/tasks.json.old
vendored
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"command": "dotnet",
|
||||
"isShellCommand": true,
|
||||
"args": [],
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "build",
|
||||
"args": [
|
||||
"${workspaceRoot}/ElectronNET.CLI/ElectronNET.CLI.csproj"
|
||||
],
|
||||
"isBuildCommand": true,
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
467
Changelog.md
467
Changelog.md
@@ -1,374 +1,139 @@
|
||||
# Not released
|
||||
|
||||
# 18.6.1
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* 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.API:
|
||||
|
||||
* 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)
|
||||
|
||||
# Released
|
||||
|
||||
# 13.5.1
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* 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)
|
||||
|
||||
# 11.5.1
|
||||
|
||||
ElectronNET.CLI:
|
||||
|
||||
* 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)
|
||||
|
||||
ElectronNET.API:
|
||||
|
||||
* 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)
|
||||
|
||||
Example for the Dock Menu
|
||||
|
||||
`Electron.Dock.SetMenu(new [] {
|
||||
new MenuItem {
|
||||
Label = "Dock Menu Item",
|
||||
Click = () => {
|
||||
// do something
|
||||
}
|
||||
},
|
||||
});`
|
||||
|
||||
Example for consuming the activate event (MacOs only)
|
||||
|
||||
`Electron.App.On("activate", obj => {
|
||||
var hasWindows = (bool)obj;
|
||||
// do something
|
||||
});`
|
||||
|
||||
* 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) ❤
|
||||
# 0.4.1
|
||||
|
||||
# 8.31.2
|
||||
## ElectronNET.Core
|
||||
|
||||
- Fixed handling of `Center` property for windows (#1001)
|
||||
- Added missing methods on `Cookies` (#1000)
|
||||
|
||||
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)
|
||||
# 0.4.0
|
||||
|
||||
ElectronNET.API:
|
||||
## ElectronNET.Core
|
||||
|
||||
* 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)
|
||||
- Fixed ElectronSingleInstance handling (#996) @softworkz
|
||||
- Fixed `PackageId` handling (#993) @softworkz
|
||||
- Added cross-platform npm restore and check mismatch on publish (#988) @softworkz
|
||||
|
||||
# 0.3.1
|
||||
|
||||
# 8.31.1
|
||||
## ElectronNET.Core
|
||||
|
||||
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`
|
||||
- Fixed issue transforming the project ID (#989, #990) @softworkz
|
||||
|
||||
# 0.3.0
|
||||
|
||||
ElectronNET.API:
|
||||
## ElectronNET.Core
|
||||
|
||||
* 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)
|
||||
- Updated infrastructure (#937, #939) @softworkz
|
||||
- Updated all model classes to Electron API 39.2 (#949) @softworkz
|
||||
- Fixed output path for `electron-builder` (#942) @softworkz
|
||||
- Fixed floating point display resolution (#944) @softworkz
|
||||
- Fixed error in case of missing electron-host-hook (#978)
|
||||
- Fixed previous API break using exposed `JsonElement` objects (#938) @softworkz
|
||||
- Fixed and improved several test cases (#962) @softworkz
|
||||
- Fixed startup of Electron.NET from VS Code Debug Adapter (#952)
|
||||
- Fixed the `BrowserWindowOptions` (#945) @softworkz
|
||||
- Fixed example for `AutoMenuHide` to reflect platform capabilities (#982) @markatosi
|
||||
- Added several migration checks for publishing (#966) @softworkz
|
||||
- Added more test runners for E2E tests (#950, #951) @agracio
|
||||
- Added dynamic updates for tray menu (#973) @davidroth
|
||||
- Added matrix tests with 6 runners and 2 electron version (#948) @softworkz
|
||||
- Added additional APIs for WebContents (#958) @agracio
|
||||
- Added documentation for MacOS package publish (#983) @markatosi
|
||||
- Added sample application for `ElectronHostHook` (#967) @adityashirsatrao007
|
||||
|
||||
# 7.30.2
|
||||
# 0.2.0
|
||||
|
||||
ElectronNET.CLI:
|
||||
## ElectronNET.Core
|
||||
|
||||
* 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`.
|
||||
- Updated dependencies (#930) @softworkz
|
||||
- Updated integration tests (#931) @softworkz
|
||||
- Updated `ElectronNET.Host` (#935) @softworkz
|
||||
- Removed transition period specific build configuration (#928) @softworkz
|
||||
- Added `IsRunningBlazor` option to `BrowserWindowOptions` (#926)
|
||||
- Added platform support attributes (#929) @softworkz
|
||||
|
||||
* 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))
|
||||
# 0.1.0
|
||||
|
||||
ElectronNET.API:
|
||||
## ElectronNET.Core
|
||||
|
||||
* 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))
|
||||
- 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
|
||||
|
||||
Thank you for donation [robertmclaws](https://github.com/robertmclaws) ❤
|
||||
# 0.0.18
|
||||
|
||||
# 5.30.1
|
||||
## ElectronNET.Core
|
||||
|
||||
ElectronNET.CLI:
|
||||
### Highlights
|
||||
|
||||
* Move to .NET Core 3.0
|
||||
* Use npm npx instead of global installations (thanks [jimbuck](https://github.com/jimbuck))
|
||||
- **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
|
||||
|
||||
ElectronNET.API:
|
||||
### Build System & Project Structure
|
||||
|
||||
* Move to .NET Core 3.0
|
||||
* New Feature: Add BrowserWindow.RemoveMenu() (thanks [hack2root](https://github.com/hack2root))
|
||||
- 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
|
||||
|
||||
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
|
||||
### Development Experience
|
||||
|
||||
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
|
||||
- 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)
|
||||
|
||||
### Debugging & Runtime
|
||||
|
||||
- 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
|
||||
|
||||
### Technical Improvements
|
||||
|
||||
- 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
|
||||
|
||||
### Package & Distribution
|
||||
|
||||
- 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
|
||||
|
||||
### Migration & Compatibility
|
||||
|
||||
- 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
|
||||
|
||||
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.
|
||||
|
||||
@@ -1,474 +0,0 @@
|
||||
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.
|
||||
/// Doesn’t 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,551 +0,0 @@
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,150 +0,0 @@
|
||||
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
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
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 system’s notification area.
|
||||
/// </summary>
|
||||
public static Tray Tray { get { return Tray.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Detect keyboard events when the application does not have keyboard focus.
|
||||
/// </summary>
|
||||
public static GlobalShortcut GlobalShortcut { get { return GlobalShortcut.Instance; } }
|
||||
|
||||
/// <summary>
|
||||
/// Manage files and URLs using their default applications.
|
||||
/// </summary>
|
||||
public static Shell Shell { get { return Shell.Instance; } }
|
||||
|
||||
/// <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; } }
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<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>
|
||||
@@ -1,33 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AddRepresentationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the width
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height
|
||||
/// </summary>
|
||||
public int? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the buffer
|
||||
/// </summary>
|
||||
public byte[] Buffer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dataURL
|
||||
/// </summary>
|
||||
public string DataUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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};
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CPUUsage
|
||||
{
|
||||
/// <summary>
|
||||
/// Percentage of CPU used since the last call to getCPUUsage. First call returns 0.
|
||||
/// </summary>
|
||||
public int PercentCPUUsage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of average idle cpu wakeups per second since the last call to
|
||||
/// getCPUUsage.First call returns 0.
|
||||
/// </summary>
|
||||
public int IdleWakeupsPerSecond { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ClearStorageDataOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Should follow window.location.origin’s representation scheme://host:port.
|
||||
/// </summary>
|
||||
public string Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The types of storages to clear, can contain: appcache, cookies, filesystem,
|
||||
/// indexdb, localstorage, shadercache, websql, serviceworkers, cachestorage.
|
||||
/// </summary>
|
||||
public string[] Storages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The types of quotas to clear, can contain: temporary, persistent, syncable.
|
||||
/// </summary>
|
||||
public string[] Quotas { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Cookie {
|
||||
/// <summary>
|
||||
/// The name of the cookie.
|
||||
/// </summary>
|
||||
public string Name { get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// The value of the cookie.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains.
|
||||
/// </summary>
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is a host-only cookie; this will only be true if no domain was passed.
|
||||
/// </summary>
|
||||
public bool HostOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure.
|
||||
/// </summary>
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as HTTP only.
|
||||
/// </summary>
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is a session cookie or a persistent cookie with an expiration date.
|
||||
/// </summary>
|
||||
public bool Session { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies.
|
||||
/// </summary>
|
||||
public long ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The cause of the change
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum CookieChangedCause
|
||||
{
|
||||
/// <summary>
|
||||
///The cookie was changed directly by a consumer's action.
|
||||
/// </summary>
|
||||
[JsonProperty("explicit")]
|
||||
@explicit,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically removed due to an insert operation that overwrote it.
|
||||
/// </summary>
|
||||
overwrite,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically removed as it expired.
|
||||
/// </summary>
|
||||
expired,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was automatically evicted during garbage collection.
|
||||
/// </summary>
|
||||
evicted,
|
||||
|
||||
/// <summary>
|
||||
/// The cookie was overwritten with an already-expired expiration date.
|
||||
/// </summary>
|
||||
[JsonProperty("expired_overwrite")]
|
||||
expiredOverwrite
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CookieDetails {
|
||||
/// <summary>
|
||||
/// The URL to associate the cookie with. The callback will be rejected if the URL is invalid.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The name of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The value of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as HTTP only. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch.
|
||||
/// If omitted then the cookie becomes a session cookie and will not be retained between sessions.
|
||||
/// </summary>
|
||||
[DefaultValue(0)]
|
||||
public long ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class CookieRemovedResponse
|
||||
{
|
||||
public Cookie cookie {get;set;}
|
||||
|
||||
public CookieChangedCause cause { get; set; }
|
||||
public bool removed { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
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};
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
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};
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for creating a new <see cref="NativeImage"/>
|
||||
/// </summary>
|
||||
public class CreateOptions
|
||||
{
|
||||
/// <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;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DisplayBalloonOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the icon.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The icon.
|
||||
/// </value>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The title.
|
||||
/// </value>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// </value>
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum FileIconSize
|
||||
{
|
||||
/// <summary>
|
||||
/// The small
|
||||
/// </summary>
|
||||
small,
|
||||
|
||||
/// <summary>
|
||||
/// The normal
|
||||
/// </summary>
|
||||
normal,
|
||||
|
||||
/// <summary>
|
||||
/// The large
|
||||
/// </summary>
|
||||
large
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class GPUFeatureStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Canvas.
|
||||
/// </summary>
|
||||
[JsonProperty("2d_canvas")]
|
||||
public string Canvas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_3d")]
|
||||
public string Flash3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash Stage3D.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_stage3d")]
|
||||
public string FlashStage3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash Stage3D Baseline profile.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_stage3d_baseline")]
|
||||
public string FlashStage3dBaseline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compositing.
|
||||
/// </summary>
|
||||
[JsonProperty("gpu_compositing")]
|
||||
public string GpuCompositing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Multiple Raster Threads.
|
||||
/// </summary>
|
||||
[JsonProperty("multiple_raster_threads")]
|
||||
public string MultipleRasterThreads { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Native GpuMemoryBuffers.
|
||||
/// </summary>
|
||||
[JsonProperty("native_gpu_memory_buffers")]
|
||||
public string NativeGpuMemoryBuffers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rasterization.
|
||||
/// </summary>
|
||||
public string Rasterization { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Video Decode.
|
||||
/// </summary>
|
||||
[JsonProperty("video_decode")]
|
||||
public string VideoDecode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Video Encode.
|
||||
/// </summary>
|
||||
[JsonProperty("video_encode")]
|
||||
public string VideoEncode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VPx Video Decode.
|
||||
/// </summary>
|
||||
[JsonProperty("vpx_decode")]
|
||||
public string VpxDecode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// WebGL.
|
||||
/// </summary>
|
||||
public string Webgl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// WebGL2.
|
||||
/// </summary>
|
||||
public string Webgl2 { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to use Electrons PostData Object
|
||||
/// </summary>
|
||||
public interface IPostData
|
||||
{
|
||||
/// <summary>
|
||||
/// One of the following:
|
||||
/// rawData - <see cref="UploadRawData"/> The data is available as a Buffer, in the rawData field.
|
||||
/// file - <see cref="UploadFile"/> The object represents a file. The filePath, offset, length and modificationTime fields will be used to describe the file.
|
||||
/// blob - <see cref="Blob"/> The object represents a Blob. The blobUUID field will be used to describe the Blob.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ImageOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scale factor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = NativeImage.DefaultScaleFactor;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class JumpListCategory
|
||||
{
|
||||
/// <summary>
|
||||
/// Must be set if type is custom, otherwise it should be omitted.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of objects if type is tasks or custom, otherwise it should be omitted.
|
||||
/// </summary>
|
||||
public JumpListItem[] Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// One of the following: "tasks" | "frequent" | "recent" | "custom"
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public JumpListCategoryType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class JumpListItem
|
||||
{
|
||||
/// <summary>
|
||||
/// The command line arguments when program is executed. Should only be set if type is task.
|
||||
/// </summary>
|
||||
public string Args { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Description of the task (displayed in a tooltip). Should only be set if type is task.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the icon in the resource file. If a resource file contains multiple
|
||||
/// icons this value can be used to specify the zero-based index of the icon that
|
||||
/// should be displayed for this task.If a resource file contains only one icon,
|
||||
/// this property should be set to zero.
|
||||
/// </summary>
|
||||
public int IconIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The absolute path to an icon to be displayed in a Jump List, which can be an
|
||||
/// arbitrary resource file that contains an icon(e.g. .ico, .exe, .dll). You can
|
||||
/// usually specify process.execPath to show the program icon.
|
||||
/// </summary>
|
||||
public string IconPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path of the file to open, should only be set if type is file.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path of the program to execute, usually you should specify process.execPath
|
||||
/// which opens the current program.Should only be set if type is task.
|
||||
/// </summary>
|
||||
public string Program { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The text to be displayed for the item in the Jump List. Should only be set if type is task.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// One of the following: "task" | "separator" | "file"
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public JumpListItemType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class JumpListSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum number of items that will be shown in the Jump List (for a more detailed description of this value see the
|
||||
/// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85).aspx">MSDN</see> docs).
|
||||
/// </summary>
|
||||
public int MinItems { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Array of JumpListItem objects that correspond to items that the user has explicitly removed from custom categories
|
||||
/// in the Jump List. These items must not be re-added to the Jump List in the next call to <see cref="App.SetJumpList"/>, Windows will
|
||||
/// not display any custom category that contains any of the removed items.
|
||||
/// </summary>
|
||||
public JumpListItem[] RemovedItems { get; set; } = Array.Empty<JumpListItem>();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginItemSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the app is set to open at login.
|
||||
/// </summary>
|
||||
public bool OpenAtLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the app is set to open as hidden at login. This setting is not available
|
||||
/// on <see href="https://www.electronjs.org/docs/tutorial/mac-app-store-submission-guide">MAS builds</see>.
|
||||
/// </summary>
|
||||
public bool OpenAsHidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the app was opened at login automatically. This setting is not available
|
||||
/// on <see href="https://www.electronjs.org/docs/tutorial/mac-app-store-submission-guide">MAS builds</see>.
|
||||
/// </summary>
|
||||
public bool WasOpenedAtLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the app was opened as a hidden login item. This indicates that the app should not
|
||||
/// open any windows at startup. This setting is not available on
|
||||
/// <see href="https://www.electronjs.org/docs/tutorial/mac-app-store-submission-guide">MAS builds</see>.
|
||||
/// </summary>
|
||||
public bool WasOpenedAsHidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the app was opened as a login item that should restore the state from the previous
|
||||
/// session. This indicates that the app should restore the windows that were open the last time the app was closed.
|
||||
/// This setting is not available on <see href="https://www.electronjs.org/docs/tutorial/mac-app-store-submission-guide">MAS builds</see>.
|
||||
/// </summary>
|
||||
public bool RestoreState { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginItemSettingsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The executable path to compare against. Defaults to process.execPath.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The command-line arguments to compare against. Defaults to an empty array.
|
||||
/// </summary>
|
||||
public string[] Args { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// <see langword="true"/> to open the app at login, <see langword="false"/> to remove the app as a login item.
|
||||
/// Defaults to <see langword="false"/>.
|
||||
/// </summary>
|
||||
public bool OpenAtLogin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> to open the app as hidden. Defaults to <see langword="false"/>. The user can edit this
|
||||
/// setting from the System Preferences so app.getLoginItemSettings().wasOpenedAsHidden should be checked when the app is
|
||||
/// opened to know the current value. This setting is not available on <see href="https://www.electronjs.org/docs/tutorial/mac-app-store-submission-guide">MAS builds</see>.
|
||||
/// </summary>
|
||||
public bool OpenAsHidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The executable to launch at login. Defaults to process.execPath.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The command-line arguments to pass to the executable. Defaults to an empty
|
||||
/// array.Take care to wrap paths in quotes.
|
||||
/// </summary>
|
||||
public string[] Args { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MemoryInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The amount of memory currently pinned to actual physical RAM.
|
||||
/// </summary>
|
||||
public int WorkingSetSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of memory that has ever been pinned to actual physical RAM.
|
||||
/// </summary>
|
||||
public int PeakWorkingSetSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of memory not shared by other processes, such as JS heap or HTML
|
||||
/// content.
|
||||
/// </summary>
|
||||
public int PrivateBytes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MenuItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Will be called with click(menuItem, browserWindow, event) when the menu item is
|
||||
/// clicked.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Action Click { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the label.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The label.
|
||||
/// </value>
|
||||
public string Label { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sublabel.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The sublabel.
|
||||
/// </value>
|
||||
public string Sublabel { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the accelerator.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The accelerator.
|
||||
/// </value>
|
||||
public string Accelerator { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The icon.
|
||||
/// </value>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If false, the menu item will be greyed out and unclickable.
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// If false, the menu item will be entirely hidden.
|
||||
/// </summary>
|
||||
public bool Visible { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Should only be specified for checkbox or radio type menu items.
|
||||
/// </summary>
|
||||
public bool Checked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should be specified for submenu type menu items. If submenu is specified, the
|
||||
/// type: 'submenu' can be omitted.If the value is not a Menu then it will be
|
||||
/// automatically converted to one using Menu.buildFromTemplate.
|
||||
/// </summary>
|
||||
public MenuItem[] Submenu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique within a single menu. If defined then it can be used as a reference to
|
||||
/// this item by the position attribute.
|
||||
/// </summary>
|
||||
public string Id { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// This field allows fine-grained definition of the specific location within a
|
||||
/// given menu.
|
||||
/// </summary>
|
||||
public string Position { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum MenuType
|
||||
{
|
||||
/// <summary>
|
||||
/// The normal
|
||||
/// </summary>
|
||||
normal,
|
||||
|
||||
/// <summary>
|
||||
/// The separator
|
||||
/// </summary>
|
||||
separator,
|
||||
|
||||
/// <summary>
|
||||
/// The submenu
|
||||
/// </summary>
|
||||
submenu,
|
||||
|
||||
/// <summary>
|
||||
/// The checkbox
|
||||
/// </summary>
|
||||
checkbox,
|
||||
|
||||
/// <summary>
|
||||
/// The radio
|
||||
/// </summary>
|
||||
radio
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageBoxOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Can be "none", "info", "error", "question" or "warning". On Windows, "question"
|
||||
/// displays the same icon as "info", unless you set an icon using the "icon"
|
||||
/// option. On macOS, both "warning" and "error" display the same warning icon.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MessageBoxType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of texts for buttons. On Windows, an empty array will result in one button
|
||||
/// labeled "OK".
|
||||
/// </summary>
|
||||
public string[] Buttons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Index of the button in the buttons array which will be selected by default when
|
||||
/// the message box opens.
|
||||
/// </summary>
|
||||
public int DefaultId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Title of the message box, some platforms will not show it.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content of the message box.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra information of the message.
|
||||
/// </summary>
|
||||
public string Detail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If provided, the message box will include a checkbox with the given label. The
|
||||
/// checkbox state can be inspected only when using callback.
|
||||
/// </summary>
|
||||
public string CheckboxLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initial checked state of the checkbox. false by default.
|
||||
/// </summary>
|
||||
public bool CheckboxChecked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The icon.
|
||||
/// </value>
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the button to be used to cancel the dialog, via the Esc key. By
|
||||
/// default this is assigned to the first button with "cancel" or "no" as the label.
|
||||
/// If no such labeled buttons exist and this option is not set, 0 will be used as
|
||||
/// the return value or callback response. This option is ignored on Windows.
|
||||
/// </summary>
|
||||
public int CancelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// On Windows Electron will try to figure out which one of the buttons are common
|
||||
/// buttons(like "Cancel" or "Yes"), and show the others as command links in the
|
||||
/// dialog.This can make the dialog appear in the style of modern Windows apps. If
|
||||
/// you don't like this behavior, you can set noLink to true.
|
||||
/// </summary>
|
||||
public bool NoLink { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalize the keyboard access keys across platforms. Default is false. Enabling
|
||||
/// this assumes AND character is used in the button labels for the placement of the keyboard
|
||||
/// shortcut access key and labels will be converted so they work correctly on each
|
||||
/// platform, AND characters are removed on macOS, converted to _ on Linux, and left
|
||||
/// untouched on Windows.For example, a button label of VieANDw will be converted to
|
||||
/// Vie_w on Linux and View on macOS and can be selected via Alt-W on Windows and
|
||||
/// Linux.
|
||||
/// </summary>
|
||||
public bool NormalizeAccessKeys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MessageBoxOptions"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message.</param>
|
||||
public MessageBoxOptions(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
internal class MessageBoxResponse
|
||||
{
|
||||
public int response { get; set; }
|
||||
public bool @checked { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageBoxResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the response.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The response.
|
||||
/// </value>
|
||||
public int Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [checkbox checked].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [checkbox checked]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool CheckboxChecked { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class OpenDevToolsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the devtools with specified dock state, can be right, bottom, undocked,
|
||||
/// detach.Defaults to last used dock state.In undocked mode it's possible to dock
|
||||
/// back.In detach mode it's not.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public DevToolsMode Mode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls the behavior of OpenExternal.
|
||||
/// </summary>
|
||||
public class OpenExternalOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// <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; }
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the PathName enumeration.
|
||||
/// </summary>
|
||||
public enum PathName
|
||||
{
|
||||
/// <summary>
|
||||
/// User’s home directory.
|
||||
/// </summary>
|
||||
[Description("home")]
|
||||
Home,
|
||||
|
||||
/// <summary>
|
||||
/// Per-user application data directory.
|
||||
/// </summary>
|
||||
[Description("appData")]
|
||||
AppData,
|
||||
|
||||
/// <summary>
|
||||
/// The directory for storing your app’s configuration files,
|
||||
/// which by default it is the appData directory appended with your app’s name.
|
||||
/// </summary>
|
||||
[Description("userData")]
|
||||
UserData,
|
||||
|
||||
/// <summary>
|
||||
/// Temporary directory.
|
||||
/// </summary>
|
||||
[Description("temp")]
|
||||
Temp,
|
||||
|
||||
/// <summary>
|
||||
/// The current executable file.
|
||||
/// </summary>
|
||||
[Description("exe")]
|
||||
Exe,
|
||||
|
||||
/// <summary>
|
||||
/// The libchromiumcontent library.
|
||||
/// </summary>
|
||||
[Description("Module")]
|
||||
Module,
|
||||
|
||||
/// <summary>
|
||||
/// The current user’s Desktop directory.
|
||||
/// </summary>
|
||||
[Description("desktop")]
|
||||
Desktop,
|
||||
|
||||
/// <summary>
|
||||
/// Directory for a user’s “My Documents”.
|
||||
/// </summary>
|
||||
[Description("documents")]
|
||||
Documents,
|
||||
|
||||
/// <summary>
|
||||
/// Directory for a user’s downloads.
|
||||
/// </summary>
|
||||
[Description("downloads")]
|
||||
Downloads,
|
||||
|
||||
/// <summary>
|
||||
/// Directory for a user’s music.
|
||||
/// </summary>
|
||||
[Description("music")]
|
||||
Music,
|
||||
|
||||
/// <summary>
|
||||
/// Directory for a user’s pictures.
|
||||
/// </summary>
|
||||
[Description("pictures")]
|
||||
Pictures,
|
||||
|
||||
/// <summary>
|
||||
/// Directory for a user’s videos.
|
||||
/// </summary>
|
||||
[Description("videos")]
|
||||
Videos,
|
||||
|
||||
/// <summary>
|
||||
/// The logs.
|
||||
/// </summary>
|
||||
[Description("logs")]
|
||||
Logs,
|
||||
|
||||
/// <summary>
|
||||
/// Full path to the system version of the Pepper Flash plugin.
|
||||
/// </summary>
|
||||
[Description("PepperFlashSystemPlugin")]
|
||||
PepperFlashSystemPlugin
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Print dpi
|
||||
/// </summary>
|
||||
public class PrintDpi
|
||||
{
|
||||
/// <summary>
|
||||
/// The horizontal dpi
|
||||
/// </summary>
|
||||
public float Horizontal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The vertical dpi
|
||||
/// </summary>
|
||||
public float Vertical { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The page range to print
|
||||
/// </summary>
|
||||
public class PrintPageRange
|
||||
{
|
||||
/// <summary>
|
||||
/// From
|
||||
/// </summary>
|
||||
public int From { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// To
|
||||
/// </summary>
|
||||
public int To { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print options
|
||||
/// </summary>
|
||||
public class PrintOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't ask user for print settings
|
||||
/// </summary>
|
||||
public bool Silent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prints the background color and image of the web page
|
||||
/// </summary>
|
||||
public bool PrintBackground { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the printer device name to use
|
||||
/// </summary>
|
||||
public string DeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set whether the printed web page will be in color or grayscale
|
||||
/// </summary>
|
||||
public bool Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the type of margins to use. Uses 0 for default margin, 1 for no
|
||||
/// margin, and 2 for minimum margin.
|
||||
/// </summary>
|
||||
public int MarginsType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// true for landscape, false for portrait.
|
||||
/// </summary>
|
||||
public bool Landscape { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The scale factor of the web page
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of pages to print per page sheet
|
||||
/// </summary>
|
||||
public int PagesPerSheet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of copies of the web page to print
|
||||
/// </summary>
|
||||
public bool Copies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the web page should be collated
|
||||
/// </summary>
|
||||
public bool Collate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The page range to print
|
||||
/// </summary>
|
||||
public PrintPageRange PageRanges { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the duplex mode of the printed web page. Can be simplex, shortEdge, or longEdge.
|
||||
/// </summary>
|
||||
public string DuplexMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dpi
|
||||
/// </summary>
|
||||
public PrintDpi Dpi { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Printer info
|
||||
/// </summary>
|
||||
public class PrinterInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Status
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is default
|
||||
/// </summary>
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProcessMetric
|
||||
{
|
||||
/// <summary>
|
||||
/// Process id of the process.
|
||||
/// </summary>
|
||||
public int PId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Process type (Browser or Tab or GPU etc).
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CPU usage of the process.
|
||||
/// </summary>
|
||||
public CPUUsage Cpu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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 int CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Memory information for the process.
|
||||
/// </summary>
|
||||
public MemoryInfo Memory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the process is sandboxed on OS level.
|
||||
/// </summary>
|
||||
public bool Sandboxed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// One of the following values:
|
||||
/// untrusted | low | medium | high | unknown
|
||||
/// </summary>
|
||||
public string IntegrityLevel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProgressBarOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Mode for the progress bar. Can be 'none' | 'normal' | 'indeterminate' | 'error' | 'paused'.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public ProgressBarMode Mode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProgressInfo
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string BytesPerSecond { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Percent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Total { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Transferred { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class SecondInstanceResponse
|
||||
{
|
||||
public string[] args { get; set; }
|
||||
|
||||
public string workingDirectory { get;set;}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public sealed class SourcesOption
|
||||
{
|
||||
public string[] Types { get; set; }
|
||||
public Size ThumbnailSize { get; set; }
|
||||
public bool FetchWindowIcons { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use ImageOptions instead.")]
|
||||
public class ToBitmapOptions
|
||||
{
|
||||
/// <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 ImageOptions(ToBitmapOptions o) => new () {ScaleFactor = o.ScaleFactor};
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use ImageOptions instead.")]
|
||||
public class ToDataUrlOptions
|
||||
{
|
||||
/// <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 ImageOptions(ToDataUrlOptions o) => new () {ScaleFactor = o.ScaleFactor};
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("Use ImageOptions instead.")]
|
||||
public class ToPNGOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the scalefactor
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
/// <summary>
|
||||
/// Utility conversion for obsolete class
|
||||
/// </summary>
|
||||
public static implicit operator ImageOptions(ToPNGOptions o) => new () {ScaleFactor = o.ScaleFactor};
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
public class TrayClickEventResponse
|
||||
{
|
||||
public TrayClickEventArgs eventArgs { get; set; }
|
||||
public Rectangle bounds { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UpdateInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The version.
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public UpdateFileInfo[] Files { get; set; } = Array.Empty<UpdateFileInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// The release name.
|
||||
/// </summary>
|
||||
public string ReleaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The release notes.
|
||||
/// </summary>
|
||||
public string ReleaseNotes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ReleaseDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The staged rollout percentage, 0-100.
|
||||
/// </summary>
|
||||
public int StagingPercentage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using System.Runtime.Serialization;
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum Vibrancy
|
||||
{
|
||||
/// <summary>
|
||||
/// The appearance based
|
||||
/// </summary>
|
||||
[EnumMember(Value = "appearance-based")]
|
||||
[Obsolete("Removed in macOS Catalina (10.15).")]
|
||||
appearanceBased,
|
||||
|
||||
/// <summary>
|
||||
/// The light
|
||||
/// </summary>
|
||||
[Obsolete("Removed in macOS Catalina (10.15).")]
|
||||
light,
|
||||
|
||||
/// <summary>
|
||||
/// The dark
|
||||
/// </summary>
|
||||
[Obsolete("Removed in macOS Catalina (10.15).")]
|
||||
dark,
|
||||
|
||||
/// <summary>
|
||||
/// The titlebar
|
||||
/// </summary>
|
||||
titlebar,
|
||||
|
||||
/// <summary>
|
||||
/// The selection
|
||||
/// </summary>
|
||||
selection,
|
||||
|
||||
/// <summary>
|
||||
/// The menu
|
||||
/// </summary>
|
||||
menu,
|
||||
|
||||
/// <summary>
|
||||
/// The popover
|
||||
/// </summary>
|
||||
popover,
|
||||
|
||||
/// <summary>
|
||||
/// The sidebar
|
||||
/// </summary>
|
||||
sidebar,
|
||||
|
||||
/// <summary>
|
||||
/// The medium light
|
||||
/// </summary>
|
||||
[EnumMember(Value = "medium-light")]
|
||||
[Obsolete("Removed in macOS Catalina (10.15).")]
|
||||
mediumLight,
|
||||
|
||||
/// <summary>
|
||||
/// The ultra dark
|
||||
/// </summary>
|
||||
[EnumMember(Value = "ultra-dark")]
|
||||
[Obsolete("Removed in macOS Catalina (10.15).")]
|
||||
ultraDark,
|
||||
|
||||
header,
|
||||
|
||||
sheet,
|
||||
|
||||
window,
|
||||
|
||||
hud,
|
||||
|
||||
[EnumMember(Value = "fullscreen-ui")]
|
||||
fullscreenUI,
|
||||
|
||||
tooltip,
|
||||
|
||||
content,
|
||||
|
||||
[EnumMember(Value = "under-window")]
|
||||
underWindow,
|
||||
|
||||
[EnumMember(Value = "under-page")]
|
||||
underPage
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic Event Consumers for Electron Modules
|
||||
/// </summary>
|
||||
internal class Events
|
||||
{
|
||||
private static Events _events;
|
||||
private static readonly object _syncRoot = new();
|
||||
private readonly TextInfo _ti = new CultureInfo("en-US", false).TextInfo;
|
||||
private Events()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static Events Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_events == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_events == null)
|
||||
{
|
||||
_events = new Events();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _events;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped electron event.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">The name of the module, e.g. app, dock, etc...</param>
|
||||
/// <param name="eventName">The name of the event</param>
|
||||
/// <param name="fn">The event handler</param>
|
||||
public void On(string moduleName, string eventName, Action fn) => On(moduleName, eventName, _ => fn());
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped electron event.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">The name of the module, e.g. app, dock, etc...</param>
|
||||
/// <param name="eventName">The name of the event</param>
|
||||
/// <param name="fn">The event handler</param>
|
||||
public void On(string moduleName, string eventName, Action<object> fn)
|
||||
{
|
||||
var listener = $"{moduleName}{_ti.ToTitleCase(eventName)}Completed";
|
||||
var subscriber = $"register-{moduleName}-on-event";
|
||||
|
||||
BridgeConnector.On(listener, fn);
|
||||
BridgeConnector.Emit(subscriber, eventName, listener);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped electron event.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">The name of the module, e.g. app, dock, etc...</param>
|
||||
/// <param name="eventName">The name of the event</param>
|
||||
/// <param name="fn">The event handler</param>
|
||||
public void Once(string moduleName, string eventName, Action fn) => Once(moduleName, eventName, _ => fn());
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped electron event.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">The name of the module, e.g. app, dock, etc...</param>
|
||||
/// <param name="eventName">The name of the event</param>
|
||||
/// <param name="fn">The event handler</param>
|
||||
public void Once(string moduleName, string eventName, Action<object> fn)
|
||||
{
|
||||
var listener = $"{moduleName}{_ti.ToTitleCase(eventName)}Completed";
|
||||
var subscriber = $"register-{moduleName}-once-event";
|
||||
BridgeConnector.Once(listener, fn);
|
||||
BridgeConnector.Emit(subscriber, eventName, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ElectronNET.API.Extensions
|
||||
{
|
||||
internal static class EnumExtensions
|
||||
{
|
||||
public static string GetDescription<T>(this T enumerationValue) where T : struct
|
||||
{
|
||||
Type type = enumerationValue.GetType();
|
||||
if (!type.IsEnum)
|
||||
{
|
||||
throw new ArgumentException("EnumerationValue must be of Enum type", nameof(enumerationValue));
|
||||
}
|
||||
|
||||
//Tries to find a DescriptionAttribute for a potential friendly name
|
||||
//for the enum
|
||||
MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
|
||||
if (memberInfo != null && memberInfo.Length > 0)
|
||||
{
|
||||
object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
{
|
||||
//Pull out the description value
|
||||
return ((DescriptionAttribute)attrs[0]).Description;
|
||||
}
|
||||
}
|
||||
//If we have no description attribute, just return the ToString of the enum
|
||||
return enumerationValue.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,709 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Control your application's event lifecycle.
|
||||
/// </summary>
|
||||
public interface IApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Emitted when all windows have been closed.
|
||||
/// <para/>
|
||||
/// If you do not subscribe to this event and all windows are closed, the default behavior is to quit
|
||||
/// the app; however, if you subscribe, you control whether the app quits or not.If the user pressed
|
||||
/// Cmd + Q, or the developer called <see cref="Quit"/>, Electron will first try to close all the windows
|
||||
/// and then emit the <see cref="WillQuit"/> event, and in this case the <see cref="WindowAllClosed"/> event
|
||||
/// would not be emitted.
|
||||
/// </summary>
|
||||
event Action WindowAllClosed;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted before the application starts closing its windows.
|
||||
/// <para/>
|
||||
/// Note: If application quit was initiated by <see cref="AutoUpdater.QuitAndInstall"/> then <see cref="BeforeQuit"/>
|
||||
/// is emitted after emitting close event on all windows and closing them.
|
||||
/// <para/>
|
||||
/// Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
|
||||
/// </summary>
|
||||
event Func<QuitEventArgs, Task> BeforeQuit;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when all windows have been closed and the application will quit.
|
||||
/// <para/>
|
||||
/// See the description of the <see cref="WindowAllClosed"/> event for the differences between the <see cref="WillQuit"/>
|
||||
/// and <see cref="WindowAllClosed"/> events.
|
||||
/// <para/>
|
||||
/// Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
|
||||
/// </summary>
|
||||
event Func<QuitEventArgs, Task> WillQuit;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the application is quitting.
|
||||
/// <para/>
|
||||
/// Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
|
||||
/// </summary>
|
||||
event Func<Task> Quitting;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a <see cref="BrowserWindow"/> blurred.
|
||||
/// </summary>
|
||||
event Action BrowserWindowBlur;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a <see cref="BrowserWindow"/> gets focused.
|
||||
/// </summary>
|
||||
event Action BrowserWindowFocus;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a new <see cref="BrowserWindow"/> is created.
|
||||
/// </summary>
|
||||
event Action BrowserWindowCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a new <see cref="WebContents"/> is created.
|
||||
/// </summary>
|
||||
event Action WebContentsCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when Chrome’s accessibility support changes. This event fires when assistive technologies, such as
|
||||
/// screen readers, are enabled or disabled. See https://www.chromium.org/developers/design-documents/accessibility for more details.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> when Chrome's accessibility support is enabled, <see langword="false"/> otherwise.</returns>
|
||||
event Action<bool> AccessibilitySupportChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the application has finished basic startup.
|
||||
/// </summary>
|
||||
event Action Ready;
|
||||
|
||||
/// <summary>
|
||||
/// Application host fully started.
|
||||
/// </summary>
|
||||
bool IsReady { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="string"/> property that indicates the current application's name, which is the name in the
|
||||
/// application's package.json file.
|
||||
///
|
||||
/// Usually the name field of package.json is a short lowercase name, according to the npm modules spec. You
|
||||
/// should usually also specify a productName field, which is your application's full capitalized name, and
|
||||
/// which will be preferred over name by Electron.
|
||||
/// </summary>
|
||||
string Name
|
||||
{
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="string"/> property that indicates the current application's name, which is the name in the
|
||||
/// application's package.json file.
|
||||
///
|
||||
/// Usually the name field of package.json is a short lowercase name, according to the npm modules spec. You
|
||||
/// should usually also specify a productName field, which is your application's full capitalized name, and
|
||||
/// which will be preferred over name by Electron.
|
||||
/// </summary>
|
||||
Task<string> GetNameAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="CommandLine"/> object that allows you to read and manipulate the command line arguments that Chromium uses.
|
||||
/// </summary>
|
||||
CommandLine CommandLine { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="string"/> which is the user agent string Electron will use as a global fallback.
|
||||
/// <para/>
|
||||
/// This is the user agent that will be used when no user agent is set at the webContents or
|
||||
/// session level. It is useful for ensuring that your entire app has the same user agent. Set to a
|
||||
/// custom value as early as possible in your app's initialization to ensure that your overridden value
|
||||
/// is used.
|
||||
/// </summary>
|
||||
string UserAgentFallback
|
||||
{
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="string"/> which is the user agent string Electron will use as a global fallback.
|
||||
/// <para/>
|
||||
/// This is the user agent that will be used when no user agent is set at the webContents or
|
||||
/// session level. It is useful for ensuring that your entire app has the same user agent. Set to a
|
||||
/// custom value as early as possible in your app's initialization to ensure that your overridden value
|
||||
/// is used.
|
||||
/// </summary>
|
||||
Task<string> GetUserAgentFallbackAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a MacOS user wants to open a file with the application. The open-file event is usually emitted
|
||||
/// when the application is already open and the OS wants to reuse the application to open the file.
|
||||
/// open-file is also emitted when a file is dropped onto the dock and the application is not yet running.
|
||||
/// <para/>
|
||||
/// On Windows, you have to parse the arguments using App.CommandLine to get the filepath.
|
||||
/// </summary>
|
||||
event Action<string> OpenFile;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when a MacOS user wants to open a URL with the application. Your application's Info.plist file must
|
||||
/// define the URL scheme within the CFBundleURLTypes key, and set NSPrincipalClass to AtomApplication.
|
||||
/// </summary>
|
||||
event Action<string> OpenUrl;
|
||||
|
||||
/// <summary>
|
||||
/// Try to close all windows. The <see cref="BeforeQuit"/> event will be emitted first. If all windows are successfully
|
||||
/// closed, the <see cref="WillQuit"/> event will be emitted and by default the application will terminate. This method
|
||||
/// guarantees that all beforeunload and unload event handlers are correctly executed. It is possible
|
||||
/// that a window cancels the quitting by returning <see langword="false"/> in the beforeunload event handler.
|
||||
/// </summary>
|
||||
void Quit();
|
||||
|
||||
/// <summary>
|
||||
/// All windows will be closed immediately without asking user and the <see cref="BeforeQuit"/> and <see cref="WillQuit"/>
|
||||
/// events will not be emitted.
|
||||
/// </summary>
|
||||
/// <param name="exitCode">Exits immediately with exitCode. exitCode defaults to 0.</param>
|
||||
void Exit(int exitCode = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Relaunches the app when current instance exits. By default the new instance will use the same working directory
|
||||
/// and command line arguments with current instance.
|
||||
/// <para/>
|
||||
/// Note that this method does not quit the app when executed, you have to call <see cref="Quit"/> or <see cref="Exit"/>
|
||||
/// after calling <see cref="Relaunch()"/> to make the app restart.
|
||||
/// <para/>
|
||||
/// When <see cref="Relaunch()"/> is called for multiple times, multiple instances will be started after current instance
|
||||
/// exited.
|
||||
/// </summary>
|
||||
void Relaunch();
|
||||
|
||||
/// <summary>
|
||||
/// Relaunches the app when current instance exits. By default the new instance will use the same working directory
|
||||
/// and command line arguments with current instance. When <see cref="RelaunchOptions.Args"/> is specified, the
|
||||
/// <see cref="RelaunchOptions.Args"/> will be passed as command line arguments instead. When <see cref="RelaunchOptions.ExecPath"/>
|
||||
/// is specified, the <see cref="RelaunchOptions.ExecPath"/> will be executed for relaunch instead of current app.
|
||||
/// <para/>
|
||||
/// Note that this method does not quit the app when executed, you have to call <see cref="Quit"/> or <see cref="Exit"/>
|
||||
/// after calling <see cref="Relaunch()"/> to make the app restart.
|
||||
/// <para/>
|
||||
/// When <see cref="Relaunch()"/> is called for multiple times, multiple instances will be started after current instance
|
||||
/// exited.
|
||||
/// </summary>
|
||||
/// <param name="relaunchOptions">Options for the relaunch.</param>
|
||||
void Relaunch(RelaunchOptions relaunchOptions);
|
||||
|
||||
/// <summary>
|
||||
/// On Linux, focuses on the first visible window. On macOS, makes the application the active app. On Windows, focuses
|
||||
/// on the application's first window.
|
||||
/// </summary>
|
||||
void Focus();
|
||||
|
||||
/// <summary>
|
||||
/// On Linux, focuses on the first visible window. On macOS, makes the application the active app. On Windows, focuses
|
||||
/// on the application's first window.
|
||||
/// <para/>
|
||||
/// You should seek to use the <see cref="FocusOptions.Steal"/> option as sparingly as possible.
|
||||
/// </summary>
|
||||
void Focus(FocusOptions focusOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Hides all application windows without minimizing them.
|
||||
/// </summary>
|
||||
void Hide();
|
||||
|
||||
/// <summary>
|
||||
/// Shows application windows after they were hidden. Does not automatically focus them.
|
||||
/// </summary>
|
||||
void Show();
|
||||
|
||||
/// <summary>
|
||||
/// The current application directory.
|
||||
/// </summary>
|
||||
Task<string> GetAppPathAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets or creates a directory your app's logs which can then be manipulated with <see cref="GetPathAsync"/>
|
||||
/// or <see cref="SetPath"/>.
|
||||
/// <para/>
|
||||
/// Calling <see cref="SetAppLogsPath"/> without a path parameter will result in this directory being set to
|
||||
/// ~/Library/Logs/YourAppName on macOS, and inside the userData directory on Linux and Windows.
|
||||
/// </summary>
|
||||
/// <param name="path">A custom path for your logs. Must be absolute.</param>
|
||||
void SetAppLogsPath(string path);
|
||||
|
||||
/// <summary>
|
||||
/// The path to a special directory. If <see cref="GetPathAsync"/> is called without called
|
||||
/// <see cref="SetAppLogsPath"/> being called first, a default directory will be created equivalent
|
||||
/// to calling <see cref="SetAppLogsPath"/> without a path parameter.
|
||||
/// </summary>
|
||||
/// <param name="pathName">Special directory.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A path to a special directory or file associated with name.</returns>
|
||||
Task<string> GetPathAsync(PathName pathName, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the path to a special directory or file associated with name. If the path specifies a directory
|
||||
/// that does not exist, an Error is thrown. In that case, the directory should be created with fs.mkdirSync or similar.
|
||||
/// <para/>
|
||||
/// You can only override paths of a name defined in <see cref="GetPathAsync"/>.
|
||||
/// <para/>
|
||||
/// By default, web pages' cookies and caches will be stored under the <see cref="PathName.UserData"/> directory. If you
|
||||
/// want to change this location, you have to override the <see cref="PathName.UserData"/> path before the <see cref="Ready"/>
|
||||
/// event of the <see cref="App"/> module is emitted.
|
||||
/// <param name="name">Special directory.</param>
|
||||
/// <param name="path">New path to a special directory.</param>
|
||||
/// </summary>
|
||||
void SetPath(PathName name, string path);
|
||||
|
||||
/// <summary>
|
||||
/// The version of the loaded application. If no version is found in the application’s package.json file,
|
||||
/// the version of the current bundle or executable is returned.
|
||||
/// </summary>
|
||||
/// <returns>The version of the loaded application.</returns>
|
||||
Task<string> GetVersionAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// The current application locale. Possible return values are documented <see href="https://www.electronjs.org/docs/api/locales">here</see>.
|
||||
/// <para/>
|
||||
/// Note: When distributing your packaged app, you have to also ship the locales folder.
|
||||
/// <para/>
|
||||
/// Note: On Windows, you have to call it after the <see cref="Ready"/> events gets emitted.
|
||||
/// </summary>
|
||||
/// <returns>The current application locale.</returns>
|
||||
Task<string> GetLocaleAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Adds path to the recent documents list. This list is managed by the OS. On Windows you can visit the
|
||||
/// list from the task bar, and on macOS you can visit it from dock menu.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to add.</param>
|
||||
void AddRecentDocument(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the recent documents list.
|
||||
/// </summary>
|
||||
void ClearRecentDocuments();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current executable as the default handler for a protocol (aka URI scheme). It allows you to
|
||||
/// integrate your app deeper into the operating system. Once registered, all links with your-protocol://
|
||||
/// will be opened with the current executable. The whole link, including protocol, will be passed to your
|
||||
/// application as a parameter.
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can only register protocols that have been added to your app's info.plist, which
|
||||
/// cannot be modified at runtime. However, you can change the file during build time via
|
||||
/// <see href="https://www.electronforge.io/">Electron Forge</see>,
|
||||
/// <see href="https://github.com/electron/electron-packager">Electron Packager</see>, or by editing info.plist
|
||||
/// with a text editor. Please refer to
|
||||
/// <see href="https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// Note: In a Windows Store environment (when packaged as an appx) this API will return true for all calls but
|
||||
/// the registry key it sets won't be accessible by other applications. In order to register your Windows Store
|
||||
/// application as a default protocol handler you <see href="https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol">must declare the protocol in your manifest</see>.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">
|
||||
/// The name of your protocol, without ://. For example, if you want your app to handle electron:// links,
|
||||
/// call this method with electron as the parameter.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> SetAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current executable as the default handler for a protocol (aka URI scheme). It allows you to
|
||||
/// integrate your app deeper into the operating system. Once registered, all links with your-protocol://
|
||||
/// will be opened with the current executable. The whole link, including protocol, will be passed to your
|
||||
/// application as a parameter.
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can only register protocols that have been added to your app's info.plist, which
|
||||
/// cannot be modified at runtime. However, you can change the file during build time via
|
||||
/// <see href="https://www.electronforge.io/">Electron Forge</see>,
|
||||
/// <see href="https://github.com/electron/electron-packager">Electron Packager</see>, or by editing info.plist
|
||||
/// with a text editor. Please refer to
|
||||
/// <see href="https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// Note: In a Windows Store environment (when packaged as an appx) this API will return true for all calls but
|
||||
/// the registry key it sets won't be accessible by other applications. In order to register your Windows Store
|
||||
/// application as a default protocol handler you <see href="https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol">must declare the protocol in your manifest</see>.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">
|
||||
/// The name of your protocol, without ://. For example, if you want your app to handle electron:// links,
|
||||
/// call this method with electron as the parameter.</param>
|
||||
/// <param name="path">The path to the Electron executable. Defaults to process.execPath</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> SetAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current executable as the default handler for a protocol (aka URI scheme). It allows you to
|
||||
/// integrate your app deeper into the operating system. Once registered, all links with your-protocol://
|
||||
/// will be opened with the current executable. The whole link, including protocol, will be passed to your
|
||||
/// application as a parameter.
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can only register protocols that have been added to your app's info.plist, which
|
||||
/// cannot be modified at runtime. However, you can change the file during build time via
|
||||
/// <see href="https://www.electronforge.io/">Electron Forge</see>,
|
||||
/// <see href="https://github.com/electron/electron-packager">Electron Packager</see>, or by editing info.plist
|
||||
/// with a text editor. Please refer to
|
||||
/// <see href="https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// Note: In a Windows Store environment (when packaged as an appx) this API will return true for all calls but
|
||||
/// the registry key it sets won't be accessible by other applications. In order to register your Windows Store
|
||||
/// application as a default protocol handler you <see href="https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol">must declare the protocol in your manifest</see>.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">
|
||||
/// The name of your protocol, without ://. For example, if you want your app to handle electron:// links,
|
||||
/// call this method with electron as the parameter.</param>
|
||||
/// <param name="path">The path to the Electron executable. Defaults to process.execPath</param>
|
||||
/// <param name="args">Arguments passed to the executable. Defaults to an empty array.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> SetAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable as the default handler for a protocol (aka URI scheme).
|
||||
/// If so, it will remove the app as the default handler.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> RemoveAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable as the default handler for a protocol (aka URI scheme).
|
||||
/// If so, it will remove the app as the default handler.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="path">Defaults to process.execPath.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> RemoveAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable as the default handler for a protocol (aka URI scheme).
|
||||
/// If so, it will remove the app as the default handler.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="path">Defaults to process.execPath.</param>
|
||||
/// <param name="args">Defaults to an empty array.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> RemoveAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable is the default handler for a protocol (aka URI scheme).
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can use this method to check if the app has been registered as the default protocol
|
||||
/// handler for a protocol. You can also verify this by checking ~/Library/Preferences/com.apple.LaunchServices.plist
|
||||
/// on the macOS machine. Please refer to <see href="https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the current executable is the default handler for a protocol (aka URI scheme).</returns>
|
||||
Task<bool> IsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable is the default handler for a protocol (aka URI scheme).
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can use this method to check if the app has been registered as the default protocol
|
||||
/// handler for a protocol. You can also verify this by checking ~/Library/Preferences/com.apple.LaunchServices.plist
|
||||
/// on the macOS machine. Please refer to <see href="https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="path">Defaults to process.execPath.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the current executable is the default handler for a protocol (aka URI scheme).</returns>
|
||||
Task<bool> IsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// This method checks if the current executable is the default handler for a protocol (aka URI scheme).
|
||||
/// <para/>
|
||||
/// Note: On macOS, you can use this method to check if the app has been registered as the default protocol
|
||||
/// handler for a protocol. You can also verify this by checking ~/Library/Preferences/com.apple.LaunchServices.plist
|
||||
/// on the macOS machine. Please refer to <see href="https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme">Apple's documentation</see>
|
||||
/// for details.
|
||||
/// <para/>
|
||||
/// The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
/// </summary>
|
||||
/// <param name="protocol">The name of your protocol, without ://.</param>
|
||||
/// <param name="path">Defaults to process.execPath.</param>
|
||||
/// <param name="args">Defaults to an empty array.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the current executable is the default handler for a protocol (aka URI scheme).</returns>
|
||||
Task<bool> IsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Adds tasks to the <see cref="UserTask"/> category of the JumpList on Windows.
|
||||
/// <para/>
|
||||
/// Note: If you'd like to customize the Jump List even more use <see cref="SetJumpList"/> instead.
|
||||
/// </summary>
|
||||
/// <param name="userTasks">Array of <see cref="UserTask"/> objects.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> SetUserTasksAsync(UserTask[] userTasks, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Jump List settings for the application.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Jump List settings.</returns>
|
||||
Task<JumpListSettings> GetJumpListSettingsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets or removes a custom Jump List for the application. If categories is null the previously set custom
|
||||
/// Jump List (if any) will be replaced by the standard Jump List for the app (managed by Windows).
|
||||
/// <para/>
|
||||
/// Note: If a <see cref="JumpListCategory"/> object has neither the <see cref="JumpListCategory.Type"/> nor
|
||||
/// the <see cref="JumpListCategory.Name"/> property set then its <see cref="JumpListCategory.Type"/> is assumed
|
||||
/// to be <see cref="JumpListCategoryType.tasks"/>. If the <see cref="JumpListCategory.Name"/> property is set but
|
||||
/// the <see cref="JumpListCategory.Type"/> property is omitted then the <see cref="JumpListCategory.Type"/> is
|
||||
/// assumed to be <see cref="JumpListCategoryType.custom"/>.
|
||||
/// <para/>
|
||||
/// Note: Users can remove items from custom categories, and Windows will not allow a removed item to be added
|
||||
/// back into a custom category until after the next successful call to <see cref="SetJumpList"/>. Any attempt
|
||||
/// to re-add a removed item to a custom category earlier than that will result in the entire custom category being
|
||||
/// omitted from the Jump List. The list of removed items can be obtained using <see cref="GetJumpListSettingsAsync"/>.
|
||||
/// </summary>
|
||||
/// <param name="categories">Array of <see cref="JumpListCategory"/> objects.</param>
|
||||
void SetJumpList(JumpListCategory[] categories);
|
||||
|
||||
/// <summary>
|
||||
/// The return value of this method indicates whether or not this instance of your application successfully obtained
|
||||
/// the lock. If it failed to obtain the lock, you can assume that another instance of your application is already
|
||||
/// running with the lock and exit immediately.
|
||||
/// <para/>
|
||||
/// I.e.This method returns <see langword="true"/> if your process is the primary instance of your application and your
|
||||
/// app should continue loading. It returns <see langword="false"/> if your process should immediately quit as it has
|
||||
/// sent its parameters to another instance that has already acquired the lock.
|
||||
/// <para/>
|
||||
/// On macOS, the system enforces single instance automatically when users try to open a second instance of your app
|
||||
/// in Finder, and the open-file and open-url events will be emitted for that.However when users start your app in
|
||||
/// command line, the system's single instance mechanism will be bypassed, and you have to use this method to ensure
|
||||
/// single instance.
|
||||
/// </summary>
|
||||
/// <param name="newInstanceOpened">Lambda with an array of the second instance’s command line arguments.
|
||||
/// The second parameter is the working directory path.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>This method returns false if your process is the primary instance of the application and your app
|
||||
/// should continue loading. And returns true if your process has sent its parameters to another instance, and
|
||||
/// you should immediately quit.
|
||||
/// </returns>
|
||||
Task<bool> RequestSingleInstanceLockAsync(Action<string[], string> newInstanceOpened, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Releases all locks that were created by makeSingleInstance. This will allow
|
||||
/// multiple instances of the application to once again run side by side.
|
||||
/// </summary>
|
||||
void ReleaseSingleInstanceLock();
|
||||
|
||||
/// <summary>
|
||||
/// This method returns whether or not this instance of your app is currently holding the single instance lock.
|
||||
/// You can request the lock with <see cref="RequestSingleInstanceLockAsync"/> and release with
|
||||
/// <see cref="ReleaseSingleInstanceLock"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
Task<bool> HasSingleInstanceLockAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an NSUserActivity and sets it as the current activity. The activity is
|
||||
/// eligible for <see href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html">Handoff</see>
|
||||
/// to another device afterward.
|
||||
/// </summary>
|
||||
/// <param name="type">Uniquely identifies the activity. Maps to <see href="https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSUserActivity_Class/index.html#//apple_ref/occ/instp/NSUserActivity/activityType">NSUserActivity.activityType</see>.</param>
|
||||
/// <param name="userInfo">App-specific state to store for use by another device.</param>
|
||||
void SetUserActivity(string type, object userInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an NSUserActivity and sets it as the current activity. The activity is
|
||||
/// eligible for <see href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html">Handoff</see>
|
||||
/// to another device afterward.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// Uniquely identifies the activity. Maps to <see href="https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSUserActivity_Class/index.html#//apple_ref/occ/instp/NSUserActivity/activityType">NSUserActivity.activityType</see>.
|
||||
/// </param>
|
||||
/// <param name="userInfo">App-specific state to store for use by another device.</param>
|
||||
/// <param name="webpageUrl">
|
||||
/// The webpage to load in a browser if no suitable app is installed on the resuming device. The scheme must be http or https.
|
||||
/// </param>
|
||||
void SetUserActivity(string type, object userInfo, string webpageUrl);
|
||||
|
||||
/// <summary>
|
||||
/// The type of the currently running activity.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
Task<string> GetCurrentActivityTypeAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Invalidates the current <see href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html">Handoff</see> user activity.
|
||||
/// </summary>
|
||||
void InvalidateCurrentActivity();
|
||||
|
||||
/// <summary>
|
||||
/// Marks the current <see href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html">Handoff</see> user activity as inactive without invalidating it.
|
||||
/// </summary>
|
||||
void ResignCurrentActivity();
|
||||
|
||||
/// <summary>
|
||||
/// Changes the <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx">Application User Model ID</see> to id.
|
||||
/// </summary>
|
||||
/// <param name="id">Model Id.</param>
|
||||
void SetAppUserModelId(string id);
|
||||
|
||||
/// TODO: Check new parameter which is a function [App.ImportCertificate]
|
||||
/// <summary>
|
||||
/// Imports the certificate in pkcs12 format into the platform certificate store.
|
||||
/// callback is called with the result of import operation, a value of 0 indicates
|
||||
/// success while any other value indicates failure according to chromium net_error_list.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Result of import. Value of 0 indicates success.</returns>
|
||||
Task<int> ImportCertificateAsync(ImportCertificateOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Memory and cpu usage statistics of all the processes associated with the app.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Array of ProcessMetric objects that correspond to memory and cpu usage
|
||||
/// statistics of all the processes associated with the app.
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// </returns>
|
||||
Task<ProcessMetric[]> GetAppMetricsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// The Graphics Feature Status from chrome://gpu/.
|
||||
/// <para/>
|
||||
/// Note: This information is only usable after the gpu-info-update event is emitted.
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// </summary>
|
||||
Task<GPUFeatureStatus> GetGpuFeatureStatusAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the counter badge for current app. Setting the count to 0 will hide the badge.
|
||||
/// On macOS it shows on the dock icon. On Linux it only works for Unity launcher.
|
||||
/// <para/>
|
||||
/// Note: Unity launcher requires the existence of a .desktop file to work, for more
|
||||
/// information please read <see href="https://www.electronjs.org/docs/tutorial/desktop-environment-integration#unity-launcher">Desktop Environment Integration</see>.
|
||||
/// </summary>
|
||||
/// <param name="count">Counter badge.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the call succeeded.</returns>
|
||||
Task<bool> SetBadgeCountAsync(int count, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// The current value displayed in the counter badge.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
Task<int> GetBadgeCountAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the current desktop environment is Unity launcher.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
Task<bool> IsUnityRunningAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// If you provided path and args options to <see cref="SetLoginItemSettings"/> then you need to pass the same
|
||||
/// arguments here for <see cref="LoginItemSettings.OpenAtLogin"/> to be set correctly.
|
||||
/// </summary>
|
||||
Task<LoginItemSettings> GetLoginItemSettingsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// If you provided path and args options to <see cref="SetLoginItemSettings"/> then you need to pass the same
|
||||
/// arguments here for <see cref="LoginItemSettings.OpenAtLogin"/> to be set correctly.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
Task<LoginItemSettings> GetLoginItemSettingsAsync(LoginItemSettingsOptions options, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Set the app's login item settings.
|
||||
/// To work with Electron's autoUpdater on Windows, which uses <see href="https://github.com/Squirrel/Squirrel.Windows">Squirrel</see>,
|
||||
/// you'll want to set the launch path to Update.exe, and pass arguments that specify your application name.
|
||||
/// </summary>
|
||||
/// <param name="loginSettings"></param>
|
||||
void SetLoginItemSettings(LoginSettings loginSettings);
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if Chrome's accessibility support is enabled, <see langword="false"/> otherwise. This API will
|
||||
/// return <see langword="true"/> if the use of assistive technologies, such as screen readers, has been detected.
|
||||
/// See <see href="chromium.org/developers/design-documents/accessibility">Chromium's accessibility docs</see> for more details.
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if Chrome’s accessibility support is enabled, <see langword="false"/> otherwise.</returns>
|
||||
Task<bool> IsAccessibilitySupportEnabledAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Manually enables Chrome's accessibility support, allowing to expose accessibility switch to users in application settings.
|
||||
/// See <see href="chromium.org/developers/design-documents/accessibility">Chromium's accessibility docs</see> for more details.
|
||||
/// Disabled (<see langword="false"/>) by default.
|
||||
/// <para/>
|
||||
/// This API must be called after the <see cref="Ready"/> event is emitted.
|
||||
/// <para/>
|
||||
/// Note: Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
|
||||
/// </summary>
|
||||
/// <param name="enabled">Enable or disable <see href="https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree">accessibility tree</see> rendering.</param>
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Show the app's about panel options. These options can be overridden with
|
||||
/// <see cref="SetAboutPanelOptions"/>.
|
||||
/// </summary>
|
||||
void ShowAboutPanel();
|
||||
|
||||
/// <summary>
|
||||
/// Set the about panel options. This will override the values defined in the app's .plist file on macOS. See the
|
||||
/// <see href="https://developer.apple.com/reference/appkit/nsapplication/1428479-orderfrontstandardaboutpanelwith?language=objc">Apple docs</see>
|
||||
/// for more details. On Linux, values must be set in order to be shown; there are no defaults.
|
||||
/// <para/>
|
||||
/// If you do not set credits but still wish to surface them in your app, AppKit will look for a file named "Credits.html",
|
||||
/// "Credits.rtf", and "Credits.rtfd", in that order, in the bundle returned by the NSBundle class method main. The first file
|
||||
/// found is used, and if none is found, the info area is left blank. See Apple
|
||||
/// <see href="https://developer.apple.com/documentation/appkit/nsaboutpaneloptioncredits?language=objc">documentation</see> for more information.
|
||||
/// </summary>
|
||||
/// <param name="options">About panel options.</param>
|
||||
void SetAboutPanelOptions(AboutPanelOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="App"/> module.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void On(string eventName, Action fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="App"/> module.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void On(string eventName, Action<object> fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="App"/> module once.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void Once(string eventName, Action fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="App"/> module once.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void Once(string eventName, Action<object> fn);
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Enable apps to automatically update themselves. Based on electron-updater.
|
||||
/// </summary>
|
||||
public interface IAutoUpdater
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether to automatically download an update when it is found. (Default is true)
|
||||
/// </summary>
|
||||
bool AutoDownload { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically download an update when it is found. (Default is true)
|
||||
/// </summary>
|
||||
Task<bool> IsAutoDownloadEnabledAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically install a downloaded update on app quit (if `QuitAndInstall` was not called before).
|
||||
///
|
||||
/// Applicable only on Windows and Linux.
|
||||
/// </summary>
|
||||
bool AutoInstallOnAppQuit { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically install a downloaded update on app quit (if `QuitAndInstall` was not called before).
|
||||
///
|
||||
/// Applicable only on Windows and Linux.
|
||||
/// </summary>
|
||||
Task<bool> IsAutoInstallOnAppQuitEnabledAsync { get; }
|
||||
|
||||
/// <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>
|
||||
bool AllowPrerelease { set; }
|
||||
|
||||
/// <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>
|
||||
Task<bool> IsAllowPrereleaseEnabledAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.*
|
||||
/// Get all release notes (from current version to latest), not just the latest (Default is false).
|
||||
/// </summary>
|
||||
bool FullChangelog { set; }
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.*
|
||||
/// Get all release notes (from current version to latest), not just the latest (Default is false).
|
||||
/// </summary>
|
||||
Task<bool> IsFullChangeLogEnabledAsync { get; }
|
||||
|
||||
/// <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>
|
||||
bool AllowDowngrade { set; }
|
||||
|
||||
Task<bool> IsAllowDowngradeEnabledAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// For test only.
|
||||
/// </summary>
|
||||
Task<string> GetUpdateConfigPathAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The current application version
|
||||
/// </summary>
|
||||
Task<SemVer> GetCurrentVersionAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the update channel. Not applicable for GitHub.
|
||||
/// Doesn’t return channel from the update configuration, only if was previously set.
|
||||
/// </summary>
|
||||
Task<string> GetChannelAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The request headers.
|
||||
/// </summary>
|
||||
Task<Dictionary<string, string>> GetRequestHeadersAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The request headers.
|
||||
/// </summary>
|
||||
Dictionary<string, string> RequestHeaders { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is an error while updating.
|
||||
/// </summary>
|
||||
event Action<string> OnError;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when checking if an update has started.
|
||||
/// </summary>
|
||||
event Action OnCheckingForUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is an available update.
|
||||
/// The update is downloaded automatically if AutoDownload is true.
|
||||
/// </summary>
|
||||
event Action<UpdateInfo> OnUpdateAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is no available update.
|
||||
/// </summary>
|
||||
event Action<UpdateInfo> OnUpdateNotAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download progress.
|
||||
/// </summary>
|
||||
event Action<ProgressInfo> OnDownloadProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download complete.
|
||||
/// </summary>
|
||||
event Action<UpdateInfo> OnUpdateDownloaded;
|
||||
|
||||
/// <summary>
|
||||
/// Asks the server whether there is an update.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<UpdateCheckResult> CheckForUpdatesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asks the server whether there is an update.
|
||||
///
|
||||
/// This will immediately download an update, then install when the app quits.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<UpdateCheckResult> CheckForUpdatesAndNotifyAsync();
|
||||
|
||||
/// <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>
|
||||
void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false);
|
||||
|
||||
/// <summary>
|
||||
/// Start downloading update manually. You can use this method if "AutoDownload" option is set to "false".
|
||||
/// </summary>
|
||||
/// <returns>Path to downloaded file.</returns>
|
||||
Task<string> DownloadUpdateAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Feed URL.
|
||||
/// </summary>
|
||||
/// <returns>Feed URL.</returns>
|
||||
Task<string> GetFeedURLAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Perform copy and paste operations on the system clipboard.
|
||||
/// </summary>
|
||||
public interface IClipboard
|
||||
{
|
||||
/// <summary>
|
||||
/// Read the content in the clipboard as plain text.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>The content in the clipboard as plain text.</returns>
|
||||
Task<string> ReadTextAsync(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text into the clipboard as plain text.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="type"></param>
|
||||
void WriteText(string text, string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// The content in the clipboard as markup.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> ReadHTMLAsync(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Writes markup to the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="markup"></param>
|
||||
/// <param name="type"></param>
|
||||
void WriteHTML(string markup, string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// The content in the clipboard as RTF.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> ReadRTFAsync(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text into the clipboard in RTF.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="type"></param>
|
||||
void WriteRTF(string text, string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Returns an Object containing title and url keys representing
|
||||
/// the bookmark in the clipboard. The title and url values will
|
||||
/// be empty strings when the bookmark is unavailable.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<ReadBookmark> ReadBookmarkAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Writes the title and url into the clipboard as a bookmark.
|
||||
///
|
||||
/// Note: Most apps on Windows don’t support pasting bookmarks
|
||||
/// into them so you can use clipboard.write to write both a
|
||||
/// bookmark and fallback text to the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="type"></param>
|
||||
void WriteBookmark(string title, string url, string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// macOS: The text on the find pasteboard. This method uses synchronous IPC
|
||||
/// when called from the renderer process. The cached value is reread from the
|
||||
/// find pasteboard whenever the application is activated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<string> ReadFindTextAsync();
|
||||
|
||||
/// <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>
|
||||
void WriteFindText(string text);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the clipboard content.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
void Clear(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// An array of supported formats for the clipboard type.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task<string[]> AvailableFormatsAsync(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="type"></param>
|
||||
void Write(Data data, string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Reads an image from the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task<NativeImage> ReadImageAsync(string type = "");
|
||||
|
||||
/// <summary>
|
||||
/// Writes an image to the clipboard.
|
||||
/// </summary>
|
||||
/// <param name="image"></param>
|
||||
/// <param name="type"></param>
|
||||
void WriteImage(NativeImage image, string type = "");
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Display native system dialogs for opening and saving files, alerting, etc.
|
||||
/// </summary>
|
||||
public interface IDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Note: On Windows and Linux an open dialog can not be both a file selector
|
||||
/// and a directory selector, so if you set properties to ['openFile', 'openDirectory']
|
||||
/// on these platforms, a directory selector will be shown.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.</param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns>An array of file paths chosen by the user</returns>
|
||||
Task<string[]> ShowOpenDialogAsync(BrowserWindow browserWindow, OpenDialogOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Dialog for save files.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.</param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns>Returns String, the path of the file chosen by the user, if a callback is provided it returns an empty string.</returns>
|
||||
Task<string> ShowSaveDialogAsync(BrowserWindow browserWindow, SaveDialogOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Shows a message box, it will block the process until the message box is closed.
|
||||
/// It returns the index of the clicked button. The browserWindow argument allows
|
||||
/// the dialog to attach itself to a parent window, making it modal. If a callback
|
||||
/// is passed, the dialog will not block the process.The API call will be
|
||||
/// asynchronous and the result will be passed via callback(response).
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
|
||||
Task<MessageBoxResult> ShowMessageBoxAsync(string message);
|
||||
|
||||
/// <summary>
|
||||
/// Shows a message box, it will block the process until the message box is closed.
|
||||
/// It returns the index of the clicked button. The browserWindow argument allows
|
||||
/// the dialog to attach itself to a parent window, making it modal. If a callback
|
||||
/// is passed, the dialog will not block the process.The API call will be
|
||||
/// asynchronous and the result will be passed via callback(response).
|
||||
/// </summary>
|
||||
/// <param name="messageBoxOptions"></param>
|
||||
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
|
||||
Task<MessageBoxResult> ShowMessageBoxAsync(MessageBoxOptions messageBoxOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Shows a message box, it will block the process until the message box is closed.
|
||||
/// It returns the index of the clicked button. If a callback
|
||||
/// is passed, the dialog will not block the process.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.</param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
|
||||
Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Shows a message box, it will block the process until the message box is closed.
|
||||
/// It returns the index of the clicked button. If a callback
|
||||
/// is passed, the dialog will not block the process.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browserWindow argument allows the dialog to attach itself to a parent window, making it modal.</param>
|
||||
/// <param name="messageBoxOptions"></param>
|
||||
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
|
||||
Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Displays a modal dialog that shows an error message.
|
||||
///
|
||||
/// This API can be called safely before the ready event the app module emits,
|
||||
/// it is usually used to report errors in early stage of startup.If called
|
||||
/// before the app readyevent on Linux, the message will be emitted to stderr,
|
||||
/// and no GUI dialog will appear.
|
||||
/// </summary>
|
||||
/// <param name="title">The title to display in the error box.</param>
|
||||
/// <param name="content">The text content to display in the error box.</param>
|
||||
void ShowErrorBox(string title, string content);
|
||||
|
||||
/// <summary>
|
||||
/// On macOS, this displays a modal dialog that shows a message and certificate information,
|
||||
/// and gives the user the option of trusting/importing the certificate. If you provide a
|
||||
/// browserWindow argument the dialog will be attached to the parent window, making it modal.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
Task ShowCertificateTrustDialogAsync(CertificateTrustDialogOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// On macOS, this displays a modal dialog that shows a message and certificate information,
|
||||
/// and gives the user the option of trusting/importing the certificate. If you provide a
|
||||
/// browserWindow argument the dialog will be attached to the parent window, making it modal.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
Task ShowCertificateTrustDialogAsync(BrowserWindow browserWindow, CertificateTrustDialogOptions options);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Control your app in the macOS dock.
|
||||
/// </summary>
|
||||
public interface IDock
|
||||
{
|
||||
/// <summary>
|
||||
/// When <see cref="DockBounceType.Critical"/> is passed, the dock icon will bounce until either the application becomes
|
||||
/// active or the request is canceled. When <see cref="DockBounceType.Informational"/> is passed, the dock icon will bounce
|
||||
/// for one second. However, the request remains active until either the application becomes active or the request is canceled.
|
||||
/// <para/>
|
||||
/// Note: This method can only be used while the app is not focused; when the app is focused it will return -1.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
Task<int> BounceAsync(DockBounceType type, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the bounce of id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the request.</param>
|
||||
void CancelBounce(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Bounces the Downloads stack if the filePath is inside the Downloads folder.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
void DownloadFinished(string filePath);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the string to be displayed in the dock’s badging area.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
void SetBadge(string text);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string to be displayed in the dock’s badging area.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The badge string of the dock.</returns>
|
||||
Task<string> GetBadgeAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Hides the dock icon.
|
||||
/// </summary>
|
||||
void Hide();
|
||||
|
||||
/// <summary>
|
||||
/// Shows the dock icon.
|
||||
/// </summary>
|
||||
void Show();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the dock icon is visible. The app.dock.show() call is asynchronous
|
||||
/// so this method might not return true immediately after that call.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Whether the dock icon is visible.</returns>
|
||||
Task<bool> IsVisibleAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dock menu items.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The menu items.
|
||||
/// </value>
|
||||
IReadOnlyCollection<MenuItem> MenuItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the application's dock menu.
|
||||
/// </summary>
|
||||
void SetMenu(MenuItem[] menuItems);
|
||||
|
||||
/// <summary>
|
||||
/// TODO: Menu (macOS) still to be implemented
|
||||
/// Gets the application's dock menu.
|
||||
/// </summary>
|
||||
Task<Menu> GetMenu(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image associated with this dock icon.
|
||||
/// </summary>
|
||||
/// <param name="image"></param>
|
||||
void SetIcon(string image);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Detect keyboard events when the application does not have keyboard focus.
|
||||
/// </summary>
|
||||
public interface IGlobalShortcut
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a global shortcut of accelerator.
|
||||
/// The callback is called when the registered shortcut is pressed by the user.
|
||||
///
|
||||
/// When the accelerator is already taken by other applications, this call will
|
||||
/// silently fail.This behavior is intended by operating systems, since they don’t
|
||||
/// want applications to fight for global shortcuts.
|
||||
/// </summary>
|
||||
void Register(string accelerator, Action function);
|
||||
|
||||
/// <summary>
|
||||
/// When the accelerator is already taken by other applications,
|
||||
/// this call will still return false. This behavior is intended by operating systems,
|
||||
/// since they don’t want applications to fight for global shortcuts.
|
||||
/// </summary>
|
||||
/// <returns>Whether this application has registered accelerator.</returns>
|
||||
Task<bool> IsRegisteredAsync(string accelerator);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the global shortcut of accelerator.
|
||||
/// </summary>
|
||||
void Unregister(string accelerator);
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all of the global shortcuts.
|
||||
/// </summary>
|
||||
void UnregisterAll();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <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 interface IHostHook
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
void Call(string socketEventName, params dynamic[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Execute native JavaScript/TypeScript code.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Results from the executed host code.</typeparam>
|
||||
/// <param name="socketEventName">Socket name registered on the host.</param>
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
/// <returns></returns>
|
||||
Task<T> CallAsync<T>(string socketEventName, params dynamic[] arguments);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Communicate asynchronously from the main process to renderer processes.
|
||||
/// </summary>
|
||||
public interface IIpcMain
|
||||
{
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...).
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="listener">Callback Method.</param>
|
||||
void On(string channel, Action<object> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process synchronously via channel,
|
||||
/// you can also send arbitrary arguments.
|
||||
///
|
||||
/// Note: Sending a synchronous message will block the whole renderer process,
|
||||
/// unless you know what you are doing you should never use it.
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="listener"></param>
|
||||
void OnSync(string channel, Func<object, object> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a one time listener method for the event. This listener is invoked only
|
||||
/// the next time a message is sent to channel, after which it is removed.
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="listener">Callback Method.</param>
|
||||
void Once(string channel, Action<object> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Removes listeners of the specified channel.
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
void RemoveAllListeners(string channel);
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process asynchronously via channel, you can also send
|
||||
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
|
||||
/// no functions or prototype chain will be included. The renderer process handles it by
|
||||
/// listening for channel with ipcRenderer module.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">BrowserWindow with channel.</param>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="data">Arguments data.</param>
|
||||
void Send(BrowserWindow browserWindow, string channel, params object[] data);
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the BrowserView renderer process asynchronously via channel, you can also send
|
||||
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
|
||||
/// no functions or prototype chain will be included. The renderer process handles it by
|
||||
/// listening for channel with ipcRenderer module.
|
||||
/// </summary>
|
||||
/// <param name="browserView">BrowserView with channel.</param>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="data">Arguments data.</param>
|
||||
void Send(BrowserView browserView, string channel, params object[] data);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Create native application menus and context menus.
|
||||
/// </summary>
|
||||
public interface IMenu
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the menu items.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The menu items.
|
||||
/// </value>
|
||||
IReadOnlyCollection<MenuItem> MenuItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the context menu items.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The context menu items.
|
||||
/// </value>
|
||||
IReadOnlyDictionary<int, ReadOnlyCollection<MenuItem>> ContextMenuItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the application menu.
|
||||
/// </summary>
|
||||
/// <param name="menuItems">The menu items.</param>
|
||||
void SetApplicationMenu(MenuItem[] menuItems);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the context menu.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browser window.</param>
|
||||
/// <param name="menuItems">The menu items.</param>
|
||||
void SetContextMenu(BrowserWindow browserWindow, MenuItem[] menuItems);
|
||||
|
||||
/// <summary>
|
||||
/// Contexts the menu popup.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">The browser window.</param>
|
||||
void ContextMenuPopup(BrowserWindow browserWindow);
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Read and respond to changes in Chromium's native color theme.
|
||||
/// </summary>
|
||||
public interface INativeTheme
|
||||
{
|
||||
/// <summary>
|
||||
/// Setting this property to <see cref="ThemeSourceMode.System"/> will remove the override and everything will be reset to the OS default. By default 'ThemeSource' is <see cref="ThemeSourceMode.System"/>.
|
||||
/// <para/>
|
||||
/// Settings this property to <see cref="ThemeSourceMode.Dark"/> will have the following effects:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="true"/> when accessed</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the dark UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the dark UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'prefers-color-scheme' CSS query will match 'dark' mode.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para/>
|
||||
/// Settings this property to <see cref="ThemeSourceMode.Light"/> will have the following effects:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description><see cref="ShouldUseDarkColorsAsync"/> will be <see langword="false"/> when accessed</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the light UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Any UI the OS renders on macOS including menus, window frames, etc. will use the light UI.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'prefers-color-scheme' CSS query will match 'light' mode.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// The usage of this property should align with a classic "dark mode" state machine in your application where the user has three options.
|
||||
/// <para/>
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description>Follow OS: SetThemeSource(ThemeSourceMode.System);</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Dark Mode: SetThemeSource(ThemeSourceMode.Dark);</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Light Mode: SetThemeSource(ThemeSourceMode.Light);</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// Your application should then always use <see cref="ShouldUseDarkColorsAsync"/> to determine what CSS to apply.
|
||||
/// </summary>
|
||||
/// <param name="themeSourceMode">The new ThemeSource.</param>
|
||||
void SetThemeSource(ThemeSourceMode themeSourceMode);
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ThemeSourceMode"/> property that can be <see cref="ThemeSourceMode.System"/>, <see cref="ThemeSourceMode.Light"/> or <see cref="ThemeSourceMode.Dark"/>. It is used to override (<seealso cref="SetThemeSource"/>) and
|
||||
/// supercede the value that Chromium has chosen to use internally.
|
||||
/// </summary>
|
||||
Task<ThemeSourceMode> GetThemeSourceAsync();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has a dark mode enabled or is
|
||||
/// being instructed to show a dark-style UI. If you want to modify this value you
|
||||
/// should use <see cref="SetThemeSource"/>.
|
||||
/// </summary>
|
||||
Task<bool> ShouldUseDarkColorsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has high-contrast mode enabled or is
|
||||
/// being instructed to show a high-contrast UI.
|
||||
/// </summary>
|
||||
Task<bool> ShouldUseHighContrastColorsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="bool"/> for if the OS / Chromium currently has an inverted color scheme or is
|
||||
/// being instructed to use an inverted color scheme.
|
||||
/// </summary>
|
||||
Task<bool> ShouldUseInvertedColorSchemeAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of <see cref="ShouldUseDarkColorsAsync"/>,
|
||||
/// <see cref="ShouldUseHighContrastColorsAsync"/> or <see cref="ShouldUseInvertedColorSchemeAsync"/> has changed. You will have to check them to determine which one has changed.
|
||||
/// </summary>
|
||||
event Action Updated;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
public interface INotification
|
||||
{
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
/// <param name="notificationOptions"></param>
|
||||
void Show(NotificationOptions notificationOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not desktop notifications are supported on the current system.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<bool> IsSupportedAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Monitor power state changes..
|
||||
/// </summary>
|
||||
public interface IPowerMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to lock the screen.
|
||||
/// </summary>
|
||||
event Action OnLockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to unlock the screen.
|
||||
/// </summary>
|
||||
event Action OnUnLockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is suspending.
|
||||
/// </summary>
|
||||
event Action OnSuspend;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system is resuming.
|
||||
/// </summary>
|
||||
event Action OnResume;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system changes to AC power.
|
||||
/// </summary>
|
||||
event Action OnAC;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system changes to battery power.
|
||||
/// </summary>
|
||||
event Action OnBattery;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to reboot or shut down. If the event handler
|
||||
/// invokes `e.preventDefault()`, Electron will attempt to delay system shutdown in
|
||||
/// order for the app to exit cleanly.If `e.preventDefault()` is called, the app
|
||||
/// should exit as soon as possible by calling something like `app.quit()`.
|
||||
/// </summary>
|
||||
event Action OnShutdown;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve information about screen size, displays, cursor position, etc.
|
||||
/// </summary>
|
||||
public interface IScreen
|
||||
{
|
||||
/// <summary>
|
||||
/// Emitted when an new Display has been added.
|
||||
/// </summary>
|
||||
event Action<Display> OnDisplayAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when oldDisplay has been removed.
|
||||
/// </summary>
|
||||
event Action<Display> OnDisplayRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when one or more metrics change in a display.
|
||||
/// The changedMetrics is an array of strings that describe the changes.
|
||||
/// Possible changes are bounds, workArea, scaleFactor and rotation.
|
||||
/// </summary>
|
||||
event Action<Display, string[]> OnDisplayMetricsChanged;
|
||||
|
||||
/// <summary>
|
||||
/// The current absolute position of the mouse pointer.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<Point> GetCursorScreenPointAsync();
|
||||
|
||||
/// <summary>
|
||||
/// macOS: The height of the menu bar in pixels.
|
||||
/// </summary>
|
||||
/// <returns>The height of the menu bar in pixels.</returns>
|
||||
Task<int> GetMenuBarHeightAsync();
|
||||
|
||||
/// <summary>
|
||||
/// The primary display.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<Display> GetPrimaryDisplayAsync();
|
||||
|
||||
/// <summary>
|
||||
/// An array of displays that are currently available.
|
||||
/// </summary>
|
||||
/// <returns>An array of displays that are currently available.</returns>
|
||||
Task<Display[]> GetAllDisplaysAsync();
|
||||
|
||||
/// <summary>
|
||||
/// The display nearest the specified point.
|
||||
/// </summary>
|
||||
/// <returns>The display nearest the specified point.</returns>
|
||||
Task<Display> GetDisplayNearestPointAsync(Point point);
|
||||
|
||||
/// <summary>
|
||||
/// The display that most closely intersects the provided bounds.
|
||||
/// </summary>
|
||||
/// <param name="rectangle"></param>
|
||||
/// <returns>The display that most closely intersects the provided bounds.</returns>
|
||||
Task<Display> GetDisplayMatchingAsync(Rectangle rectangle);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage files and URLs using their default applications.
|
||||
/// </summary>
|
||||
public interface IShell
|
||||
{
|
||||
/// <summary>
|
||||
/// Show the given file in a file manager. If possible, select the file.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path to the directory / file.</param>
|
||||
Task ShowItemInFolderAsync(string fullPath);
|
||||
|
||||
/// <summary>
|
||||
/// Open the given file in the desktop's default manner.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the directory / file.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
Task<string> OpenPathAsync(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Open the given external protocol URL in the desktop’s default manner.
|
||||
/// (For example, mailto: URLs in the user’s default mail agent).
|
||||
/// </summary>
|
||||
/// <param name="url">Max 2081 characters on windows.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
Task<string> OpenExternalAsync(string url);
|
||||
|
||||
/// <summary>
|
||||
/// Open the given external protocol URL in the desktop’s default manner.
|
||||
/// (For example, mailto: URLs in the user’s default mail agent).
|
||||
/// </summary>
|
||||
/// <param name="url">Max 2081 characters on windows.</param>
|
||||
/// <param name="options">Controls the behavior of OpenExternal.</param>
|
||||
/// <returns>The error message corresponding to the failure if a failure occurred, otherwise <see cref="string.Empty"/>.</returns>
|
||||
Task<string> OpenExternalAsync(string url, OpenExternalOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Move the given file to trash and returns a <see cref="bool"/> status for the operation.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path to the directory / file.</param>
|
||||
/// <returns> Whether the item was successfully moved to the trash.</returns>
|
||||
Task<bool> TrashItemAsync(string fullPath);
|
||||
|
||||
/// <summary>
|
||||
/// Play the beep sound.
|
||||
/// </summary>
|
||||
void Beep();
|
||||
|
||||
/// <summary>
|
||||
/// Creates or updates a shortcut link at shortcutPath.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The path to the shortcut.</param>
|
||||
/// <param name="operation">Default is <see cref="ShortcutLinkOperation.Create"/></param>
|
||||
/// <param name="options">Structure of a shortcut.</param>
|
||||
/// <returns>Whether the shortcut was created successfully.</returns>
|
||||
Task<bool> WriteShortcutLinkAsync(string shortcutPath, ShortcutLinkOperation operation, ShortcutDetails options);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the shortcut link at shortcutPath.
|
||||
/// An exception will be thrown when any error happens.
|
||||
/// </summary>
|
||||
/// <param name="shortcutPath">The path tot the shortcut.</param>
|
||||
/// <returns><see cref="ShortcutDetails"/> of the shortcut.</returns>
|
||||
Task<ShortcutDetails> ReadShortcutLinkAsync(string shortcutPath);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Add icons and context menus to the system's notification area.
|
||||
/// </summary>
|
||||
public interface ITray
|
||||
{
|
||||
/// <summary>
|
||||
/// Emitted when the tray icon is clicked.
|
||||
/// </summary>
|
||||
event Action<TrayClickEventArgs, Rectangle> OnClick;
|
||||
|
||||
/// <summary>
|
||||
/// macOS, Windows: Emitted when the tray icon is right clicked.
|
||||
/// </summary>
|
||||
event Action<TrayClickEventArgs, Rectangle> OnRightClick;
|
||||
|
||||
/// <summary>
|
||||
/// macOS, Windows: Emitted when the tray icon is double clicked.
|
||||
/// </summary>
|
||||
event Action<TrayClickEventArgs, Rectangle> OnDoubleClick;
|
||||
|
||||
/// <summary>
|
||||
/// Windows: Emitted when the tray balloon shows.
|
||||
/// </summary>
|
||||
event Action OnBalloonShow;
|
||||
|
||||
/// <summary>
|
||||
/// Windows: Emitted when the tray balloon is clicked.
|
||||
/// </summary>
|
||||
event Action OnBalloonClick;
|
||||
|
||||
/// <summary>
|
||||
/// Windows: Emitted when the tray balloon is closed
|
||||
/// because of timeout or user manually closes it.
|
||||
/// </summary>
|
||||
event Action OnBalloonClosed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the menu items.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The menu items.
|
||||
/// </value>
|
||||
IReadOnlyCollection<MenuItem> MenuItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Shows the Traybar.
|
||||
/// </summary>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="menuItem">The menu item.</param>
|
||||
void Show(string image, MenuItem menuItem);
|
||||
|
||||
/// <summary>
|
||||
/// Shows the Traybar.
|
||||
/// </summary>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="menuItems">The menu items.</param>
|
||||
void Show(string image, MenuItem[] menuItems);
|
||||
|
||||
/// <summary>
|
||||
/// Shows the Traybar (empty).
|
||||
/// </summary>
|
||||
/// <param name="image">The image.</param>
|
||||
void Show(string image);
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the tray icon immediately.
|
||||
/// </summary>
|
||||
void Destroy();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image associated with this tray icon.
|
||||
/// </summary>
|
||||
/// <param name="image"></param>
|
||||
void SetImage(string image);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the image associated with this tray icon when pressed on macOS.
|
||||
/// </summary>
|
||||
/// <param name="image"></param>
|
||||
void SetPressedImage(string image);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the hover text for this tray icon.
|
||||
/// </summary>
|
||||
/// <param name="toolTip"></param>
|
||||
void SetToolTip(string toolTip);
|
||||
|
||||
/// <summary>
|
||||
/// macOS: Sets the title displayed aside of the tray icon in the status bar.
|
||||
/// </summary>
|
||||
/// <param name="title"></param>
|
||||
void SetTitle(string title);
|
||||
|
||||
/// <summary>
|
||||
/// Windows: Displays a tray balloon.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
void DisplayBalloon(DisplayBalloonOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the tray icon is destroyed.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<bool> IsDestroyedAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="Tray"/> module.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void On(string eventName, Action fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="Tray"/> module.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void On(string eventName, Action<object> fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="Tray"/> module once.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void Once(string eventName, Action fn);
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to an unmapped event on the <see cref="Tray"/> module once.
|
||||
/// </summary>
|
||||
/// <param name="eventName">The event name</param>
|
||||
/// <param name="fn">The handler</param>
|
||||
void Once(string eventName, Action<object> fn);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
namespace ElectronNET.API.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage Browser Windows and Views
|
||||
/// </summary>
|
||||
public interface IWindowManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Quit when all windows are closed. (Default is true)
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [quit window all closed]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsQuitOnWindowAllClosed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser windows.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The browser windows.
|
||||
/// </value>
|
||||
IReadOnlyCollection<BrowserWindow> BrowserWindows { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser views.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The browser view.
|
||||
/// </value>
|
||||
IReadOnlyCollection<BrowserView> BrowserViews { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates the window asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="loadUrl">The load URL.</param>
|
||||
/// <returns></returns>
|
||||
Task<BrowserWindow> CreateWindowAsync(string loadUrl = "http://localhost");
|
||||
|
||||
/// <summary>
|
||||
/// Creates the window asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="loadUrl">The load URL.</param>
|
||||
/// <returns></returns>
|
||||
Task<BrowserWindow> CreateWindowAsync(BrowserWindowOptions options, string loadUrl = "http://localhost");
|
||||
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<BrowserView> CreateBrowserViewAsync();
|
||||
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
Task<BrowserView> CreateBrowserViewAsync(BrowserViewConstructorOptions options);
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ElectronNET.API.Interfaces;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Communicate asynchronously from the main process to renderer processes.
|
||||
/// </summary>
|
||||
public sealed class IpcMain : IIpcMain
|
||||
{
|
||||
private static IpcMain _ipcMain;
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
internal IpcMain() { }
|
||||
|
||||
internal static IpcMain Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_ipcMain == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if(_ipcMain == null)
|
||||
{
|
||||
_ipcMain = new IpcMain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _ipcMain;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsConnected => BridgeConnector.IsConnected;
|
||||
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...).
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="listener">Callback Method.</param>
|
||||
public void On(string channel, Action<object> listener)
|
||||
{
|
||||
BridgeConnector.Emit("registerIpcMainChannel", channel);
|
||||
BridgeConnector.Off(channel);
|
||||
BridgeConnector.On<object[]>(channel, (args) =>
|
||||
{
|
||||
var objectArray = FormatArguments(args);
|
||||
|
||||
if (objectArray.Count == 1)
|
||||
{
|
||||
listener(objectArray.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
listener(objectArray);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...). This listner will keep the window event sender id
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="listener">Callback Method.</param>
|
||||
public void OnWithId(string channel, Action<(int browserId, int webContentId, object arguments)> listener)
|
||||
{
|
||||
BridgeConnector.Emit("registerIpcMainChannelWithId", channel);
|
||||
BridgeConnector.Off(channel);
|
||||
BridgeConnector.On<ArgsAndIds>(channel, (data) =>
|
||||
{
|
||||
var objectArray = FormatArguments(data.args);
|
||||
|
||||
if (objectArray.Count == 1)
|
||||
{
|
||||
listener((data.id, data.wcId, objectArray.First()));
|
||||
}
|
||||
else
|
||||
{
|
||||
listener((data.id, data.wcId, objectArray));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ArgsAndIds
|
||||
{
|
||||
public int id { get; set; }
|
||||
public int wcId { get; set; }
|
||||
public object[] args { get; set; }
|
||||
}
|
||||
|
||||
private List<object> FormatArguments(object[] objectArray)
|
||||
{
|
||||
return objectArray.Where(o => o is object).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process synchronously via channel,
|
||||
/// you can also send arbitrary arguments.
|
||||
///
|
||||
/// Note: Sending a synchronous message will block the whole renderer process,
|
||||
/// unless you know what you are doing you should never use it.
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="listener"></param>
|
||||
public void OnSync(string channel, Func<object, object> listener)
|
||||
{
|
||||
BridgeConnector.Emit("registerSyncIpcMainChannel", channel);
|
||||
BridgeConnector.On<object[]>(channel, (args) => {
|
||||
var objectArray = FormatArguments(args);
|
||||
object parameter;
|
||||
if (objectArray.Count == 1)
|
||||
{
|
||||
parameter = objectArray.First();
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = objectArray;
|
||||
}
|
||||
|
||||
var result = listener(parameter);
|
||||
BridgeConnector.Emit(channel + "Sync", result);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a one time listener method for the event. This listener is invoked only
|
||||
/// the next time a message is sent to channel, after which it is removed.
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="listener">Callback Method.</param>
|
||||
public void Once(string channel, Action<object> listener)
|
||||
{
|
||||
BridgeConnector.Emit("registerOnceIpcMainChannel", channel);
|
||||
BridgeConnector.Once<object[]>(channel, (args) =>
|
||||
{
|
||||
var objectArray = FormatArguments(args);
|
||||
|
||||
if (objectArray.Count == 1)
|
||||
{
|
||||
listener(objectArray.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
listener(objectArray);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes listeners of the specified channel.
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
public void RemoveAllListeners(string channel)
|
||||
{
|
||||
BridgeConnector.Emit("removeAllListenersIpcMainChannel", channel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process asynchronously via channel, you can also send
|
||||
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
|
||||
/// no functions or prototype chain will be included. The renderer process handles it by
|
||||
/// listening for channel with ipcRenderer module.
|
||||
/// </summary>
|
||||
/// <param name="browserWindow">BrowserWindow with channel.</param>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="data">Arguments data.</param>
|
||||
public void Send(BrowserWindow browserWindow, string channel, params object[] data)
|
||||
{
|
||||
var objectsWithCorrectSerialization = new List<object>
|
||||
{
|
||||
browserWindow.Id,
|
||||
channel
|
||||
};
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
|
||||
{
|
||||
objectsWithCorrectSerialization.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
}
|
||||
else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
{
|
||||
objectsWithCorrectSerialization.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
}
|
||||
else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
{
|
||||
objectsWithCorrectSerialization.Add(parameterObject);
|
||||
}
|
||||
}
|
||||
|
||||
BridgeConnector.Emit("sendToIpcRenderer", objectsWithCorrectSerialization.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the BrowserView renderer process asynchronously via channel, you can also send
|
||||
/// arbitrary arguments. Arguments will be serialized in JSON internally and hence
|
||||
/// no functions or prototype chain will be included. The renderer process handles it by
|
||||
/// listening for channel with ipcRenderer module.
|
||||
/// </summary>
|
||||
/// <param name="browserView">BrowserView with channel.</param>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
/// <param name="data">Arguments data.</param>
|
||||
public void Send(BrowserView browserView, string channel, params object[] data)
|
||||
{
|
||||
List<JObject> jobjects = new();
|
||||
List<JArray> jarrays = new();
|
||||
List<object> objects = new();
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
|
||||
{
|
||||
jarrays.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
{
|
||||
jobjects.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
{
|
||||
objects.Add(parameterObject);
|
||||
}
|
||||
}
|
||||
|
||||
if(jobjects.Count > 0 || jarrays.Count > 0)
|
||||
{
|
||||
BridgeConnector.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, jarrays.ToArray(), jobjects.ToArray(), objects.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message to the console output pipe. This is used when running with "detachedProcess" : true on the electron.manifest.json,
|
||||
/// as in that case we can't open pipes to read the console output from the child process anymore
|
||||
/// </summary>
|
||||
/// <param name="text">Message to log</param>
|
||||
public static void ConsoleLog(string text)
|
||||
{
|
||||
BridgeConnector.Emit("console-stdout", text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message to the console error pipe. This is used when running with "detachedProcess" : true on the electron.manifest.json,
|
||||
/// as in that case we can't open pipes to read the console output from the child process anymore
|
||||
/// </summary>
|
||||
/// <param name="text">Message to log</param>
|
||||
|
||||
public static void ConsoleError(string text)
|
||||
{
|
||||
BridgeConnector.Emit("console-stderr", text);
|
||||
}
|
||||
|
||||
private readonly JsonSerializer _jsonSerializer = new()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class that reports if ASP.NET Core has fully started.
|
||||
/// </summary>
|
||||
internal class LifetimeServiceHost : IHostedService
|
||||
{
|
||||
public LifetimeServiceHost(IHostApplicationLifetime lifetime)
|
||||
{
|
||||
lifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
App.Instance.IsReady = true;
|
||||
|
||||
BridgeConnector.Log("ASP.NET Core host has fully started.");
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the application host is ready to start the service.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the application host is performing a graceful shutdown.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
internal class MenuResponse
|
||||
{
|
||||
public string id { get; set; }
|
||||
public int windowId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Interfaces;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
public sealed class Notification : INotification
|
||||
{
|
||||
private static Notification _notification;
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
internal Notification() { }
|
||||
|
||||
internal static Notification Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_notification == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_notification == null)
|
||||
{
|
||||
_notification = new Notification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _notification;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly List<NotificationOptions> _notificationOptions = new();
|
||||
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
/// <param name="notificationOptions"></param>
|
||||
public void Show(NotificationOptions notificationOptions)
|
||||
{
|
||||
GenerateIDsForDefinedActions(notificationOptions);
|
||||
|
||||
BridgeConnector.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer));
|
||||
}
|
||||
|
||||
private static void GenerateIDsForDefinedActions(NotificationOptions notificationOptions)
|
||||
{
|
||||
bool isActionDefined = false;
|
||||
|
||||
if (notificationOptions.OnShow != null)
|
||||
{
|
||||
notificationOptions.ShowID = Guid.NewGuid().ToString();
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Off("NotificationEventShow");
|
||||
BridgeConnector.On<string>("NotificationEventShow", (id) => {
|
||||
_notificationOptions.Single(x => x.ShowID == id).OnShow();
|
||||
});
|
||||
}
|
||||
|
||||
if (notificationOptions.OnClick != null)
|
||||
{
|
||||
notificationOptions.ClickID = Guid.NewGuid().ToString();
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Off("NotificationEventClick");
|
||||
BridgeConnector.On<string>("NotificationEventClick", (id) => {
|
||||
_notificationOptions.Single(x => x.ClickID == id).OnClick();
|
||||
});
|
||||
}
|
||||
|
||||
if (notificationOptions.OnClose != null)
|
||||
{
|
||||
notificationOptions.CloseID = Guid.NewGuid().ToString();
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Off("NotificationEventClose");
|
||||
BridgeConnector.On<string>("NotificationEventClose", (id) => {
|
||||
_notificationOptions.Single(x => x.CloseID == id.ToString()).OnClose();
|
||||
});
|
||||
}
|
||||
|
||||
if (notificationOptions.OnReply != null)
|
||||
{
|
||||
notificationOptions.ReplyID = Guid.NewGuid().ToString();
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Off("NotificationEventReply");
|
||||
BridgeConnector.On<string[]>("NotificationEventReply", (args) => {
|
||||
_notificationOptions.Single(x => x.ReplyID == args[0].ToString()).OnReply(args[1].ToString());
|
||||
});
|
||||
}
|
||||
|
||||
if (notificationOptions.OnAction != null)
|
||||
{
|
||||
notificationOptions.ActionID = Guid.NewGuid().ToString();
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Off("NotificationEventAction");
|
||||
BridgeConnector.On<string[]>("NotificationEventAction", (args) => {
|
||||
_notificationOptions.Single(x => x.ReplyID == args[0].ToString()).OnAction(args[1].ToString());
|
||||
});
|
||||
}
|
||||
|
||||
if (isActionDefined)
|
||||
{
|
||||
_notificationOptions.Add(notificationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not desktop notifications are supported on the current system.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<bool> IsSupportedAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
BridgeConnector.On<bool>("notificationIsSupportedComplete", (isSupported) =>
|
||||
{
|
||||
BridgeConnector.Off("notificationIsSupportedComplete");
|
||||
taskCompletionSource.SetResult(isSupported);
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("notificationIsSupported");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private static readonly JsonSerializer _jsonSerializer = new()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Interfaces;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Monitor power state changes..
|
||||
/// </summary>
|
||||
public sealed class PowerMonitor : IPowerMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to lock the screen.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnLockScreen
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_lockScreen == null)
|
||||
{
|
||||
BridgeConnector.On("pm-lock-screen" , () =>
|
||||
{
|
||||
_lockScreen();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-lock-screen");
|
||||
}
|
||||
_lockScreen += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_lockScreen -= value;
|
||||
|
||||
if (_lockScreen == null)
|
||||
BridgeConnector.Off("pm-lock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _lockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to unlock the screen.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnUnLockScreen
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_unlockScreen == null)
|
||||
{
|
||||
BridgeConnector.On("pm-unlock-screen", () =>
|
||||
{
|
||||
_unlockScreen();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-unlock-screen");
|
||||
}
|
||||
_unlockScreen += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_unlockScreen -= value;
|
||||
|
||||
if (_unlockScreen == null)
|
||||
BridgeConnector.Off("pm-unlock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _unlockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is suspending.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnSuspend
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_suspend == null)
|
||||
{
|
||||
BridgeConnector.On("pm-suspend", () =>
|
||||
{
|
||||
_suspend();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-suspend");
|
||||
}
|
||||
_suspend += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_suspend -= value;
|
||||
|
||||
if (_suspend == null)
|
||||
BridgeConnector.Off("pm-suspend");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _suspend;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system is resuming.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnResume
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_resume == null)
|
||||
{
|
||||
BridgeConnector.On("pm-resume", () =>
|
||||
{
|
||||
_resume();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-resume");
|
||||
}
|
||||
_resume += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_resume -= value;
|
||||
|
||||
if (_resume == null)
|
||||
BridgeConnector.Off("pm-resume");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _resume;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system changes to AC power.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnAC
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_onAC == null)
|
||||
{
|
||||
BridgeConnector.On("pm-on-ac", () =>
|
||||
{
|
||||
_onAC();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-on-ac");
|
||||
}
|
||||
_onAC += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_onAC -= value;
|
||||
|
||||
if (_onAC == null)
|
||||
BridgeConnector.Off("pm-on-ac");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _onAC;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system changes to battery power.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
public event Action OnBattery
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_onBattery == null)
|
||||
{
|
||||
BridgeConnector.On("pm-on-battery", () =>
|
||||
{
|
||||
_onBattery();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-on-battery");
|
||||
}
|
||||
_onBattery += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_onBattery -= value;
|
||||
|
||||
if (_onBattery == null)
|
||||
BridgeConnector.Off("pm-on-battery");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _onBattery;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to reboot or shut down. If the event handler
|
||||
/// invokes `e.preventDefault()`, Electron will attempt to delay system shutdown in
|
||||
/// order for the app to exit cleanly.If `e.preventDefault()` is called, the app
|
||||
/// should exit as soon as possible by calling something like `app.quit()`.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("linux")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
|
||||
public event Action OnShutdown
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_shutdown == null)
|
||||
{
|
||||
BridgeConnector.On("pm-shutdown", () =>
|
||||
{
|
||||
_shutdown();
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("register-pm-shutdown");
|
||||
}
|
||||
_shutdown += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_shutdown -= value;
|
||||
|
||||
if (_shutdown == null)
|
||||
BridgeConnector.Off("pm-on-shutdown");
|
||||
}
|
||||
}
|
||||
|
||||
private event Action _shutdown;
|
||||
|
||||
private static PowerMonitor _powerMonitor;
|
||||
private static readonly object _syncRoot = new();
|
||||
|
||||
internal PowerMonitor() { }
|
||||
|
||||
internal static PowerMonitor Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_powerMonitor == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_powerMonitor == null)
|
||||
{
|
||||
_powerMonitor = new PowerMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _powerMonitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
internal class ProcessHelper
|
||||
{
|
||||
public static void Execute(string command, string workingDirectoryPath)
|
||||
{
|
||||
using (Process cmd = new Process())
|
||||
{
|
||||
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
if (isWindows)
|
||||
{
|
||||
cmd.StartInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// works for OSX and Linux (at least on Ubuntu)
|
||||
var escapedArgs = command.Replace("\"", "\\\"");
|
||||
cmd.StartInfo = new ProcessStartInfo("bash", $"-c \"{escapedArgs}\"");
|
||||
}
|
||||
|
||||
cmd.StartInfo.RedirectStandardInput = false;
|
||||
cmd.StartInfo.RedirectStandardOutput = false;
|
||||
cmd.StartInfo.RedirectStandardError = false;
|
||||
cmd.StartInfo.CreateNoWindow = true;
|
||||
cmd.StartInfo.UseShellExecute = false;
|
||||
cmd.StartInfo.WorkingDirectory = workingDirectoryPath;
|
||||
cmd.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user