mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-02-17 13:45:34 +00:00
Compare commits
106 Commits
0.1.0-pre.
...
0.2.0-pre.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
@@ -7,24 +7,27 @@ env:
|
||||
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
# linux:
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
8.0.x
|
||||
# - name: Setup dotnet
|
||||
# uses: actions/setup-dotnet@v4
|
||||
# with:
|
||||
# dotnet-version: |
|
||||
# 6.0.x
|
||||
# 8.0.x
|
||||
# 10.0.x
|
||||
|
||||
- name: Build
|
||||
run: ./build.sh
|
||||
# - name: Build
|
||||
# run: ./build.sh
|
||||
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -35,6 +38,7 @@ jobs:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
8.0.x
|
||||
10.0.x
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
209
.github/workflows/integration-tests.yml
vendored
Normal file
209
.github/workflows/integration-tests.yml
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop, main ]
|
||||
pull_request:
|
||||
branches: [ develop, main ]
|
||||
|
||||
concurrency:
|
||||
group: integration-tests-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Integration Tests (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-24.04
|
||||
rid: linux-x64
|
||||
- os: windows-2022
|
||||
rid: win-x64
|
||||
- os: macos-14
|
||||
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: 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 }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --no-restore -c Release -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
|
||||
|
||||
- name: Install Linux GUI dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
set -e
|
||||
sudo apt-get update
|
||||
# Core Electron dependencies
|
||||
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 libasound2t64
|
||||
|
||||
- name: Run tests (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
mkdir -p test-results/Ubuntu
|
||||
xvfb-run -a dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj \
|
||||
-c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} \
|
||||
--logger "trx;LogFileName=Ubuntu.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/Windows | Out-Null
|
||||
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} --logger "trx;LogFileName=Windows.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/macOS
|
||||
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} --logger "trx;LogFileName=macOS.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 }}
|
||||
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 (keep suites; set filePath=OS)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p ctrf
|
||||
shopt -s globstar nullglob
|
||||
conv=0
|
||||
for trx in test-results/**/*.trx; do
|
||||
fname="$(basename "$trx")"
|
||||
os="${fname%.trx}"
|
||||
outdir="ctrf/${os}"
|
||||
mkdir -p "$outdir"
|
||||
out="${outdir}/ctrf-report.json"
|
||||
|
||||
dotnet tool run DotnetCtrfJsonReporter -p "$trx" -d "$outdir" -f "ctrf-report.json"
|
||||
|
||||
jq --arg os "$os" '.results.tests |= map(.filePath = $os)' "$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: Create PR Comment
|
||||
if: always()
|
||||
uses: ctrf-io/github-test-reporter@v1
|
||||
with:
|
||||
report-path: 'ctrf/**/*.json'
|
||||
|
||||
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 }}
|
||||
|
||||
- name: Summary
|
||||
run: echo "All matrix test jobs completed."
|
||||
85
.github/workflows/trailing-whitespace-check.yml
vendored
Normal file
85
.github/workflows/trailing-whitespace-check.yml
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
name: Trailing Whitespace Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
check-trailing-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
|
||||
@@ -1,23 +1,54 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/build",
|
||||
"title": "Build Schema",
|
||||
"definitions": {
|
||||
"build": {
|
||||
"type": "object",
|
||||
"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": {
|
||||
"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"
|
||||
]
|
||||
},
|
||||
"Continue": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates to continue a previously failed build attempt"
|
||||
@@ -27,25 +58,8 @@
|
||||
"description": "Shows the help text for this build assembly"
|
||||
},
|
||||
"Host": {
|
||||
"type": "string",
|
||||
"description": "Host for execution. Default is 'automatic'",
|
||||
"enum": [
|
||||
"AppVeyor",
|
||||
"AzurePipelines",
|
||||
"Bamboo",
|
||||
"Bitbucket",
|
||||
"Bitrise",
|
||||
"GitHubActions",
|
||||
"GitLab",
|
||||
"Jenkins",
|
||||
"Rider",
|
||||
"SpaceAutomation",
|
||||
"TeamCity",
|
||||
"Terminal",
|
||||
"TravisCI",
|
||||
"VisualStudio",
|
||||
"VSCode"
|
||||
]
|
||||
"$ref": "#/definitions/Host"
|
||||
},
|
||||
"NoLogo": {
|
||||
"type": "boolean",
|
||||
@@ -66,10 +80,6 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"ReleaseNotesFilePath": {
|
||||
"type": "string",
|
||||
"description": "ReleaseNotesFilePath - To determine the lates changelog version"
|
||||
},
|
||||
"Root": {
|
||||
"type": "string",
|
||||
"description": "Root directory during build execution"
|
||||
@@ -78,59 +88,50 @@
|
||||
"type": "array",
|
||||
"description": "List of targets to be skipped. Empty list skips all dependencies",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Clean",
|
||||
"Compile",
|
||||
"CreatePackages",
|
||||
"Default",
|
||||
"Package",
|
||||
"PrePublish",
|
||||
"Publish",
|
||||
"PublishPackages",
|
||||
"PublishPreRelease",
|
||||
"PublishRelease",
|
||||
"Restore",
|
||||
"RunUnitTests"
|
||||
]
|
||||
"$ref": "#/definitions/ExecutableTarget"
|
||||
}
|
||||
},
|
||||
"Solution": {
|
||||
"type": "string",
|
||||
"description": "Path to a solution file that is automatically loaded"
|
||||
},
|
||||
"Target": {
|
||||
"type": "array",
|
||||
"description": "List of targets to be invoked. Default is '{default_target}'",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Clean",
|
||||
"Compile",
|
||||
"CreatePackages",
|
||||
"Default",
|
||||
"Package",
|
||||
"PrePublish",
|
||||
"Publish",
|
||||
"PublishPackages",
|
||||
"PublishPreRelease",
|
||||
"PublishRelease",
|
||||
"Restore",
|
||||
"RunUnitTests"
|
||||
]
|
||||
"$ref": "#/definitions/ExecutableTarget"
|
||||
}
|
||||
},
|
||||
"Verbosity": {
|
||||
"type": "string",
|
||||
"description": "Logging verbosity during build execution. Default is 'Normal'",
|
||||
"enum": [
|
||||
"Minimal",
|
||||
"Normal",
|
||||
"Quiet",
|
||||
"Verbose"
|
||||
]
|
||||
"$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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
23
Changelog.md
23
Changelog.md
@@ -1,12 +1,35 @@
|
||||
# 0.2.0
|
||||
|
||||
## ElectronNET.Core
|
||||
|
||||
- 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
|
||||
|
||||
# 0.1.0
|
||||
|
||||
## ElectronNET.Core
|
||||
|
||||
- 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
|
||||
|
||||
# 0.0.18
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2024 Gregor Biswanger, Robert Mühsig
|
||||
Copyright (c) 2017-2025 Gregor Biswanger, Robert Mühsig, Florian Rappl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
78
README.md
78
README.md
@@ -58,22 +58,22 @@ To do so, use the `UseElectron` extension method on a `WebApplicationBuilder`, a
|
||||
using ElectronNET.API;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseElectron(args, ElectronAppReady)
|
||||
.UseStartup<Startup>()
|
||||
.Build()
|
||||
.Run();
|
||||
}
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseElectron(args, ElectronAppReady)
|
||||
.UseStartup<Startup>()
|
||||
.Build()
|
||||
.Run();
|
||||
}
|
||||
|
||||
public static async Task ElectronAppReady()
|
||||
{
|
||||
var browserWindow = await Electron.WindowManager.CreateWindowAsync(
|
||||
new BrowserWindowOptions { Show = false });
|
||||
public static async Task ElectronAppReady()
|
||||
{
|
||||
var browserWindow = await Electron.WindowManager.CreateWindowAsync(
|
||||
new BrowserWindowOptions { Show = false });
|
||||
|
||||
browserWindow.OnReadyToShow += () => browserWindow.Show();
|
||||
}
|
||||
browserWindow.OnReadyToShow += () => browserWindow.Show();
|
||||
}
|
||||
```
|
||||
|
||||
### Minimal API Example
|
||||
@@ -113,6 +113,56 @@ app.MapRazorPages();
|
||||
app.Run();
|
||||
```
|
||||
|
||||
### Blazor
|
||||
|
||||
For a project with Blazor you can use:
|
||||
|
||||
```cs
|
||||
using ElectronNET.API;
|
||||
using ElectronNET.API.Entities;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services
|
||||
.AddRazorComponents()
|
||||
.AddInteractiveWebAssemblyComponents();
|
||||
|
||||
builder.Services.AddElectron(); // <-- might be useful to set up DI
|
||||
|
||||
builder.UseElectron(args, async () =>
|
||||
{
|
||||
var options = new BrowserWindowOptions {
|
||||
Show = false,
|
||||
AutoHideMenuBar = true,
|
||||
IsRunningBlazor = true, // <-- crucial
|
||||
};
|
||||
var browserWindow = await Electron.WindowManager.CreateWindowAsync(options);
|
||||
browserWindow.OnReadyToShow += () => browserWindow.Show();
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseWebAssemblyDebugging();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapRazorComponents<BlazorApp.Components.App>()
|
||||
.AddInteractiveWebAssemblyRenderMode();
|
||||
|
||||
app.Run();
|
||||
```
|
||||
|
||||
The `IsRunningBlazor` option makes sure to set up the renderer in a way that Blazor can just run without any interference. This includes things such as HMR for development.
|
||||
|
||||
## 🚀 Starting and Debugging the Application
|
||||
|
||||
Just press `F5` in Visual Studio or use dotnet for debugging.
|
||||
|
||||
@@ -49,12 +49,12 @@ Add the Electron.NET configuration to your `.csproj` file:
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ElectronNET.Core" Version="1.0.0" />
|
||||
<PackageReference Include="ElectronNET.Core" Version="0.2.0" />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Add publish profiles to `Properties/PublishProfiles/`:
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>publish\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
@@ -48,7 +48,7 @@ Add publish profiles to `Properties/PublishProfiles/`:
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>publish\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
@@ -68,7 +68,7 @@ Add publish profiles to `Properties/PublishProfiles/`:
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>publish\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
@@ -89,7 +89,7 @@ Add publish profiles to `Properties/PublishProfiles/`:
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>publish\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.305",
|
||||
"version": "10.0.100",
|
||||
"rollForward": "feature",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Nuke.Common;
|
||||
using Nuke.Common.CI.GitHubActions;
|
||||
using Nuke.Common.IO;
|
||||
using Nuke.Common.ProjectModel;
|
||||
using Nuke.Common.Tooling;
|
||||
using Nuke.Common.Tools.DotNet;
|
||||
using Nuke.Common.Tools.GitHub;
|
||||
using Nuke.Common.Tools.NuGet;
|
||||
@@ -15,7 +16,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using static Nuke.Common.IO.FileSystemTasks;
|
||||
using static Nuke.Common.IO.PathConstruction;
|
||||
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
||||
// ReSharper disable ArrangeThisQualifier
|
||||
@@ -116,7 +116,7 @@ class Build : NukeBuild
|
||||
Target Restore => _ => _
|
||||
.Executes(() =>
|
||||
{
|
||||
DotNetRestore(s => s.SetProjectFile(Solution.Path));
|
||||
DotNetRestore(s => s.SetProjectFile(Solution));
|
||||
});
|
||||
|
||||
Target Compile => _ => _
|
||||
@@ -124,7 +124,7 @@ class Build : NukeBuild
|
||||
.Executes(() =>
|
||||
{
|
||||
DotNetBuild(s => s
|
||||
.SetProjectFile(Solution.Path)
|
||||
.SetProjectFile(Solution)
|
||||
.SetConfiguration(Configuration)
|
||||
.SetProperty("GeneratePackageOnBuild", "True")
|
||||
.SetProperty("VersionPostFix", VersionPostFix ?? string.Empty));
|
||||
@@ -134,18 +134,17 @@ class Build : NukeBuild
|
||||
.DependsOn(Compile)
|
||||
.Executes(() =>
|
||||
{
|
||||
// There aren't any yet
|
||||
});
|
||||
var TestProject = SourceDirectory / "ElectronNET.IntegrationTests" / "ElectronNET.IntegrationTests.csproj";
|
||||
|
||||
Target CreatePackages => _ => _
|
||||
.DependsOn(Compile)
|
||||
.Executes(() =>
|
||||
{
|
||||
// Packages are created on build
|
||||
DotNetTest(s => s
|
||||
.SetProjectFile(TestProject)
|
||||
.SetConfiguration(Configuration)
|
||||
.When(_ => GitHubActions.Instance is not null, x => x.SetLoggers("GitHubActions"))
|
||||
);
|
||||
});
|
||||
|
||||
Target PublishPackages => _ => _
|
||||
.DependsOn(CreatePackages)
|
||||
.DependsOn(Compile)
|
||||
.DependsOn(RunUnitTests)
|
||||
.Executes(() =>
|
||||
{
|
||||
@@ -240,7 +239,7 @@ class Build : NukeBuild
|
||||
|
||||
Target Package => _ => _
|
||||
.DependsOn(RunUnitTests)
|
||||
.DependsOn(CreatePackages);
|
||||
.DependsOn(Compile);
|
||||
|
||||
Target Default => _ => _
|
||||
.DependsOn(Package);
|
||||
|
||||
@@ -85,7 +85,7 @@ public sealed class ReleaseNotesParser
|
||||
|
||||
// Parse content.
|
||||
var notes = new List<string>();
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Sanity checks.
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nuke.Common" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Build" Version="17.11.48" />
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.11.48" />
|
||||
<PackageReference Include="Nuke.Common" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageDownload Include="NuGet.CommandLine" Version="[6.3.1]" />
|
||||
<PackageDownload Include="NuGet.CommandLine" Version="[6.12.2]" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
4
src/.editorconfig
Normal file
4
src/.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
[*.cs]
|
||||
|
||||
# CA1416: Validate platform compatibility
|
||||
dotnet_diagnostic.CA1416.severity = error
|
||||
375
src/ElectronNET.API/API/ApiBase.cs
Normal file
375
src/ElectronNET.API/API/ApiBase.cs
Normal file
@@ -0,0 +1,375 @@
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
using Common;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public abstract class ApiBase
|
||||
{
|
||||
protected enum SocketTaskEventNameTypes
|
||||
{
|
||||
DashesLowerFirst,
|
||||
NoDashUpperFirst
|
||||
}
|
||||
|
||||
protected enum SocketTaskMessageNameTypes
|
||||
{
|
||||
DashesLowerFirst,
|
||||
NoDashUpperFirst
|
||||
}
|
||||
|
||||
protected enum SocketEventNameTypes
|
||||
{
|
||||
DashedLower,
|
||||
CamelCase,
|
||||
}
|
||||
|
||||
private const int InvocationTimeout = 1000;
|
||||
|
||||
private readonly string objectName;
|
||||
private readonly ConcurrentDictionary<string, Invocator> invocators;
|
||||
private readonly ConcurrentDictionary<string, string> invocationEventNames = new();
|
||||
private readonly ConcurrentDictionary<string, string> invocationMessageNames = new();
|
||||
private readonly ConcurrentDictionary<string, string> methodMessageNames = new();
|
||||
private static readonly ConcurrentDictionary<string, EventContainer> eventContainers = new();
|
||||
private static readonly ConcurrentDictionary<string, ConcurrentDictionary<string, Invocator>> AllInvocators = new();
|
||||
|
||||
private readonly object objLock = new object();
|
||||
|
||||
public virtual int Id
|
||||
{
|
||||
get => -1;
|
||||
|
||||
// ReSharper disable once ValueParameterNotUsed
|
||||
protected set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract SocketTaskEventNameTypes SocketTaskEventNameType { get; }
|
||||
protected virtual SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.NoDashUpperFirst;
|
||||
protected virtual SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower;
|
||||
|
||||
protected ApiBase()
|
||||
{
|
||||
this.objectName = this.GetType().Name.LowerFirst();
|
||||
this.invocators = AllInvocators.GetOrAdd(this.objectName, _ => new ConcurrentDictionary<string, Invocator>());
|
||||
}
|
||||
|
||||
protected void CallMethod0([CallerMemberName] string callerName = null)
|
||||
{
|
||||
var messageName = this.methodMessageNames.GetOrAdd(callerName, s => this.objectName + s);
|
||||
if (this.Id >= 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, this.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CallMethod1(object val1, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
var messageName = this.methodMessageNames.GetOrAdd(callerName, s => this.objectName + s);
|
||||
if (this.Id >= 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, this.Id, val1);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, val1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CallMethod2(object val1, object val2, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
var messageName = this.methodMessageNames.GetOrAdd(callerName, s => this.objectName + s);
|
||||
if (this.Id >= 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, this.Id, val1, val2);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, val1, val2);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CallMethod3(object val1, object val2, object val3, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
var messageName = this.methodMessageNames.GetOrAdd(callerName, s => this.objectName + s);
|
||||
if (this.Id >= 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, this.Id, val1, val2, val3);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit(messageName, val1, val2, val3);
|
||||
}
|
||||
}
|
||||
|
||||
protected Task<T> InvokeAsync<T>(object arg = null, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
Debug.Assert(callerName != null, nameof(callerName) + " != null");
|
||||
|
||||
lock (this.objLock)
|
||||
{
|
||||
return this.invocators.GetOrAdd(callerName, _ =>
|
||||
{
|
||||
var getter = new Invocator<T>(this, callerName, InvocationTimeout, arg);
|
||||
|
||||
getter.Task<T>().ContinueWith(_ =>
|
||||
{
|
||||
lock (this.objLock)
|
||||
{
|
||||
return this.invocators.TryRemove(callerName, out var _);
|
||||
}
|
||||
});
|
||||
|
||||
return getter;
|
||||
}).Task<T>();
|
||||
}
|
||||
}
|
||||
|
||||
protected void AddEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
Debug.Assert(callerName != null, nameof(callerName) + " != null");
|
||||
var eventName = this.EventName(callerName);
|
||||
|
||||
var eventKey = this.EventKey(eventName, id);
|
||||
|
||||
lock (this.objLock)
|
||||
{
|
||||
var container = eventContainers.GetOrAdd(eventKey, _ =>
|
||||
{
|
||||
var container = new EventContainer();
|
||||
BridgeConnector.Socket.On(eventKey, container.OnEventAction);
|
||||
BridgeConnector.Socket.Emit($"register-{eventName}", id);
|
||||
return container;
|
||||
});
|
||||
|
||||
container.Register(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
Debug.Assert(callerName != null, nameof(callerName) + " != null");
|
||||
var eventName = this.EventName(callerName);
|
||||
var eventKey = this.EventKey(eventName, id);
|
||||
|
||||
lock (this.objLock)
|
||||
{
|
||||
if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value))
|
||||
{
|
||||
BridgeConnector.Socket.Off(eventKey);
|
||||
eventContainers.TryRemove(eventKey, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void AddEvent<T>(Action<T> value, int? id = null, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
Debug.Assert(callerName != null, nameof(callerName) + " != null");
|
||||
|
||||
var eventName = this.EventName(callerName);
|
||||
var eventKey = this.EventKey(eventName, id);
|
||||
|
||||
lock (this.objLock)
|
||||
{
|
||||
var container = eventContainers.GetOrAdd(eventKey, _ =>
|
||||
{
|
||||
var container = new EventContainer();
|
||||
BridgeConnector.Socket.On<T>(eventKey, container.OnEventActionT);
|
||||
BridgeConnector.Socket.Emit($"register-{eventName}", id);
|
||||
return container;
|
||||
});
|
||||
|
||||
container.Register(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveEvent<T>(Action<T> value, int? id = null, [CallerMemberName] string callerName = null)
|
||||
{
|
||||
Debug.Assert(callerName != null, nameof(callerName) + " != null");
|
||||
var eventName = this.EventName(callerName);
|
||||
var eventKey = this.EventKey(eventName, id);
|
||||
|
||||
lock (this.objLock)
|
||||
{
|
||||
if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value))
|
||||
{
|
||||
BridgeConnector.Socket.Off(eventKey);
|
||||
eventContainers.TryRemove(eventKey, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string EventName(string callerName)
|
||||
{
|
||||
switch (this.SocketEventNameType)
|
||||
{
|
||||
case SocketEventNameTypes.DashedLower:
|
||||
return $"{this.objectName}-{callerName.ToDashedEventName()}";
|
||||
case SocketEventNameTypes.CamelCase:
|
||||
return $"{this.objectName}-{callerName.ToCamelCaseEventName()}";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private string EventKey(string eventName, int? id)
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}{1:D}", eventName, id);
|
||||
}
|
||||
|
||||
internal abstract class Invocator
|
||||
{
|
||||
public abstract Task<T> Task<T>();
|
||||
}
|
||||
|
||||
internal class Invocator<T> : Invocator
|
||||
{
|
||||
private readonly Task<T> tcsTask;
|
||||
private TaskCompletionSource<T> tcs;
|
||||
|
||||
public Invocator(ApiBase apiBase, string callerName, int timeoutMs, object arg = null)
|
||||
{
|
||||
this.tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
this.tcsTask = this.tcs.Task;
|
||||
|
||||
string eventName;
|
||||
string messageName;
|
||||
|
||||
switch (apiBase.SocketTaskEventNameType)
|
||||
{
|
||||
case SocketTaskEventNameTypes.DashesLowerFirst:
|
||||
eventName = apiBase.invocationEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}-completed");
|
||||
break;
|
||||
case SocketTaskEventNameTypes.NoDashUpperFirst:
|
||||
eventName = apiBase.invocationEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}{s.StripAsync()}Completed");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
switch (apiBase.SocketTaskMessageNameType)
|
||||
{
|
||||
case SocketTaskMessageNameTypes.DashesLowerFirst:
|
||||
messageName = apiBase.invocationMessageNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}");
|
||||
break;
|
||||
case SocketTaskMessageNameTypes.NoDashUpperFirst:
|
||||
messageName = apiBase.invocationMessageNames.GetOrAdd(callerName, s => apiBase.objectName + s.StripAsync());
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Once<T>(eventName, (result) =>
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
var value = result;
|
||||
this.tcs?.SetResult(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.tcs?.TrySetException(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.tcs = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (arg != null)
|
||||
{
|
||||
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName);
|
||||
}
|
||||
|
||||
System.Threading.Tasks.Task.Delay(InvocationTimeout).ContinueWith(_ =>
|
||||
{
|
||||
if (this.tcs != null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (this.tcs != null)
|
||||
{
|
||||
var ex = new TimeoutException($"No response after {timeoutMs:D}ms trying to retrieve value {apiBase.objectName}.{callerName}()");
|
||||
this.tcs.TrySetException(ex);
|
||||
this.tcs = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override Task<T1> Task<T1>()
|
||||
{
|
||||
return this.tcsTask as Task<T1>;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentlySynchronizedField")]
|
||||
private class EventContainer
|
||||
{
|
||||
private Action eventAction;
|
||||
private Delegate eventActionT;
|
||||
|
||||
private Action<T> GetEventActionT<T>()
|
||||
{
|
||||
return (Action<T>)this.eventActionT;
|
||||
}
|
||||
|
||||
private void SetEventActionT<T>(Action<T> actionT)
|
||||
{
|
||||
this.eventActionT = actionT;
|
||||
}
|
||||
|
||||
public void OnEventAction() => this.eventAction?.Invoke();
|
||||
|
||||
public void OnEventActionT<T>(T p) => this.GetEventActionT<T>()?.Invoke(p);
|
||||
|
||||
public void Register(Action receiver)
|
||||
{
|
||||
this.eventAction += receiver;
|
||||
}
|
||||
|
||||
public void Register<T>(Action<T> receiver)
|
||||
{
|
||||
var actionT = this.GetEventActionT<T>();
|
||||
actionT += receiver;
|
||||
this.SetEventActionT(actionT);
|
||||
}
|
||||
|
||||
public bool Unregister(Action receiver)
|
||||
{
|
||||
this.eventAction -= receiver;
|
||||
return this.eventAction != null;
|
||||
}
|
||||
|
||||
public bool Unregister<T>(Action<T> receiver)
|
||||
{
|
||||
var actionT = this.GetEventActionT<T>();
|
||||
actionT -= receiver;
|
||||
this.SetEventActionT(actionT);
|
||||
|
||||
return actionT != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,8 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.Common;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -13,8 +10,12 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Enable apps to automatically update themselves. Based on electron-updater.
|
||||
/// </summary>
|
||||
public sealed class AutoUpdater
|
||||
public sealed class AutoUpdater : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to automatically download an update when it is found. (Default is true)
|
||||
/// </summary>
|
||||
@@ -22,20 +23,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-autoDownload-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-autoDownload-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoDownload-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<bool>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -52,20 +40,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-autoInstallOnAppQuit-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-autoInstallOnAppQuit-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<bool>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -74,7 +49,7 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.* Whether to allow update to pre-release versions.
|
||||
/// *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").
|
||||
@@ -83,20 +58,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-allowPrerelease-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-allowPrerelease-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<bool>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -105,27 +67,14 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// *GitHub provider only.*
|
||||
/// *GitHub provider only.*
|
||||
/// Get all release notes (from current version to latest), not just the latest (Default is false).
|
||||
/// </summary>
|
||||
public bool FullChangelog
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-fullChangelog-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-fullChangelog-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<bool>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -142,20 +91,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<bool>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-allowDowngrade-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-allowDowngrade-get-reply");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<bool>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -170,20 +106,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<string>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-updateConfigPath-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-updateConfigPath-get-reply");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdater-updateConfigPath-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<string>()).Result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,25 +117,12 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<SemVer>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<SemVer>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-currentVersion-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-currentVersion-get-reply");
|
||||
SemVer version = ((JObject)result).ToObject<SemVer>();
|
||||
taskCompletionSource.SetResult(version);
|
||||
});
|
||||
BridgeConnector.Socket.Emit("autoUpdater-currentVersion-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
});
|
||||
return Task.Run(() => this.InvokeAsync<SemVer>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the update channel. Not applicable for GitHub.
|
||||
/// Get the update channel. Not applicable for GitHub.
|
||||
/// Doesn’t return channel from the update configuration, only if was previously set.
|
||||
/// </summary>
|
||||
[Obsolete("Use the asynchronous version ChannelAsync instead")]
|
||||
@@ -225,29 +135,27 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the update channel. Not applicable for GitHub.
|
||||
/// 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> ChannelAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<string>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdater-channel-get-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-channel-get-reply");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
BridgeConnector.Socket.Emit("autoUpdater-channel-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
});
|
||||
return Task.Run(() => this.InvokeAsync<string>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the update channel. Not applicable for GitHub.
|
||||
/// </summary>
|
||||
public string SetChannel
|
||||
{
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-channel-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -257,18 +165,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Dictionary<string, string>>();
|
||||
BridgeConnector.Socket.On("autoUpdater-requestHeaders-get-reply", (headers) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdater-requestHeaders-get-reply");
|
||||
Dictionary<string, string> result = ((JObject)headers).ToObject<Dictionary<string, string>>();
|
||||
taskCompletionSource.SetResult(result);
|
||||
});
|
||||
BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-get");
|
||||
return taskCompletionSource.Task;
|
||||
});
|
||||
return Task.Run(() => this.InvokeAsync<Dictionary<string, string>>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +176,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-set", JObject.FromObject(value, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-set", value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,72 +185,62 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
public event Action<string> OnError
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-error", GetHashCode(), _error, value, (args) => args.ToString());
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-error", GetHashCode(), _error, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<string> _error;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when checking if an update has started.
|
||||
/// </summary>
|
||||
public event Action OnCheckingForUpdate
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-checking-for-update", GetHashCode(), _checkingForUpdate, value);
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-checking-for-update", GetHashCode(), _checkingForUpdate, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action _checkingForUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is an available update.
|
||||
/// Emitted when there is an available update.
|
||||
/// The update is downloaded automatically if AutoDownload is true.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateAvailable
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-update-available", GetHashCode(), _updateAvailable, value, (args) => JObject.Parse(args.ToString()).ToObject<UpdateInfo>());
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-update-available", GetHashCode(), _updateAvailable, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when there is no available update.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateNotAvailable
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-update-not-available", GetHashCode(), _updateNotAvailable, value, (args) => JObject.Parse(args.ToString()).ToObject<UpdateInfo>());
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-update-not-available", GetHashCode(), _updateNotAvailable, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateNotAvailable;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download progress.
|
||||
/// </summary>
|
||||
public event Action<ProgressInfo> OnDownloadProgress
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-download-progress", GetHashCode(), _downloadProgress, value, (args) => JObject.Parse(args.ToString()).ToObject<ProgressInfo>());
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-download-progress", GetHashCode(), _downloadProgress, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<ProgressInfo> _downloadProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted on download complete.
|
||||
/// </summary>
|
||||
public event Action<UpdateInfo> OnUpdateDownloaded
|
||||
{
|
||||
add => ApiEventManager.AddEvent("autoUpdater-update-downloaded", GetHashCode(), _updateDownloaded, value, (args) => JObject.Parse(args.ToString()).ToObject<UpdateInfo>());
|
||||
remove => ApiEventManager.RemoveEvent("autoUpdater-update-downloaded", GetHashCode(), _updateDownloaded, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<UpdateInfo> _updateDownloaded;
|
||||
|
||||
private static AutoUpdater _autoUpdater;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal AutoUpdater() { }
|
||||
internal AutoUpdater()
|
||||
{
|
||||
}
|
||||
|
||||
internal static AutoUpdater Instance
|
||||
{
|
||||
@@ -383,30 +270,27 @@ namespace ElectronNET.API
|
||||
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
|
||||
BridgeConnector.Socket.Once<UpdateCheckResult>("autoUpdater-checkForUpdates-completed" + guid, (result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
|
||||
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
|
||||
BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesError" + guid);
|
||||
taskCompletionSource.SetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
taskCompletionSource.SetException(ex);
|
||||
}
|
||||
});
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesError" + guid, (error) =>
|
||||
BridgeConnector.Socket.Once<string>("autoUpdater-checkForUpdatesError" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
|
||||
BridgeConnector.Socket.Off("autoUpdater-checkForUpdates-completed" + guid);
|
||||
string message = "An error occurred in CheckForUpdatesAsync";
|
||||
if (error != null && !string.IsNullOrEmpty(error.ToString()))
|
||||
message = JsonConvert.SerializeObject(error);
|
||||
if (!string.IsNullOrEmpty(result)) message = result;
|
||||
taskCompletionSource.SetException(new Exception(message));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid);
|
||||
BridgeConnector.Socket.Emit("autoUpdater-checkForUpdates", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
@@ -422,49 +306,43 @@ namespace ElectronNET.API
|
||||
var taskCompletionSource = new TaskCompletionSource<UpdateCheckResult>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
|
||||
BridgeConnector.Socket.Once<UpdateCheckResult>("autoUpdater-checkForUpdatesAndNotify-completed" + guid, (result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
|
||||
if (updateCheckResult == null)
|
||||
taskCompletionSource.SetResult(null);
|
||||
else
|
||||
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
|
||||
BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesAndNotifyError" + guid);
|
||||
taskCompletionSource.SetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
taskCompletionSource.SetException(ex);
|
||||
}
|
||||
});
|
||||
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyError" + guid, (error) =>
|
||||
BridgeConnector.Socket.Once<string>("autoUpdater-checkForUpdatesAndNotifyError" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
|
||||
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
|
||||
string message = "An error occurred in autoUpdaterCheckForUpdatesAndNotify";
|
||||
if (error != null)
|
||||
message = JsonConvert.SerializeObject(error);
|
||||
BridgeConnector.Socket.Off("autoUpdater-checkForUpdatesAndNotify-completed" + guid);
|
||||
string message = "An error occurred in CheckForUpdatesAndNotifyAsync";
|
||||
if (!string.IsNullOrEmpty(result)) message = result;
|
||||
taskCompletionSource.SetException(new Exception(message));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid);
|
||||
BridgeConnector.Socket.Emit("autoUpdater-checkForUpdatesAndNotify", 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.
|
||||
/// Restarts the app and installs the update after it has been downloaded.
|
||||
/// It should only be called after `update-downloaded` has been emitted.
|
||||
///
|
||||
/// Note: QuitAndInstall() will close all application windows first and only emit `before-quit` event on `app` after that.
|
||||
/// This is different from the normal quit event sequence.
|
||||
/// </summary>
|
||||
/// <param name="isSilent">*windows-only* Runs the installer in silent mode. Defaults to `false`.</param>
|
||||
/// <param name="isForceRunAfter">Run the app after finish even on silent install. Not applicable for macOS. Ignored if `isSilent` is set to `false`.</param>
|
||||
public void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter);
|
||||
BridgeConnector.Socket.Emit("autoUpdater-quitAndInstall", isSilent, isForceRunAfter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -473,18 +351,13 @@ namespace ElectronNET.API
|
||||
/// <returns>Path to downloaded file.</returns>
|
||||
public Task<string> DownloadUpdateAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterDownloadUpdateComplete" + guid, (downloadedPath) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterDownloadUpdateComplete" + guid);
|
||||
taskCompletionSource.SetResult(downloadedPath.ToString());
|
||||
});
|
||||
BridgeConnector.Socket.Once<string>("autoUpdater-downloadUpdate-completed" + guid, tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("autoUpdater-downloadUpdate", guid);
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterDownloadUpdate", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -493,23 +366,13 @@ namespace ElectronNET.API
|
||||
/// <returns>Feed URL.</returns>
|
||||
public Task<string> GetFeedURLAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("autoUpdaterGetFeedURLComplete" + guid, (downloadedPath) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("autoUpdaterGetFeedURLComplete" + guid);
|
||||
taskCompletionSource.SetResult(downloadedPath.ToString());
|
||||
});
|
||||
BridgeConnector.Socket.Once<string>("autoUpdater-getFeedURL-completed" + guid, tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("autoUpdater-getFeedURL", guid);
|
||||
|
||||
BridgeConnector.Socket.Emit("autoUpdaterGetFeedURL", guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private readonly JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,22 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// A BrowserView can be used to embed additional web content into a BrowserWindow.
|
||||
/// It is like a child window, except that it is positioned relative to its owning window.
|
||||
/// It is meant to be an alternative to the webview tag.
|
||||
/// </summary>
|
||||
public class BrowserView
|
||||
public class BrowserView : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The identifier.
|
||||
/// </value>
|
||||
public int Id { get; internal set; }
|
||||
public override int Id { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Render and control web pages.
|
||||
@@ -28,38 +25,24 @@ namespace ElectronNET.API
|
||||
|
||||
/// <summary>
|
||||
/// Resizes and moves the view to the supplied bounds relative to the window.
|
||||
///
|
||||
/// (experimental)
|
||||
/// </summary>
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
return Task.Run<Rectangle>(() =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Rectangle>();
|
||||
|
||||
BridgeConnector.Socket.On("browserView-getBounds-reply", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("browserView-getBounds-reply");
|
||||
taskCompletionSource.SetResult((Rectangle)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("browserView-getBounds", Id);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}).Result;
|
||||
return Task.Run(() => this.InvokeAsync<Rectangle>()).Result;
|
||||
}
|
||||
set
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setBounds", Id, JObject.FromObject(value, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("browserView-bounds-set", Id, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BrowserView
|
||||
/// </summary>
|
||||
internal BrowserView(int id)
|
||||
internal BrowserView(int id)
|
||||
{
|
||||
Id = id;
|
||||
|
||||
@@ -74,12 +57,11 @@ namespace ElectronNET.API
|
||||
/// <param name="options"></param>
|
||||
public void SetAutoResize(AutoResizeOptions options)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setAutoResize", Id, JObject.FromObject(options, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("browserView-setAutoResize", Id, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color in #aarrggbb or #argb form. The alpha channel is optional.
|
||||
///
|
||||
/// (experimental)
|
||||
/// </summary>
|
||||
/// <param name="color">Color in #aarrggbb or #argb form. The alpha channel is optional.</param>
|
||||
@@ -87,11 +69,5 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Emit("browserView-setBackgroundColor", Id, color);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,27 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Perform copy and paste operations on the system clipboard.
|
||||
/// </summary>
|
||||
public sealed class Clipboard
|
||||
public sealed class Clipboard : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
|
||||
private static Clipboard _clipboard;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Clipboard() { }
|
||||
internal Clipboard()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Clipboard Instance
|
||||
{
|
||||
@@ -40,21 +47,7 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>The content in the clipboard as plain text.</returns>
|
||||
public Task<string> ReadTextAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readText-Completed", (text) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readText-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(text.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readText", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<string> ReadTextAsync(string type = "") => this.InvokeAsync<string>(type);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text into the clipboard as plain text.
|
||||
@@ -71,21 +64,7 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public Task<string> ReadHTMLAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readHTML-Completed", (text) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readHTML-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(text.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readHTML", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<string> ReadHTMLAsync(string type = "") => this.InvokeAsync<string>(type);
|
||||
|
||||
/// <summary>
|
||||
/// Writes markup to the clipboard.
|
||||
@@ -102,21 +81,7 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public Task<string> ReadRTFAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readRTF-Completed", (text) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readRTF-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(text.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readRTF", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<string> ReadRTFAsync(string type = "") => this.InvokeAsync<string>(type);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text into the clipboard in RTF.
|
||||
@@ -125,41 +90,31 @@ namespace ElectronNET.API
|
||||
/// <param name="type"></param>
|
||||
public void WriteRTF(string text, string type = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-writeHTML", text, type);
|
||||
BridgeConnector.Socket.Emit("clipboard-writeRTF", text, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an Object containing title and url keys representing
|
||||
/// the bookmark in the clipboard. The title and url values will
|
||||
/// 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>
|
||||
public Task<ReadBookmark> ReadBookmarkAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ReadBookmark>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readBookmark-Completed", (bookmark) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readBookmark-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(((JObject)bookmark).ToObject<ReadBookmark>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readBookmark");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public Task<ReadBookmark> ReadBookmarkAsync() => this.InvokeAsync<ReadBookmark>();
|
||||
|
||||
/// <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
|
||||
/// 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>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public void WriteBookmark(string title, string url, string type = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-writeBookmark", title, url, type);
|
||||
@@ -171,27 +126,15 @@ namespace ElectronNET.API
|
||||
/// find pasteboard whenever the application is activated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<string> ReadFindTextAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readFindText-Completed", (text) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readFindText-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(text.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readFindText");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public Task<string> ReadFindTextAsync() => this.InvokeAsync<string>();
|
||||
|
||||
/// <summary>
|
||||
/// macOS: Writes the text into the find pasteboard as plain text. This method uses
|
||||
/// macOS: Writes the text into the find pasteboard as plain text. This method uses
|
||||
/// synchronous IPC when called from the renderer process.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public void WriteFindText(string text)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-writeFindText", text);
|
||||
@@ -211,21 +154,7 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public Task<string[]> AvailableFormatsAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string[]>();
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-availableFormats-Completed", (formats) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-availableFormats-Completed");
|
||||
|
||||
taskCompletionSource.SetResult(((JArray)formats).ToObject<string[]>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-availableFormats", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<string[]> AvailableFormatsAsync(string type = "") => this.InvokeAsync<string[]>(type);
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the clipboard.
|
||||
@@ -234,7 +163,7 @@ namespace ElectronNET.API
|
||||
/// <param name="type"></param>
|
||||
public void Write(Data data, string type = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-write", JObject.FromObject(data, _jsonSerializer), type);
|
||||
BridgeConnector.Socket.Emit("clipboard-write", data, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -242,25 +171,8 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public Task<NativeImage> ReadImageAsync(string type = "")
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<NativeImage>();
|
||||
public Task<NativeImage> ReadImageAsync(string type = "") => this.InvokeAsync<NativeImage>(type);
|
||||
|
||||
BridgeConnector.Socket.On("clipboard-readImage-Completed", (image) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("clipboard-readImage-Completed");
|
||||
|
||||
var nativeImage = ((JObject)image).ToObject<NativeImage>();
|
||||
|
||||
taskCompletionSource.SetResult(nativeImage);
|
||||
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("clipboard-readImage", type);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an image to the clipboard.
|
||||
/// </summary>
|
||||
@@ -268,14 +180,7 @@ namespace ElectronNET.API
|
||||
/// <param name="type"></param>
|
||||
public void WriteImage(NativeImage image, string type = "")
|
||||
{
|
||||
BridgeConnector.Socket.Emit("clipboard-writeImage", JsonConvert.SerializeObject(image), type);
|
||||
BridgeConnector.Socket.Emit("clipboard-writeImage", JsonSerializer.Serialize(image, ElectronJson.Options), type);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
public sealed class CommandLine
|
||||
{
|
||||
internal CommandLine() { }
|
||||
internal CommandLine()
|
||||
{
|
||||
}
|
||||
|
||||
internal static CommandLine Instance
|
||||
{
|
||||
@@ -66,22 +68,17 @@ namespace ElectronNET.API
|
||||
/// <param name="switchName">A command-line switch</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Whether the command-line switch is present.</returns>
|
||||
public async Task<bool> HasSwitchAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<bool> HasSwitchAsync(string switchName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("appCommandLineHasSwitchCompleted", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("appCommandLineHasSwitchCompleted");
|
||||
taskCompletionSource.SetResult((bool)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<bool>("appCommandLineHasSwitchCompleted", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("appCommandLineHasSwitch", switchName);
|
||||
|
||||
return await taskCompletionSource.Task.ConfigureAwait(false);
|
||||
return await tcs.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,23 +91,18 @@ namespace ElectronNET.API
|
||||
/// <remarks>
|
||||
/// Note: When the switch is not present or has no value, it returns empty string.
|
||||
/// </remarks>
|
||||
public async Task<string> GetSwitchValueAsync(string switchName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public async Task<string> GetSwitchValueAsync(string switchName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("appCommandLineGetSwitchValueCompleted", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("appCommandLineGetSwitchValueCompleted");
|
||||
taskCompletionSource.SetResult((string)result);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<string>("appCommandLineGetSwitchValueCompleted", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("appCommandLineGetSwitchValue", switchName);
|
||||
|
||||
return await taskCompletionSource.Task.ConfigureAwait(false);
|
||||
return await tcs.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -34,16 +32,21 @@ namespace ElectronNET.API
|
||||
{
|
||||
if (_changed == null)
|
||||
{
|
||||
BridgeConnector.Socket.On("webContents-session-cookies-changed" + Id, (args) =>
|
||||
BridgeConnector.Socket.On<JsonElement>("webContents-session-cookies-changed" + Id, (args) =>
|
||||
{
|
||||
Cookie cookie = ((JArray)args)[0].ToObject<Cookie>();
|
||||
CookieChangedCause cause = ((JArray)args)[1].ToObject<CookieChangedCause>();
|
||||
bool removed = ((JArray)args)[2].ToObject<bool>();
|
||||
var e = args.EnumerateArray().GetEnumerator();
|
||||
e.MoveNext();
|
||||
var cookie = e.Current.Deserialize<Cookie>(ElectronJson.Options);
|
||||
e.MoveNext();
|
||||
var cause = e.Current.Deserialize<CookieChangedCause>(ElectronJson.Options);
|
||||
e.MoveNext();
|
||||
var removed = e.Current.GetBoolean();
|
||||
_changed(cookie, cause, removed);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-webContents-session-cookies-changed", Id);
|
||||
}
|
||||
|
||||
_changed += value;
|
||||
}
|
||||
remove
|
||||
@@ -56,12 +59,5 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
private event Action<Cookie, CookieChangedCause, bool> _changed;
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -16,7 +14,9 @@ namespace ElectronNET.API
|
||||
private static Dialog _dialog;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Dialog() { }
|
||||
internal Dialog()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Dialog Instance
|
||||
{
|
||||
@@ -26,7 +26,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if(_dialog == null)
|
||||
if (_dialog == null)
|
||||
{
|
||||
_dialog = new Dialog();
|
||||
}
|
||||
@@ -38,8 +38,8 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <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']
|
||||
/// 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>
|
||||
@@ -47,23 +47,16 @@ namespace ElectronNET.API
|
||||
/// <returns>An array of file paths chosen by the user</returns>
|
||||
public Task<string[]> ShowOpenDialogAsync(BrowserWindow browserWindow, OpenDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string[]>();
|
||||
var tcs = new TaskCompletionSource<string[]>();
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showOpenDialogComplete" + guid, (filePaths) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showOpenDialogComplete" + guid);
|
||||
|
||||
var result = ((JArray)filePaths).ToObject<string[]>();
|
||||
taskCompletionSource.SetResult(result);
|
||||
});
|
||||
|
||||
|
||||
BridgeConnector.Socket.Once<string[]>("showOpenDialogComplete" + guid, tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("showOpenDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer), guid);
|
||||
browserWindow,
|
||||
options,
|
||||
guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,22 +67,16 @@ namespace ElectronNET.API
|
||||
/// <returns>Returns String, the path of the file chosen by the user, if a callback is provided it returns an empty string.</returns>
|
||||
public Task<string> ShowSaveDialogAsync(BrowserWindow browserWindow, SaveDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showSaveDialogComplete" + guid, (filename) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showSaveDialogComplete" + guid);
|
||||
|
||||
taskCompletionSource.SetResult(filename.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<string>("showSaveDialogComplete" + guid, tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("showSaveDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer),
|
||||
guid);
|
||||
browserWindow,
|
||||
options,
|
||||
guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,43 +130,47 @@ namespace ElectronNET.API
|
||||
/// <returns>The API call will be asynchronous and the result will be passed via MessageBoxResult.</returns>
|
||||
public Task<MessageBoxResult> ShowMessageBoxAsync(BrowserWindow browserWindow, MessageBoxOptions messageBoxOptions)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<MessageBoxResult>();
|
||||
var tcs = new TaskCompletionSource<MessageBoxResult>();
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showMessageBoxComplete" + guid, (args) =>
|
||||
BridgeConnector.Socket.Once<JsonElement>("showMessageBoxComplete" + guid, (args) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showMessageBoxComplete" + guid);
|
||||
// args is [response:int, checkboxChecked:boolean]
|
||||
var arr = args.EnumerateArray();
|
||||
var e = arr.GetEnumerator();
|
||||
e.MoveNext();
|
||||
var response = e.Current.GetInt32();
|
||||
e.MoveNext();
|
||||
var checkbox = e.Current.GetBoolean();
|
||||
|
||||
var result = ((JArray)args);
|
||||
|
||||
taskCompletionSource.SetResult(new MessageBoxResult
|
||||
tcs.SetResult(new MessageBoxResult
|
||||
{
|
||||
Response = (int)result.First,
|
||||
CheckboxChecked = (bool)result.Last
|
||||
Response = response,
|
||||
CheckboxChecked = checkbox
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
if (browserWindow == null)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("showMessageBox", JObject.FromObject(messageBoxOptions, _jsonSerializer), guid);
|
||||
} else
|
||||
BridgeConnector.Socket.Emit("showMessageBox", messageBoxOptions, guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("showMessageBox",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(messageBoxOptions, _jsonSerializer),
|
||||
BridgeConnector.Socket.Emit("showMessageBox",
|
||||
browserWindow,
|
||||
messageBoxOptions,
|
||||
guid);
|
||||
}
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <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,
|
||||
/// 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>
|
||||
@@ -191,11 +182,13 @@ namespace ElectronNET.API
|
||||
|
||||
/// <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
|
||||
/// 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>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public Task ShowCertificateTrustDialogAsync(CertificateTrustDialogOptions options)
|
||||
{
|
||||
return ShowCertificateTrustDialogAsync(null, options);
|
||||
@@ -203,36 +196,26 @@ namespace ElectronNET.API
|
||||
|
||||
/// <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
|
||||
/// 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>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public Task ShowCertificateTrustDialogAsync(BrowserWindow browserWindow, CertificateTrustDialogOptions options)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On("showCertificateTrustDialogComplete" + guid, () =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("showCertificateTrustDialogComplete" + guid);
|
||||
taskCompletionSource.SetResult(null);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once("showCertificateTrustDialogComplete" + guid, () => tcs.SetResult(null));
|
||||
BridgeConnector.Socket.Emit("showCertificateTrustDialog",
|
||||
JObject.FromObject(browserWindow, _jsonSerializer),
|
||||
JObject.FromObject(options, _jsonSerializer),
|
||||
browserWindow,
|
||||
options,
|
||||
guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Control your app in the macOS dock.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public sealed class Dock
|
||||
{
|
||||
private static Dock _dock;
|
||||
@@ -54,18 +53,13 @@ namespace ElectronNET.API
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<int>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<int>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("dock-bounce-completed", (id) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("dock-bounce-completed");
|
||||
taskCompletionSource.SetResult((int) id);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<int>("dock-bounce-completed", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("dock-bounce", type.GetDescription());
|
||||
|
||||
return await taskCompletionSource.Task
|
||||
return await tcs.Task
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -106,18 +100,13 @@ namespace ElectronNET.API
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("dock-getBadge-completed", (text) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("dock-getBadge-completed");
|
||||
taskCompletionSource.SetResult((string) text);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<string>("dock-getBadge-completed", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("dock-getBadge");
|
||||
|
||||
return await taskCompletionSource.Task
|
||||
return await tcs.Task
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -148,18 +137,13 @@ namespace ElectronNET.API
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("dock-isVisible-completed", (isVisible) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("dock-isVisible-completed");
|
||||
taskCompletionSource.SetResult((bool) isVisible);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<bool>("dock-isVisible-completed", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("dock-isVisible");
|
||||
|
||||
return await taskCompletionSource.Task
|
||||
return await tcs.Task
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -170,7 +154,14 @@ namespace ElectronNET.API
|
||||
/// <value>
|
||||
/// The menu items.
|
||||
/// </value>
|
||||
public IReadOnlyCollection<MenuItem> MenuItems { get { return _items.AsReadOnly(); } }
|
||||
public IReadOnlyCollection<MenuItem> MenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return _items.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
private List<MenuItem> _items = new List<MenuItem>();
|
||||
|
||||
/// <summary>
|
||||
@@ -179,15 +170,15 @@ namespace ElectronNET.API
|
||||
public void SetMenu(MenuItem[] menuItems)
|
||||
{
|
||||
menuItems.AddMenuItemsId();
|
||||
BridgeConnector.Socket.Emit("dock-setMenu", JArray.FromObject(menuItems, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("dock-setMenu", new[] { menuItems });
|
||||
_items.AddRange(menuItems);
|
||||
|
||||
BridgeConnector.Socket.Off("dockMenuItemClicked");
|
||||
BridgeConnector.Socket.On("dockMenuItemClicked", (id) => {
|
||||
MenuItem menuItem = _items.GetMenuItem(id.ToString());
|
||||
BridgeConnector.Socket.On<string>("dockMenuItemClicked", (id) =>
|
||||
{
|
||||
MenuItem menuItem = _items.GetMenuItem(id);
|
||||
menuItem?.Click();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -198,18 +189,13 @@ namespace ElectronNET.API
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<Menu>();
|
||||
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
|
||||
var tcs = new TaskCompletionSource<Menu>();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
|
||||
{
|
||||
BridgeConnector.Socket.On("dock-getMenu-completed", (menu) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("dock-getMenu-completed");
|
||||
taskCompletionSource.SetResult(((JObject)menu).ToObject<Menu>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Once<Menu>("dock-getMenu-completed", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("dock-getMenu");
|
||||
|
||||
return await taskCompletionSource.Task
|
||||
return await tcs.Task
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -222,11 +208,5 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Emit("dock-setIcon", image);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -8,90 +8,192 @@
|
||||
/// <summary>
|
||||
/// Communicate asynchronously from the main process to renderer processes.
|
||||
/// </summary>
|
||||
public static IpcMain IpcMain { get { return IpcMain.Instance; } }
|
||||
public static IpcMain IpcMain
|
||||
{
|
||||
get
|
||||
{
|
||||
return IpcMain.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control your application's event lifecycle.
|
||||
/// </summary>
|
||||
public static App App { get { return App.Instance; } }
|
||||
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; } }
|
||||
public static AutoUpdater AutoUpdater
|
||||
{
|
||||
get
|
||||
{
|
||||
return AutoUpdater.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control your windows.
|
||||
/// </summary>
|
||||
public static WindowManager WindowManager { get { return WindowManager.Instance; } }
|
||||
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; } }
|
||||
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; } }
|
||||
public static Dialog Dialog
|
||||
{
|
||||
get
|
||||
{
|
||||
return Dialog.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
public static Notification Notification { get { return Notification.Instance; } }
|
||||
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; } }
|
||||
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; } }
|
||||
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; } }
|
||||
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; } }
|
||||
public static Screen Screen
|
||||
{
|
||||
get
|
||||
{
|
||||
return Screen.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform copy and paste operations on the system clipboard.
|
||||
/// </summary>
|
||||
public static Clipboard Clipboard { get { return Clipboard.Instance; } }
|
||||
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
|
||||
/// 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; } }
|
||||
public static HostHook HostHook
|
||||
{
|
||||
get
|
||||
{
|
||||
return HostHook.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to execute native Lock and Unlock process.
|
||||
/// Allows you to execute native Lock and Unlock process.
|
||||
/// </summary>
|
||||
public static PowerMonitor PowerMonitor { get { return PowerMonitor.Instance; } }
|
||||
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; } }
|
||||
public static NativeTheme NativeTheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return NativeTheme.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control your app in the macOS dock.
|
||||
/// </summary>
|
||||
public static Dock Dock { get { return Dock.Instance; } }
|
||||
public static Dock Dock
|
||||
{
|
||||
get
|
||||
{
|
||||
return Dock.Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Electeon extensions to the Nodejs process object.
|
||||
/// </summary>
|
||||
public static Process Process { get { return Process.Instance; } }
|
||||
public static Process Process
|
||||
{
|
||||
get
|
||||
{
|
||||
return Process.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,6 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// Gets or sets the dataURL
|
||||
/// </summary>
|
||||
public string DataUrl { get; set; }
|
||||
public string DataUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -35,4 +35,4 @@ namespace ElectronNET.API.Entities
|
||||
[DefaultValue(false)]
|
||||
public bool Vertical { get; set; } = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,4 @@
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
@@ -32,4 +28,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public bool IsAdminRightsRequired { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,4 +22,4 @@
|
||||
/// </summary>
|
||||
public string ProxyCredentials { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using ElectronNET.Converter;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -125,6 +125,11 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public bool SkipTaskbar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Blazor is used. Will disable "module" and "process" globals. Default is false.
|
||||
/// </summary>
|
||||
public bool IsRunningBlazor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The kiosk mode. Default is false.
|
||||
/// </summary>
|
||||
@@ -199,7 +204,7 @@ namespace ElectronNET.API.Entities
|
||||
public bool DarkTheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Makes the window . Default is false.
|
||||
/// Makes the window transparent. Default is false.
|
||||
/// </summary>
|
||||
public bool Transparent { get; set; }
|
||||
|
||||
@@ -212,9 +217,20 @@ namespace ElectronNET.API.Entities
|
||||
/// The style of window title bar. Default is default. Possible values are:
|
||||
/// 'default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover'
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public TitleBarStyle TitleBarStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configures the window's title bar overlay when using a frameless window.
|
||||
/// Can be either:
|
||||
/// - false: No title bar overlay.
|
||||
/// - true: Enables the default title bar overlay.
|
||||
/// - An object defining custom overlay options (such as height, color, etc.).
|
||||
///
|
||||
/// Default is false.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(TitleBarOverlayConverter))]
|
||||
public TitleBarOverlay TitleBarOverlay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Shows the title in the tile bar in full screen mode on macOS for all
|
||||
/// titleBarStyle options.Default is false.
|
||||
@@ -229,12 +245,20 @@ namespace ElectronNET.API.Entities
|
||||
[DefaultValue(true)]
|
||||
public bool ThickFrame { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether frameless window should have rounded corners. Default is true. Setting this
|
||||
/// property to false will prevent the window from being fullscreenable on macOS. On
|
||||
/// Windows versions older than Windows 11 Build 22000 this property has no effect, and
|
||||
/// frameless windows will not have rounded corners.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public bool RoundedCorners { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Add a type of vibrancy effect to the window, only on macOS. Can be
|
||||
/// appearance-based, light, dark, titlebar, selection, menu, popover, sidebar,
|
||||
/// medium-light or ultra-dark.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public Vibrancy Vibrancy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -271,4 +295,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string ProxyCredentials { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,12 @@
|
||||
/// <summary>
|
||||
/// Percentage of CPU used since the last call to getCPUUsage. First call returns 0.
|
||||
/// </summary>
|
||||
public int PercentCPUUsage { get; set; }
|
||||
public double PercentCPUUsage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of average idle cpu wakeups per second since the last call to
|
||||
/// 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,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Provide metadata about the current loaded Chrome extension
|
||||
@@ -30,4 +26,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@
|
||||
/// </summary>
|
||||
public string[] Quotas { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
namespace ElectronNET.API.Entities {
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Cookie {
|
||||
public class Cookie
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the cookie.
|
||||
/// </summary>
|
||||
public string Name { get; set;}
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The value of the cookie.
|
||||
@@ -26,7 +28,7 @@
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie.
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure.
|
||||
@@ -36,7 +38,7 @@
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as HTTP only.
|
||||
/// </summary>
|
||||
public bool HttpOnly { get; set; }
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is a session cookie or a persistent cookie with an expiration date.
|
||||
@@ -48,4 +50,4 @@
|
||||
/// </summary>
|
||||
public long ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities {
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// The cause of the change
|
||||
/// The cause of the change
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum CookieChangedCause
|
||||
public enum CookieChangedCause
|
||||
{
|
||||
/// <summary>
|
||||
///The cookie was changed directly by a consumer's action.
|
||||
/// </summary>
|
||||
[JsonProperty("explicit")]
|
||||
[JsonPropertyName("explicit")]
|
||||
@explicit,
|
||||
|
||||
/// <summary>
|
||||
@@ -32,7 +31,7 @@ namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
/// The cookie was overwritten with an already-expired expiration date.
|
||||
/// </summary>
|
||||
[JsonProperty("expired_overwrite")]
|
||||
[JsonPropertyName("expired_overwrite")]
|
||||
expiredOverwrite
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities {
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CookieDetails {
|
||||
public class CookieDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL to associate the cookie with. The callback will be rejected if the URL is invalid.
|
||||
/// </summary>
|
||||
@@ -19,7 +21,7 @@ namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
/// (optional) - The value of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
[DefaultValue("")]
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -31,13 +33,13 @@ namespace ElectronNET.API.Entities {
|
||||
/// <summary>
|
||||
/// (optional) - The path of the cookie. Empty by default if omitted.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
[DefaultValue("")]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - Whether the cookie is marked as secure. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
[DefaultValue(false)]
|
||||
public bool Secure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -47,10 +49,10 @@ namespace ElectronNET.API.Entities {
|
||||
public bool HttpOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch.
|
||||
/// (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,13 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CookieFilter
|
||||
public class CookieFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// (optional) - Retrieves cookies which are associated with url.Empty implies retrieving cookies of all URLs.
|
||||
@@ -38,6 +34,5 @@ namespace ElectronNET.API.Entities
|
||||
/// (optional) - Filters out session or persistent cookies.
|
||||
/// </summary>
|
||||
public bool Session { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,4 +64,4 @@
|
||||
ETag = eTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
/// <summary>
|
||||
/// Unique identifier associated with the display.
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// true for an internal display and false for an external display.
|
||||
@@ -61,7 +61,7 @@
|
||||
/// <summary>
|
||||
/// Output device's pixel scale factor.
|
||||
/// </summary>
|
||||
public int ScaleFactor { get; set; }
|
||||
public double ScaleFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Can be available, unavailable, unknown.
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
/// </summary>
|
||||
public int UploadThroughput { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Docs: https://electronjs.org/docs/api/structures/extension
|
||||
@@ -41,4 +35,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -10,43 +10,43 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// Canvas.
|
||||
/// </summary>
|
||||
[JsonProperty("2d_canvas")]
|
||||
[JsonPropertyName("2d_canvas")]
|
||||
public string Canvas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_3d")]
|
||||
[JsonPropertyName("flash_3d")]
|
||||
public string Flash3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash Stage3D.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_stage3d")]
|
||||
[JsonPropertyName("flash_stage3d")]
|
||||
public string FlashStage3D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Flash Stage3D Baseline profile.
|
||||
/// </summary>
|
||||
[JsonProperty("flash_stage3d_baseline")]
|
||||
[JsonPropertyName("flash_stage3d_baseline")]
|
||||
public string FlashStage3dBaseline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compositing.
|
||||
/// </summary>
|
||||
[JsonProperty("gpu_compositing")]
|
||||
[JsonPropertyName("gpu_compositing")]
|
||||
public string GpuCompositing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Multiple Raster Threads.
|
||||
/// </summary>
|
||||
[JsonProperty("multiple_raster_threads")]
|
||||
[JsonPropertyName("multiple_raster_threads")]
|
||||
public string MultipleRasterThreads { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Native GpuMemoryBuffers.
|
||||
/// </summary>
|
||||
[JsonProperty("native_gpu_memory_buffers")]
|
||||
[JsonPropertyName("native_gpu_memory_buffers")]
|
||||
public string NativeGpuMemoryBuffers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -57,19 +57,19 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// Video Decode.
|
||||
/// </summary>
|
||||
[JsonProperty("video_decode")]
|
||||
[JsonPropertyName("video_decode")]
|
||||
public string VideoDecode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Video Encode.
|
||||
/// </summary>
|
||||
[JsonProperty("video_encode")]
|
||||
[JsonPropertyName("video_encode")]
|
||||
public string VideoEncode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// VPx Video Decode.
|
||||
/// </summary>
|
||||
[JsonProperty("vpx_decode")]
|
||||
[JsonPropertyName("vpx_decode")]
|
||||
public string VpxDecode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
/// Path for the pkcs12 file.
|
||||
/// </summary>
|
||||
public string Certificate { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Passphrase for the certificate.
|
||||
/// </summary>
|
||||
public string Password {get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
using ElectronNET.Converter;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -76,7 +75,6 @@ namespace ElectronNET.API.Entities
|
||||
/// `touchScrollStarted`, `pointerDown`, `pointerUp`, `pointerMove`,
|
||||
/// `pointerRawUpdate`, `pointerCancel` or `pointerCausedUaAction`.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public InputEventType Type { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,26 +9,32 @@ public enum InputEventType
|
||||
///
|
||||
/// </summary>
|
||||
undefined,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
mouseDown,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
mouseUp,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
mouseMove,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
mouseEnter,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
mouseLeave,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -21,7 +20,6 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// One of the following: "tasks" | "frequent" | "recent" | "custom"
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public JumpListCategoryType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -52,7 +51,6 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// One of the following: "task" | "separator" | "file"
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public JumpListItemType Type { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
public int WorkingSetSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of memory that has ever been pinned to actual physical RAM.
|
||||
/// The maximum amount of memory that has ever been pinned to actual physical RAM.
|
||||
/// </summary>
|
||||
public int PeakWorkingSetSize { get; set; }
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -11,7 +9,7 @@ namespace ElectronNET.API.Entities
|
||||
public class MenuItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Will be called with click(menuItem, browserWindow, event) when the menu item is
|
||||
/// Will be called with click(menuItem, browserWindow, event) when the menu item is
|
||||
/// clicked.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
@@ -21,13 +19,11 @@ namespace ElectronNET.API.Entities
|
||||
/// Define the action of the menu item, when specified the click property will be
|
||||
/// ignored.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MenuRole Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Can be normal, separator, submenu, checkbox or radio.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MenuType Type { get; set; }
|
||||
|
||||
|
||||
@@ -100,4 +96,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string Position { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -13,7 +12,6 @@ namespace ElectronNET.API.Entities
|
||||
/// displays the same icon as "info", unless you set an icon using the "icon"
|
||||
/// option. On macOS, both "warning" and "error" display the same warning icon.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MessageBoxType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -98,4 +96,4 @@ namespace ElectronNET.API.Entities
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@
|
||||
/// </value>
|
||||
public bool CheckboxChecked { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -21,9 +21,9 @@ namespace ElectronNET.API.Entities
|
||||
|
||||
private static readonly Dictionary<string, float> ScaleFactorPairs = new Dictionary<string, float>
|
||||
{
|
||||
{"@2x", 2.0f}, {"@3x", 3.0f}, {"@1x", 1.0f}, {"@4x", 4.0f},
|
||||
{"@5x", 5.0f}, {"@1.25x", 1.25f}, {"@1.33x", 1.33f}, {"@1.4x", 1.4f},
|
||||
{"@1.5x", 1.5f}, {"@1.8x", 1.8f}, {"@2.5x", 2.5f}
|
||||
{ "@2x", 2.0f }, { "@3x", 3.0f }, { "@1x", 1.0f }, { "@4x", 4.0f },
|
||||
{ "@5x", 5.0f }, { "@1.25x", 1.25f }, { "@1.33x", 1.33f }, { "@1.4x", 1.4f },
|
||||
{ "@1.5x", 1.5f }, { "@1.8x", 1.8f }, { "@2.5x", 2.5f }
|
||||
};
|
||||
|
||||
private static float? ExtractDpiFromFilePath(string filePath)
|
||||
@@ -34,6 +34,7 @@ namespace ElectronNET.API.Entities
|
||||
.Select(p => p.Value)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static Image BytesToImage(byte[] bytes)
|
||||
{
|
||||
var ms = new MemoryStream(bytes);
|
||||
@@ -83,7 +84,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <param name="dataUrl">A data URL with a base64 encoded image.</param>
|
||||
public static NativeImage CreateFromDataURL(string dataUrl)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
var images = new Dictionary<float, Image>();
|
||||
var parsedDataUrl = Regex.Match(dataUrl, @"data:image/(?<type>.+?),(?<data>.+)");
|
||||
var actualData = parsedDataUrl.Groups["data"].Value;
|
||||
var binData = Convert.FromBase64String(actualData);
|
||||
@@ -101,7 +102,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <param name="path">The path of the image</param>
|
||||
public static NativeImage CreateFromPath(string path)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
var images = new Dictionary<float, Image>();
|
||||
if (Regex.IsMatch(path, "(@.+?x)"))
|
||||
{
|
||||
var dpi = ExtractDpiFromFilePath(path);
|
||||
@@ -164,7 +165,7 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public NativeImage Crop(Rectangle rect)
|
||||
{
|
||||
var images = new Dictionary<float,Image>();
|
||||
var images = new Dictionary<float, Image>();
|
||||
foreach (var image in _images)
|
||||
{
|
||||
images.Add(image.Key, Crop(rect.X, rect.Y, rect.Width, rect.Height, image.Key));
|
||||
@@ -196,7 +197,7 @@ namespace ElectronNET.API.Entities
|
||||
if (options.Buffer.Length > 0)
|
||||
{
|
||||
_images[options.ScaleFactor] =
|
||||
CreateFromBuffer(options.Buffer, new CreateFromBufferOptions {ScaleFactor = options.ScaleFactor})
|
||||
CreateFromBuffer(options.Buffer, new CreateFromBufferOptions { ScaleFactor = options.ScaleFactor })
|
||||
.GetScale(options.ScaleFactor);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(options.DataUrl))
|
||||
@@ -225,7 +226,7 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public byte[] GetBitmap(BitmapOptions options)
|
||||
{
|
||||
return ToBitmap(new ToBitmapOptions{ ScaleFactor = options.ScaleFactor });
|
||||
return ToBitmap(new ToBitmapOptions { ScaleFactor = options.ScaleFactor });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -419,12 +420,13 @@ namespace ElectronNET.API.Entities
|
||||
return codec;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal Dictionary<float,string> GetAllScaledImages()
|
||||
internal Dictionary<float, string> GetAllScaledImages()
|
||||
{
|
||||
var dict = new Dictionary<float,string>();
|
||||
var dict = new Dictionary<float, string>();
|
||||
try
|
||||
{
|
||||
foreach (var (scale, image) in _images)
|
||||
@@ -436,7 +438,7 @@ namespace ElectronNET.API.Entities
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@@ -450,4 +452,4 @@ namespace ElectronNET.API.Entities
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,38 @@
|
||||
using System;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
internal class NativeImageJsonConverter : JsonConverter
|
||||
internal class NativeImageJsonConverter : JsonConverter<NativeImage>
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
public override void Write(Utf8JsonWriter writer, NativeImage value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value is NativeImage nativeImage)
|
||||
if (value is null)
|
||||
{
|
||||
var scaledImages = nativeImage.GetAllScaledImages();
|
||||
serializer.Serialize(writer, scaledImages);
|
||||
writer.WriteNullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
var scaledImages = value.GetAllScaledImages();
|
||||
JsonSerializer.Serialize(writer, scaledImages, ElectronJson.Options);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
public override NativeImage Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var dict = serializer.Deserialize<Dictionary<float, string>>(reader);
|
||||
var dict = JsonSerializer.Deserialize<Dictionary<float, string>>(ref reader, ElectronJson.Options);
|
||||
var newDictionary = new Dictionary<float, Image>();
|
||||
foreach (var item in dict)
|
||||
{
|
||||
var bytes = Convert.FromBase64String(item.Value);
|
||||
newDictionary.Add(item.Key, Image.FromStream(new MemoryStream(bytes)));
|
||||
}
|
||||
|
||||
return new NativeImage(newDictionary);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(NativeImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -43,6 +44,8 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// The timeout duration of the notification. Can be 'default' or 'never'.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("Linux")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public string TimeoutType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -58,6 +61,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("Linux")]
|
||||
public string Urgency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -86,7 +90,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// The show identifier.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
internal string ShowID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -101,7 +105,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// The click identifier.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
internal string ClickID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -118,7 +122,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// The close identifier.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
internal string CloseID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -127,6 +131,7 @@ namespace ElectronNET.API.Entities
|
||||
/// The string the user entered into the inline reply field
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public Action<string> OnReply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -135,13 +140,14 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// The reply identifier.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
internal string ReplyID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// macOS only - The index of the action that was activated
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public Action<string> OnAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -150,7 +156,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <value>
|
||||
/// The action identifier.
|
||||
/// </value>
|
||||
[JsonProperty]
|
||||
[JsonInclude]
|
||||
internal string ActionID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -164,4 +170,4 @@ namespace ElectronNET.API.Entities
|
||||
Body = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,4 @@ public class OnDidFailLoadInfo
|
||||
/// Validated URL.
|
||||
/// </summary>
|
||||
public string ValidatedUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,4 @@ public class OnDidNavigateInfo
|
||||
/// HTTP response code.
|
||||
/// </summary>
|
||||
public int HttpResponseCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -13,7 +12,6 @@ namespace ElectronNET.API.Entities
|
||||
/// detach.Defaults to last used dock state.In undocked mode it's possible to dock
|
||||
/// back.In detach mode it's not.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public DevToolsMode Mode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -33,7 +32,6 @@ namespace ElectronNET.API.Entities
|
||||
/// Contains which features the dialog should use. The following values are supported:
|
||||
/// 'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory'
|
||||
/// </summary>
|
||||
[JsonProperty("properties", ItemConverterType = typeof(StringEnumConverter))]
|
||||
public OpenDialogProperty[] Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -42,7 +40,7 @@ namespace ElectronNET.API.Entities
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The filters specifies an array of file types that can be displayed or
|
||||
/// The filters specifies an array of file types that can be displayed or
|
||||
/// selected when you want to limit the user to a specific type. For example:
|
||||
/// </summary>
|
||||
/// <example>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
|
||||
20
src/ElectronNET.API/API/Entities/PageSize.cs
Normal file
20
src/ElectronNET.API/API/Entities/PageSize.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace ElectronNET.API.Entities;
|
||||
|
||||
public class PageSize
|
||||
{
|
||||
private readonly string _value;
|
||||
|
||||
public PageSize()
|
||||
{
|
||||
}
|
||||
|
||||
private PageSize(string value) : this() => _value = value;
|
||||
|
||||
public double Height { get; set; }
|
||||
|
||||
public double Width { get; set; }
|
||||
|
||||
public static implicit operator string(PageSize pageSize) => pageSize?._value;
|
||||
|
||||
public static implicit operator PageSize(string value) => new(value);
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace ElectronNET.API.Entities
|
||||
AppData,
|
||||
|
||||
/// <summary>
|
||||
/// The directory for storing your app’s configuration files,
|
||||
/// 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")]
|
||||
@@ -92,4 +92,4 @@ namespace ElectronNET.API.Entities
|
||||
[Description("PepperFlashSystemPlugin")]
|
||||
PepperFlashSystemPlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ namespace ElectronNET.API.Entities
|
||||
/// true for landscape, false for portrait.
|
||||
/// </summary>
|
||||
public bool Landscape { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The scale factor of the web page
|
||||
/// </summary>
|
||||
@@ -102,6 +102,5 @@ namespace ElectronNET.API.Entities
|
||||
/// Dpi
|
||||
/// </summary>
|
||||
public PrintDpi Dpi { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace ElectronNET.API.Entities;
|
||||
using ElectronNET.Converter;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -30,7 +33,8 @@ public class PrintToPDFOptions
|
||||
/// `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing
|
||||
/// `height` and `width` in inches. Defaults to `Letter`.
|
||||
/// </summary>
|
||||
public object PageSize { get; set; } = "Letter";
|
||||
[JsonConverter(typeof(PageSizeConverter))]
|
||||
public PageSize PageSize { get; set; } = "Letter";
|
||||
|
||||
/// <summary>
|
||||
/// Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string,
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ElectronNET.API.Entities
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Status
|
||||
/// </summary>
|
||||
@@ -24,6 +24,5 @@ namespace ElectronNET.API.Entities
|
||||
/// Is default
|
||||
/// </summary>
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Process metrics information.
|
||||
/// </summary>
|
||||
public class ProcessMetric
|
||||
{
|
||||
@@ -21,11 +21,9 @@
|
||||
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.
|
||||
/// Creation time for this process in milliseconds since Unix epoch. Can exceed Int32 range and may contain fractional milliseconds.
|
||||
/// </summary>
|
||||
public int CreationTime { get; set; }
|
||||
public double CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Memory information for the process.
|
||||
|
||||
@@ -7,4 +7,4 @@ namespace ElectronNET.API.Entities
|
||||
/// <param name="Electron">Value representing Electron's version string</param>
|
||||
/// <returns></returns>
|
||||
public record ProcessVersions(string Chrome, string Electron);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -11,7 +10,6 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// Mode for the progress bar. Can be 'none' | 'normal' | 'indeterminate' | 'error' | 'paused'.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public ProgressBarMode Mode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
@@ -34,4 +30,4 @@ namespace ElectronNET.API.Entities
|
||||
/// </summary>
|
||||
public string Transferred { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,4 @@
|
||||
ProxyBypassRules = proxyBypassRules;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,4 @@
|
||||
/// </summary>
|
||||
public string Note { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -25,10 +24,9 @@ namespace ElectronNET.API.Entities
|
||||
public string Realm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scheme of the authentication. Can be basic, digest, ntlm, negotiate.
|
||||
/// Scheme of the authentication. Can be basic, digest, ntlm, negotiate.
|
||||
/// Must be provided if removing by origin.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public Scheme Scheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -50,4 +48,4 @@ namespace ElectronNET.API.Entities
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@
|
||||
/// </summary>
|
||||
public string Quality { get; set; } = "best";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace ElectronNET.API
|
||||
public string ButtonLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The filters specifies an array of file types that can be displayed or
|
||||
/// The filters specifies an array of file types that can be displayed or
|
||||
/// selected when you want to limit the user to a specific type. For example:
|
||||
/// </summary>
|
||||
/// <example>
|
||||
|
||||
@@ -8,35 +8,43 @@
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Raw { get; set; }
|
||||
public string Raw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool Loose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SemVerOptions Options { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Major { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Minor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int Patch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string[] Build { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -46,14 +54,16 @@
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SemVerOptions {
|
||||
public class SemVerOptions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool? Loose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool? IncludePrerelease { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,4 @@ namespace ElectronNET.API.Entities
|
||||
[Description("replace")]
|
||||
Replace
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -36,7 +35,6 @@ namespace ElectronNET.API.Entities
|
||||
/// hidden - The button is not shown to the user.
|
||||
/// noninteractive - The button is enabled but not interactive; no pressed button state is drawn.This value is intended for instances where the button is used in a notification.
|
||||
/// </summary>
|
||||
[JsonProperty("flags", ItemConverterType = typeof(StringEnumConverter))]
|
||||
public ThumbarButtonFlag[] Flags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
22
src/ElectronNET.API/API/Entities/TitleBarOverlay.cs
Normal file
22
src/ElectronNET.API/API/Entities/TitleBarOverlay.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace ElectronNET.API.Entities;
|
||||
|
||||
public class TitleBarOverlay
|
||||
{
|
||||
private readonly bool? _value;
|
||||
|
||||
public TitleBarOverlay()
|
||||
{
|
||||
}
|
||||
|
||||
private TitleBarOverlay(bool value) : this() => _value = value;
|
||||
|
||||
public string Color { get; set; }
|
||||
|
||||
public double Height { get; set; }
|
||||
|
||||
public string SymbolColor { get; set; }
|
||||
|
||||
public static implicit operator bool?(TitleBarOverlay titleBarOverlay) => titleBarOverlay?._value;
|
||||
|
||||
public static implicit operator TitleBarOverlay(bool value) => new(value);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ElectronNET.API.Entities
|
||||
{
|
||||
@@ -10,7 +10,7 @@ namespace ElectronNET.API.Entities
|
||||
/// <summary>
|
||||
/// The default style
|
||||
/// </summary>
|
||||
[JsonProperty("default")]
|
||||
[JsonPropertyName("default")]
|
||||
defaultStyle,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,4 @@
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,4 @@
|
||||
/// </summary>
|
||||
public float ScaleFactor { get; set; } = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -23,7 +22,6 @@
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@
|
||||
/// </summary>
|
||||
public UpdateCancellationToken CancellationToken { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,4 @@
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
/// The data is available as a Buffer, in the rawData field.
|
||||
/// </summary>
|
||||
public string Type { get; } = "rawData";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The raw bytes of the post data in a Buffer.
|
||||
/// </summary>
|
||||
|
||||
@@ -213,4 +213,4 @@ namespace ElectronNET.API.Entities
|
||||
[DefaultValue(false)]
|
||||
public bool EnableRemoteModule { get; set; } = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,9 @@ namespace ElectronNET.API.Extensions
|
||||
return ((DescriptionAttribute)attrs[0]).Description;
|
||||
}
|
||||
}
|
||||
|
||||
//If we have no description attribute, just return the ToString of the enum
|
||||
return enumerationValue.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace ElectronNET.API.Extensions
|
||||
var menuItem = menuItems[index];
|
||||
if (menuItem?.Submenu?.Length > 0)
|
||||
{
|
||||
if(menuItem.Type == MenuType.normal)
|
||||
if (menuItem.Type == MenuType.normal)
|
||||
{
|
||||
menuItem.Type = MenuType.submenu;
|
||||
}
|
||||
@@ -68,4 +68,4 @@ namespace ElectronNET.API.Extensions
|
||||
return menuItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,4 +36,4 @@ namespace ElectronNET.API.Extensions
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -12,7 +13,9 @@ namespace ElectronNET.API
|
||||
private static GlobalShortcut _globalShortcut;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal GlobalShortcut() { }
|
||||
internal GlobalShortcut()
|
||||
{
|
||||
}
|
||||
|
||||
internal static GlobalShortcut Instance
|
||||
{
|
||||
@@ -36,10 +39,10 @@ namespace ElectronNET.API
|
||||
private Dictionary<string, Action> _shortcuts = new Dictionary<string, Action>();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global shortcut of accelerator.
|
||||
/// 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
|
||||
/// 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>
|
||||
@@ -50,11 +53,11 @@ namespace ElectronNET.API
|
||||
_shortcuts.Add(accelerator, function);
|
||||
|
||||
BridgeConnector.Socket.Off("globalShortcut-pressed");
|
||||
BridgeConnector.Socket.On("globalShortcut-pressed", (shortcut) =>
|
||||
BridgeConnector.Socket.On<string>("globalShortcut-pressed", (shortcut) =>
|
||||
{
|
||||
if (_shortcuts.ContainsKey(shortcut.ToString()))
|
||||
if (_shortcuts.TryGetValue(shortcut, out var action))
|
||||
{
|
||||
_shortcuts[shortcut.ToString()]();
|
||||
action();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -63,25 +66,19 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the accelerator is already taken by other applications,
|
||||
/// 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>
|
||||
public Task<bool> IsRegisteredAsync(string accelerator)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("globalShortcut-isRegisteredCompleted", (isRegistered) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("globalShortcut-isRegisteredCompleted");
|
||||
|
||||
taskCompletionSource.SetResult((bool)isRegistered);
|
||||
});
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.Once<bool>("globalShortcut-isRegisteredCompleted", tcs.SetResult);
|
||||
BridgeConnector.Socket.Emit("globalShortcut-isRegistered", accelerator);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -9,7 +8,7 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Allows you to execute native JavaScript/TypeScript code from the host process.
|
||||
///
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// It is only possible if the Electron.NET CLI has previously added an
|
||||
/// ElectronHostHook directory:
|
||||
/// <c>electronize add HostHook</c>
|
||||
/// </summary>
|
||||
@@ -17,9 +16,11 @@ namespace ElectronNET.API
|
||||
{
|
||||
private static HostHook _electronHostHook;
|
||||
private static object _syncRoot = new object();
|
||||
string oneCallguid = Guid.NewGuid().ToString();
|
||||
private string oneCallguid = Guid.NewGuid().ToString();
|
||||
|
||||
internal HostHook() { }
|
||||
internal HostHook()
|
||||
{
|
||||
}
|
||||
|
||||
internal static HostHook Instance
|
||||
{
|
||||
@@ -47,11 +48,7 @@ namespace ElectronNET.API
|
||||
/// <param name="arguments">Optional parameters.</param>
|
||||
public void Call(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + oneCallguid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + oneCallguid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
});
|
||||
BridgeConnector.Socket.Once<string>(socketEventName + "Error" + oneCallguid, (result) => { Electron.Dialog.ShowErrorBox("Host Hook Exception", result); });
|
||||
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments, oneCallguid);
|
||||
}
|
||||
@@ -65,64 +62,35 @@ namespace ElectronNET.API
|
||||
/// <returns></returns>
|
||||
public Task<T> CallAsync<T>(string socketEventName, params dynamic[] arguments)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
var tcs = new TaskCompletionSource<T>();
|
||||
string guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Error" + guid, (result) =>
|
||||
BridgeConnector.Socket.Once<string>(socketEventName + "Error" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result.ToString());
|
||||
taskCompletionSource.SetException(new Exception($"Host Hook Exception {result}"));
|
||||
Electron.Dialog.ShowErrorBox("Host Hook Exception", result);
|
||||
tcs.SetException(new Exception($"Host Hook Exception {result}"));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.On(socketEventName + "Complete" + guid, (result) =>
|
||||
BridgeConnector.Socket.Once<JsonElement>(socketEventName + "Complete" + guid, (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off(socketEventName + "Error" + guid);
|
||||
BridgeConnector.Socket.Off(socketEventName + "Complete" + guid);
|
||||
T data = default;
|
||||
|
||||
try
|
||||
{
|
||||
if (result.GetType().IsValueType || result is string)
|
||||
{
|
||||
data = (T)result;
|
||||
}
|
||||
else
|
||||
{
|
||||
var token = JToken.Parse(result.ToString());
|
||||
if (token is JArray)
|
||||
{
|
||||
data = token.ToObject<T>();
|
||||
}
|
||||
else if (token is JObject)
|
||||
{
|
||||
data = token.ToObject<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (T)result;
|
||||
}
|
||||
}
|
||||
data = result.Deserialize<T>(ElectronJson.Options);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
taskCompletionSource.SetException(exception);
|
||||
//throw new InvalidCastException("Return value does not match with the generic type.", exception);
|
||||
tcs.SetException(exception);
|
||||
}
|
||||
|
||||
taskCompletionSource.SetResult(data);
|
||||
tcs.SetResult(data);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit(socketEventName, arguments, guid);
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -17,17 +15,19 @@ namespace ElectronNET.API
|
||||
private static IpcMain _ipcMain;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal IpcMain() { }
|
||||
internal IpcMain()
|
||||
{
|
||||
}
|
||||
|
||||
internal static IpcMain Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_ipcMain == null)
|
||||
if (_ipcMain == null)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if(_ipcMain == null)
|
||||
if (_ipcMain == null)
|
||||
{
|
||||
_ipcMain = new IpcMain();
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...).
|
||||
/// </summary>
|
||||
/// <param name="channel">Channelname.</param>
|
||||
@@ -48,11 +48,11 @@ namespace ElectronNET.API
|
||||
{
|
||||
await BridgeConnector.Socket.Emit("registerIpcMainChannel", channel).ConfigureAwait(false);
|
||||
BridgeConnector.Socket.Off(channel);
|
||||
BridgeConnector.Socket.On(channel, (args) =>
|
||||
BridgeConnector.Socket.On<JsonElement>(channel, (args) =>
|
||||
{
|
||||
List<object> objectArray = FormatArguments(args);
|
||||
|
||||
if(objectArray.Count == 1)
|
||||
if (objectArray.Count == 1)
|
||||
{
|
||||
listener(objectArray.First());
|
||||
}
|
||||
@@ -63,24 +63,15 @@ namespace ElectronNET.API
|
||||
});
|
||||
}
|
||||
|
||||
private List<object> FormatArguments(object args)
|
||||
private static List<object> FormatArguments(JsonElement args)
|
||||
{
|
||||
List<object> objectArray = ((JArray)args).ToObject<object[]>().ToList();
|
||||
|
||||
for (int index = 0; index < objectArray.Count; index++)
|
||||
{
|
||||
var item = objectArray[index];
|
||||
if (item == null)
|
||||
{
|
||||
objectArray.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
var objectArray = args.Deserialize<object[]>(ElectronJson.Options).ToList();
|
||||
objectArray.RemoveAll(item => item is null);
|
||||
return objectArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a message to the renderer process synchronously via channel,
|
||||
/// 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,
|
||||
@@ -91,7 +82,8 @@ namespace ElectronNET.API
|
||||
public void OnSync(string channel, Func<object, object> listener)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("registerSyncIpcMainChannel", channel);
|
||||
BridgeConnector.Socket.On(channel, (args) => {
|
||||
BridgeConnector.Socket.On<JsonElement>(channel, (args) =>
|
||||
{
|
||||
List<object> objectArray = FormatArguments(args);
|
||||
object parameter;
|
||||
if (objectArray.Count == 1)
|
||||
@@ -117,7 +109,7 @@ namespace ElectronNET.API
|
||||
public void Once(string channel, Action<object> listener)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("registerOnceIpcMainChannel", channel);
|
||||
BridgeConnector.Socket.Once<object>(channel, (args) =>
|
||||
BridgeConnector.Socket.Once<JsonElement>(channel, (args) =>
|
||||
{
|
||||
List<object> objectArray = FormatArguments(args);
|
||||
|
||||
@@ -152,32 +144,7 @@ namespace ElectronNET.API
|
||||
/// <param name="data">Arguments data.</param>
|
||||
public void Send(BrowserWindow browserWindow, string channel, params object[] data)
|
||||
{
|
||||
List<JObject> jobjects = new List<JObject>();
|
||||
List<JArray> jarrays = new List<JArray>();
|
||||
List<object> objects = new List<object>();
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
|
||||
{
|
||||
jarrays.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
{
|
||||
jobjects.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
{
|
||||
objects.Add(parameterObject);
|
||||
}
|
||||
}
|
||||
|
||||
if(jobjects.Count > 0 || jarrays.Count > 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, jarrays.ToArray(), jobjects.ToArray(), objects.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data);
|
||||
}
|
||||
BridgeConnector.Socket.Emit("sendToIpcRenderer", browserWindow, channel, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -191,39 +158,7 @@ namespace ElectronNET.API
|
||||
/// <param name="data">Arguments data.</param>
|
||||
public void Send(BrowserView browserView, string channel, params object[] data)
|
||||
{
|
||||
List<JObject> jobjects = new List<JObject>();
|
||||
List<JArray> jarrays = new List<JArray>();
|
||||
List<object> objects = new List<object>();
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
|
||||
{
|
||||
jarrays.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
{
|
||||
jobjects.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
{
|
||||
objects.Add(parameterObject);
|
||||
}
|
||||
}
|
||||
|
||||
if(jobjects.Count > 0 || jarrays.Count > 0)
|
||||
{
|
||||
BridgeConnector.Socket.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, jarrays.ToArray(), jobjects.ToArray(), objects.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Socket.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, data);
|
||||
}
|
||||
BridgeConnector.Socket.Emit("sendToIpcRendererBrowserView", browserView.Id, channel, data);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Extensions;
|
||||
using System.Linq;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -17,7 +16,9 @@ namespace ElectronNET.API
|
||||
private static Menu _menu;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Menu() { }
|
||||
internal Menu()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Menu Instance
|
||||
{
|
||||
@@ -27,7 +28,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if(_menu == null)
|
||||
if (_menu == null)
|
||||
{
|
||||
_menu = new Menu();
|
||||
}
|
||||
@@ -44,7 +45,14 @@ namespace ElectronNET.API
|
||||
/// <value>
|
||||
/// The menu items.
|
||||
/// </value>
|
||||
public IReadOnlyCollection<MenuItem> MenuItems { get { return _menuItems.AsReadOnly(); } }
|
||||
public IReadOnlyCollection<MenuItem> MenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return _menuItems.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
private List<MenuItem> _menuItems = new List<MenuItem>();
|
||||
|
||||
/// <summary>
|
||||
@@ -58,12 +66,13 @@ namespace ElectronNET.API
|
||||
menuItems.AddMenuItemsId();
|
||||
menuItems.AddSubmenuTypes();
|
||||
|
||||
BridgeConnector.Socket.Emit("menu-setApplicationMenu", JArray.FromObject(menuItems, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("menu-setApplicationMenu", new[] { menuItems });
|
||||
_menuItems.AddRange(menuItems);
|
||||
|
||||
BridgeConnector.Socket.Off("menuItemClicked");
|
||||
BridgeConnector.Socket.On("menuItemClicked", (id) => {
|
||||
MenuItem menuItem = _menuItems.GetMenuItem(id.ToString());
|
||||
BridgeConnector.Socket.On<string>("menuItemClicked", (id) =>
|
||||
{
|
||||
MenuItem menuItem = _menuItems.GetMenuItem(id);
|
||||
menuItem.Click?.Invoke();
|
||||
});
|
||||
}
|
||||
@@ -75,6 +84,7 @@ namespace ElectronNET.API
|
||||
/// The context menu items.
|
||||
/// </value>
|
||||
public IReadOnlyDictionary<int, ReadOnlyCollection<MenuItem>> ContextMenuItems { get; internal set; }
|
||||
|
||||
private Dictionary<int, List<MenuItem>> _contextMenuItems = new Dictionary<int, List<MenuItem>>();
|
||||
|
||||
/// <summary>
|
||||
@@ -87,7 +97,7 @@ namespace ElectronNET.API
|
||||
menuItems.AddMenuItemsId();
|
||||
menuItems.AddSubmenuTypes();
|
||||
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, JArray.FromObject(menuItems, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("menu-setContextMenu", browserWindow.Id, menuItems);
|
||||
|
||||
if (!_contextMenuItems.ContainsKey(browserWindow.Id))
|
||||
{
|
||||
@@ -97,10 +107,14 @@ namespace ElectronNET.API
|
||||
}
|
||||
|
||||
BridgeConnector.Socket.Off("contextMenuItemClicked");
|
||||
BridgeConnector.Socket.On("contextMenuItemClicked", (results) =>
|
||||
BridgeConnector.Socket.On<JsonElement>("contextMenuItemClicked", (results) =>
|
||||
{
|
||||
var id = ((JArray)results).First.ToString();
|
||||
var browserWindowId = (int)((JArray)results).Last;
|
||||
var arr = results.EnumerateArray();
|
||||
var e = arr.GetEnumerator();
|
||||
e.MoveNext();
|
||||
var id = e.Current.GetString();
|
||||
e.MoveNext();
|
||||
var browserWindowId = e.Current.GetInt32();
|
||||
|
||||
MenuItem menuItem = _contextMenuItems[browserWindowId].GetMenuItem(id);
|
||||
menuItem.Click?.Invoke();
|
||||
@@ -115,11 +129,5 @@ namespace ElectronNET.API
|
||||
{
|
||||
BridgeConnector.Socket.Emit("menu-contextMenuPopup", browserWindow.Id);
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Extensions;
|
||||
using ElectronNET.Common;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Read and respond to changes in Chromium's native color theme.
|
||||
/// </summary>
|
||||
public sealed class NativeTheme
|
||||
public sealed class NativeTheme : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
|
||||
private static NativeTheme _nativeTheme;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal NativeTheme() { }
|
||||
internal NativeTheme()
|
||||
{
|
||||
}
|
||||
|
||||
internal static NativeTheme Instance
|
||||
{
|
||||
@@ -54,7 +60,7 @@ namespace ElectronNET.API
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para/>
|
||||
/// Settings this property to <see cref="ThemeSourceMode.Light"/> will have the following effects:
|
||||
@@ -74,7 +80,7 @@ namespace ElectronNET.API
|
||||
/// <item>
|
||||
/// <description>The 'updated' event will be emitted</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </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">
|
||||
@@ -102,81 +108,30 @@ namespace ElectronNET.API
|
||||
/// 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>
|
||||
public Task<ThemeSourceMode> GetThemeSourceAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ThemeSourceMode>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-themeSource-getCompleted", (themeSource) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("nativeTheme-themeSource-getCompleted");
|
||||
|
||||
var themeSourceValue = (ThemeSourceMode)Enum.Parse(typeof(ThemeSourceMode), (string)themeSource, true);
|
||||
|
||||
taskCompletionSource.SetResult(themeSourceValue);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-themeSource-get");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<ThemeSourceMode> GetThemeSourceAsync() => this.InvokeAsync<ThemeSourceMode>();
|
||||
|
||||
/// <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>
|
||||
public Task<bool> ShouldUseDarkColorsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-shouldUseDarkColors-completed", (shouldUseDarkColors) => {
|
||||
BridgeConnector.Socket.Off("nativeTheme-shouldUseDarkColors-completed");
|
||||
|
||||
taskCompletionSource.SetResult((bool)shouldUseDarkColors);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-shouldUseDarkColors");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<bool> ShouldUseDarkColorsAsync() => this.InvokeAsync<bool>();
|
||||
|
||||
/// <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>
|
||||
public Task<bool> ShouldUseHighContrastColorsAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-shouldUseHighContrastColors-completed", (shouldUseHighContrastColors) => {
|
||||
BridgeConnector.Socket.Off("nativeTheme-shouldUseHighContrastColors-completed");
|
||||
|
||||
taskCompletionSource.SetResult((bool)shouldUseHighContrastColors);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-shouldUseHighContrastColors");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public Task<bool> ShouldUseHighContrastColorsAsync() => this.InvokeAsync<bool>();
|
||||
|
||||
/// <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>
|
||||
public Task<bool> ShouldUseInvertedColorSchemeAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("nativeTheme-shouldUseInvertedColorScheme-completed", (shouldUseInvertedColorScheme) => {
|
||||
BridgeConnector.Socket.Off("nativeTheme-shouldUseInvertedColorScheme-completed");
|
||||
|
||||
taskCompletionSource.SetResult((bool)shouldUseInvertedColorScheme);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("nativeTheme-shouldUseInvertedColorScheme");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public Task<bool> ShouldUseInvertedColorSchemeAsync() => this.InvokeAsync<bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when something in the underlying NativeTheme has changed. This normally means that either the value of <see cref="ShouldUseDarkColorsAsync"/>,
|
||||
@@ -184,10 +139,8 @@ namespace ElectronNET.API
|
||||
/// </summary>
|
||||
public event Action Updated
|
||||
{
|
||||
add => ApiEventManager.AddEvent("nativeTheme-updated", GetHashCode(), _updated, value);
|
||||
remove => ApiEventManager.RemoveEvent("nativeTheme-updated", GetHashCode(), _updated, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action _updated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -12,12 +9,15 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Create OS desktop notifications
|
||||
/// </summary>
|
||||
public sealed class Notification
|
||||
public sealed class Notification : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.NoDashUpperFirst;
|
||||
private static Notification _notification;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Notification() { }
|
||||
internal Notification()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Notification Instance
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace ElectronNET.API
|
||||
{
|
||||
GenerateIDsForDefinedActions(notificationOptions);
|
||||
|
||||
BridgeConnector.Socket.Emit("createNotification", JObject.FromObject(notificationOptions, _jsonSerializer));
|
||||
BridgeConnector.Socket.Emit("createNotification", notificationOptions);
|
||||
}
|
||||
|
||||
private static void GenerateIDsForDefinedActions(NotificationOptions notificationOptions)
|
||||
@@ -61,9 +61,7 @@ namespace ElectronNET.API
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Socket.Off("NotificationEventShow");
|
||||
BridgeConnector.Socket.On("NotificationEventShow", (id) => {
|
||||
_notificationOptions.Single(x => x.ShowID == id.ToString()).OnShow();
|
||||
});
|
||||
BridgeConnector.Socket.On<string>("NotificationEventShow", (id) => { _notificationOptions.Single(x => x.ShowID == id).OnShow(); });
|
||||
}
|
||||
|
||||
if (notificationOptions.OnClick != null)
|
||||
@@ -72,9 +70,7 @@ namespace ElectronNET.API
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Socket.Off("NotificationEventClick");
|
||||
BridgeConnector.Socket.On("NotificationEventClick", (id) => {
|
||||
_notificationOptions.Single(x => x.ClickID == id.ToString()).OnClick();
|
||||
});
|
||||
BridgeConnector.Socket.On<string>("NotificationEventClick", (id) => { _notificationOptions.Single(x => x.ClickID == id).OnClick(); });
|
||||
}
|
||||
|
||||
if (notificationOptions.OnClose != null)
|
||||
@@ -83,9 +79,7 @@ namespace ElectronNET.API
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Socket.Off("NotificationEventClose");
|
||||
BridgeConnector.Socket.On("NotificationEventClose", (id) => {
|
||||
_notificationOptions.Single(x => x.CloseID == id.ToString()).OnClose();
|
||||
});
|
||||
BridgeConnector.Socket.On<string>("NotificationEventClose", (id) => { _notificationOptions.Single(x => x.CloseID == id).OnClose(); });
|
||||
}
|
||||
|
||||
if (notificationOptions.OnReply != null)
|
||||
@@ -94,10 +88,7 @@ namespace ElectronNET.API
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Socket.Off("NotificationEventReply");
|
||||
BridgeConnector.Socket.On("NotificationEventReply", (args) => {
|
||||
var arguments = ((JArray)args).ToObject<string[]>();
|
||||
_notificationOptions.Single(x => x.ReplyID == arguments[0].ToString()).OnReply(arguments[1].ToString());
|
||||
});
|
||||
BridgeConnector.Socket.On<string[]>("NotificationEventReply", (args) => { _notificationOptions.Single(x => x.ReplyID == args[0]).OnReply(args[1]); });
|
||||
}
|
||||
|
||||
if (notificationOptions.OnAction != null)
|
||||
@@ -106,10 +97,7 @@ namespace ElectronNET.API
|
||||
isActionDefined = true;
|
||||
|
||||
BridgeConnector.Socket.Off("NotificationEventAction");
|
||||
BridgeConnector.Socket.On("NotificationEventAction", (args) => {
|
||||
var arguments = ((JArray)args).ToObject<string[]>();
|
||||
_notificationOptions.Single(x => x.ReplyID == arguments[0].ToString()).OnAction(arguments[1].ToString());
|
||||
});
|
||||
BridgeConnector.Socket.On<string[]>("NotificationEventAction", (args) => { _notificationOptions.Single(x => x.ActionID == args[0]).OnAction(args[1]); });
|
||||
}
|
||||
|
||||
if (isActionDefined)
|
||||
@@ -122,26 +110,6 @@ namespace ElectronNET.API
|
||||
/// Whether or not desktop notifications are supported on the current system.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<bool> IsSupportedAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("notificationIsSupportedComplete", (isSupported) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("notificationIsSupportedComplete");
|
||||
taskCompletionSource.SetResult((bool)isSupported);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("notificationIsSupported");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
public Task<bool> IsSupportedAsync() => this.InvokeAsync<bool>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.Common;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace ElectronNET.API
|
||||
@@ -8,92 +8,93 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// Monitor power state changes..
|
||||
/// </summary>
|
||||
public sealed class PowerMonitor
|
||||
public sealed class PowerMonitor : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to lock the screen.
|
||||
/// Emitted when the system is about to lock the screen.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public event Action OnLockScreen
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-lock-screen", string.Empty, _lockScreen, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-lock-screen", string.Empty, _lockScreen, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _lockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is about to unlock the screen.
|
||||
/// Emitted when the system is about to unlock the screen.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public event Action OnUnLockScreen
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-unlock-screen", string.Empty, _unlockScreen, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-unlock-screen", string.Empty, _unlockScreen, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _unlockScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system is suspending.
|
||||
/// </summary>
|
||||
public event Action OnSuspend
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-suspend", string.Empty, _suspend, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-suspend", string.Empty, _suspend, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _suspend;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system is resuming.
|
||||
/// </summary>
|
||||
public event Action OnResume
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-resume", string.Empty, _resume, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-resume", string.Empty, _resume, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _resume;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when the system changes to AC power.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public event Action OnAC
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-on-ac", string.Empty, _onAC, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-on-ac", string.Empty, _onAC, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _onAC;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when system changes to battery power.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("macOS")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
public event Action OnBattery
|
||||
{
|
||||
add => ApiEventManager.AddEvent("pm-on-battery", string.Empty, _onBattery, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-on-battery", string.Empty, _onBattery, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
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 => ApiEventManager.AddEvent("pm-shutdown", string.Empty, _shutdown, value);
|
||||
remove => ApiEventManager.RemoveEvent("pm-shutdown", string.Empty, _shutdown, value);
|
||||
add => AddEvent(value);
|
||||
remove => RemoveEvent(value);
|
||||
}
|
||||
|
||||
private event Action _shutdown;
|
||||
|
||||
private static PowerMonitor _powerMonitor;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal PowerMonitor() { }
|
||||
internal PowerMonitor()
|
||||
{
|
||||
}
|
||||
|
||||
internal static PowerMonitor Instance
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ElectronNET.API.Entities;
|
||||
using ElectronNET.API.Serialization;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
@@ -10,9 +9,14 @@ namespace ElectronNET.API
|
||||
/// Electron's process object is extended from the Node.js process object. It adds the
|
||||
/// events, properties, and methods.
|
||||
/// </summary>
|
||||
public sealed class Process
|
||||
public sealed class Process : ApiBase
|
||||
{
|
||||
internal Process() { }
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
|
||||
internal Process()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Process Instance
|
||||
{
|
||||
@@ -40,23 +44,8 @@ namespace ElectronNET.API
|
||||
/// <summary>
|
||||
/// The process.execPath property returns the absolute pathname of the executable that
|
||||
/// started the Node.js process. Symbolic links, if any, are resolved.
|
||||
/// </summary>
|
||||
public Task<string> ExecPathAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("process-execPath-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-execPath-Completed");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-execPath");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
/// </summary>
|
||||
public Task<string> ExecPathAsync => this.InvokeAsync<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The process.argv property returns an array containing the command-line arguments passed
|
||||
@@ -65,210 +54,56 @@ namespace ElectronNET.API
|
||||
/// will be the path to the JavaScript file being executed. The remaining elements will be
|
||||
/// any additional command-line arguments
|
||||
/// </summary>
|
||||
public Task<string[]> ArgvAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string[]>();
|
||||
|
||||
BridgeConnector.Socket.On("process-argv-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-argv-Completed");
|
||||
taskCompletionSource.SetResult(((JArray)result).ToObject<string[]>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-argv");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<string[]> ArgvAsync => this.InvokeAsync<string[]>();
|
||||
|
||||
/// <summary>
|
||||
/// The process.execPath property returns the absolute pathname of the executable that
|
||||
/// started the Node.js process. Symbolic links, if any, are resolved.
|
||||
/// </summary>
|
||||
public Task<string> TypeAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
public Task<string> TypeAsync => this.InvokeAsync<string>();
|
||||
|
||||
BridgeConnector.Socket.On("process-type-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-type-Completed");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-type");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The process.versions property returns an object listing the version strings of
|
||||
/// chrome and electron.
|
||||
/// </summary>
|
||||
public Task<ProcessVersions> VersionsAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<ProcessVersions>();
|
||||
/// </summary>
|
||||
public Task<ProcessVersions> VersionsAsync => this.InvokeAsync<ProcessVersions>();
|
||||
|
||||
BridgeConnector.Socket.On("process-versions-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-versions-Completed");
|
||||
taskCompletionSource.SetResult(((JObject)result).ToObject<ProcessVersions>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-versions");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A Boolean. When app is started by being passed as parameter to the default app, this
|
||||
/// property is true in the main process, otherwise it is false.
|
||||
/// </summary>
|
||||
public Task<bool> DefaultAppAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("process-defaultApp-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-defaultApp-Completed");
|
||||
taskCompletionSource.SetResult(bool.Parse(result.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-defaultApp");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<bool> DefaultAppAsync => this.InvokeAsync<bool>();
|
||||
|
||||
/// <summary>
|
||||
/// A Boolean, true when the current renderer context is the "main" renderer frame. If you
|
||||
/// want the ID of the current frame you should use webFrame.routingId
|
||||
/// </summary>
|
||||
public Task<bool> IsMainFrameAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
BridgeConnector.Socket.On("process-isMainFrame-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-isMainFrame-Completed");
|
||||
taskCompletionSource.SetResult(bool.Parse(result.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-isMainFrame");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<bool> IsMainFrameAsync => this.InvokeAsync<bool>();
|
||||
|
||||
/// <summary>
|
||||
/// A String representing the path to the resources directory.
|
||||
/// </summary>
|
||||
public Task<string> ResourcesPathAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("process-resourcesPath-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-resourcesPath-Completed");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-resourcesPath");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<string> ResourcesPathAsync => this.InvokeAsync<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The number of seconds the current Node.js process has been running. The return value
|
||||
/// includes fractions of a second. Use Math.floor() to get whole seconds.
|
||||
/// </summary>
|
||||
public Task<double> UpTimeAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<double>();
|
||||
|
||||
BridgeConnector.Socket.On("process-uptime-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-uptime-Completed");
|
||||
taskCompletionSource.SetResult(double.Parse(result.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-uptime");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<double> UpTimeAsync => this.InvokeAsync<double>();
|
||||
|
||||
/// <summary>
|
||||
/// The PID of the electron process
|
||||
/// </summary>
|
||||
public Task<int> PidAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<int>();
|
||||
|
||||
BridgeConnector.Socket.On("process-pid-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-pid-Completed");
|
||||
taskCompletionSource.SetResult(int.Parse(result.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-pid");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<int> PidAsync => this.InvokeAsync<int>();
|
||||
|
||||
/// <summary>
|
||||
/// The operating system CPU architecture for which the Node.js binary was compiled
|
||||
/// </summary>
|
||||
public Task<string> ArchAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("process-arch-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-arch-Completed");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-arch");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
public Task<string> ArchAsync => this.InvokeAsync<string>();
|
||||
|
||||
/// <summary>
|
||||
/// A string identifying the operating system platform on which the Node.js process is running
|
||||
/// </summary>
|
||||
public Task<string> PlatformAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<string>();
|
||||
|
||||
BridgeConnector.Socket.On("process-platform-Completed", (result) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("process-platform-Completed");
|
||||
taskCompletionSource.SetResult(result.ToString());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("process-platform");
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<string> PlatformAsync => this.InvokeAsync<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,74 @@
|
||||
using ElectronNET.API.Entities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ElectronNET.API.Entities;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.Common;
|
||||
using ElectronNET.API.Serialization;
|
||||
|
||||
namespace ElectronNET.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve information about screen size, displays, cursor position, etc.
|
||||
/// </summary>
|
||||
public sealed class Screen
|
||||
public sealed class Screen : ApiBase
|
||||
{
|
||||
protected override SocketTaskEventNameTypes SocketTaskEventNameType => SocketTaskEventNameTypes.DashesLowerFirst;
|
||||
protected override SocketTaskMessageNameTypes SocketTaskMessageNameType => SocketTaskMessageNameTypes.DashesLowerFirst;
|
||||
protected override SocketEventNameTypes SocketEventNameType => SocketEventNameTypes.DashedLower;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when an new Display has been added.
|
||||
/// </summary>
|
||||
public event Action<Display> OnDisplayAdded
|
||||
{
|
||||
add => ApiEventManager.AddEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value, (args) => ((JObject)args).ToObject<Display>());
|
||||
remove => ApiEventManager.RemoveEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private event Action<Display> _onDisplayAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Emitted when oldDisplay has been removed.
|
||||
/// </summary>
|
||||
public event Action<Display> OnDisplayRemoved
|
||||
{
|
||||
add => ApiEventManager.AddEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value, (args) => ((JObject)args).ToObject<Display>());
|
||||
remove => ApiEventManager.RemoveEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value);
|
||||
add => AddEvent(value, GetHashCode());
|
||||
remove => RemoveEvent(value, GetHashCode());
|
||||
}
|
||||
|
||||
private 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.
|
||||
/// 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>
|
||||
public event Action<Display, string[]> OnDisplayMetricsChanged
|
||||
{
|
||||
add => ApiEventManager.AddScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value);
|
||||
remove => ApiEventManager.RemoveScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value);
|
||||
add
|
||||
{
|
||||
if (_onDisplayMetricsChanged == null)
|
||||
{
|
||||
BridgeConnector.Socket.On<JsonElement>("screen-display-metrics-changed" + GetHashCode(), (args) =>
|
||||
{
|
||||
var arr = args.EnumerateArray().ToArray();
|
||||
var display = arr[0].Deserialize(ElectronJsonContext.Default.Display);
|
||||
var metrics = arr[1].Deserialize<string[]>(ElectronJson.Options);
|
||||
|
||||
_onDisplayMetricsChanged(display, metrics);
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("register-screen-display-metrics-changed", GetHashCode());
|
||||
}
|
||||
|
||||
_onDisplayMetricsChanged += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_onDisplayMetricsChanged -= value;
|
||||
|
||||
if (_onDisplayMetricsChanged == null)
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-display-metrics-changed" + GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private event Action<Display, string[]> _onDisplayMetricsChanged;
|
||||
@@ -51,7 +76,9 @@ namespace ElectronNET.API
|
||||
private static Screen _screen;
|
||||
private static object _syncRoot = new object();
|
||||
|
||||
internal Screen() { }
|
||||
internal Screen()
|
||||
{
|
||||
}
|
||||
|
||||
internal static Screen Instance
|
||||
{
|
||||
@@ -76,128 +103,38 @@ namespace ElectronNET.API
|
||||
/// The current absolute position of the mouse pointer.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<Point> GetCursorScreenPointAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Point>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getCursorScreenPointCompleted", (point) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getCursorScreenPointCompleted");
|
||||
|
||||
taskCompletionSource.SetResult(((JObject)point).ToObject<Point>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getCursorScreenPoint");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<Point> GetCursorScreenPointAsync() => this.InvokeAsync<Point>();
|
||||
|
||||
/// <summary>
|
||||
/// macOS: The height of the menu bar in pixels.
|
||||
/// </summary>
|
||||
/// <returns>The height of the menu bar in pixels.</returns>
|
||||
public Task<int> GetMenuBarHeightAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<int>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getMenuBarHeightCompleted", (height) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getMenuBarHeightCompleted");
|
||||
|
||||
taskCompletionSource.SetResult(int.Parse(height.ToString()));
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getMenuBarHeight");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
[SupportedOSPlatform("macOS")]
|
||||
public Task<Rectangle> GetMenuBarWorkAreaAsync() => this.InvokeAsync<Rectangle>();
|
||||
|
||||
/// <summary>
|
||||
/// The primary display.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<Display> GetPrimaryDisplayAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Display>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getPrimaryDisplayCompleted", (display) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getPrimaryDisplayCompleted");
|
||||
|
||||
taskCompletionSource.SetResult(((JObject)display).ToObject<Display>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getPrimaryDisplay");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<Display> GetPrimaryDisplayAsync() => this.InvokeAsync<Display>();
|
||||
|
||||
/// <summary>
|
||||
/// An array of displays that are currently available.
|
||||
/// </summary>
|
||||
/// <returns>An array of displays that are currently available.</returns>
|
||||
public Task<Display[]> GetAllDisplaysAsync()
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Display[]>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getAllDisplaysCompleted", (displays) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getAllDisplaysCompleted");
|
||||
|
||||
taskCompletionSource.SetResult(((JArray)displays).ToObject<Display[]>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getAllDisplays");
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<Display[]> GetAllDisplaysAsync() => this.InvokeAsync<Display[]>();
|
||||
|
||||
/// <summary>
|
||||
/// The display nearest the specified point.
|
||||
/// </summary>
|
||||
/// <returns>The display nearest the specified point.</returns>
|
||||
public Task<Display> GetDisplayNearestPointAsync(Point point)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Display>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getDisplayNearestPointCompleted", (display) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getDisplayNearestPointCompleted");
|
||||
|
||||
taskCompletionSource.SetResult(((JObject)display).ToObject<Display>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getDisplayNearestPoint", JObject.FromObject(point, _jsonSerializer));
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
public Task<Display> GetDisplayNearestPointAsync(Point point) => this.InvokeAsync<Display>(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>
|
||||
public Task<Display> GetDisplayMatchingAsync(Rectangle rectangle)
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<Display>();
|
||||
|
||||
BridgeConnector.Socket.On("screen-getDisplayMatching", (display) =>
|
||||
{
|
||||
BridgeConnector.Socket.Off("screen-getDisplayMatching");
|
||||
|
||||
taskCompletionSource.SetResult(((JObject)display).ToObject<Display>());
|
||||
});
|
||||
|
||||
BridgeConnector.Socket.Emit("screen-getDisplayMatching", JObject.FromObject(rectangle, _jsonSerializer));
|
||||
|
||||
return taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore
|
||||
};
|
||||
public Task<Display> GetDisplayMatchingAsync(Rectangle rectangle) => this.InvokeAsync<Display>(rectangle);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user