From 74b80b31771a045ac3d6f3ee8142787710956379 Mon Sep 17 00:00:00 2001 From: softworkz Date: Mon, 13 Oct 2025 13:05:34 +0200 Subject: [PATCH] Add ElectronNET project (all build functionality) --- src/ElectronNET/ElectronNET.csproj | 47 ++ .../PackageIcon.png | Bin src/ElectronNET/build/ElectronNET.Build.dll | Bin 0 -> 8192 bytes src/ElectronNET/build/ElectronNET.Core.props | 6 + .../build/ElectronNET.Core.targets | 6 + .../build/ElectronNET.DesignTime.targets | 129 ++++ .../build/ElectronNET.LateImport.targets | 480 +++++++++++++++ src/ElectronNET/build/ElectronNET.props | 32 + src/ElectronNET/build/ElectronNET.targets | 26 + .../build/ElectronNETRules.Project.xaml | 566 ++++++++++++++++++ .../build/ElectronNETRules.Project2.xaml | 62 ++ src/ElectronNET/build/electron-builder.json | 19 + src/ElectronNET/build/package.template.json | 48 ++ .../build/update_electron_versions.py | 131 ++++ 14 files changed, 1552 insertions(+) create mode 100644 src/ElectronNET/ElectronNET.csproj rename src/{ElectronNET.CLI => ElectronNET}/PackageIcon.png (100%) create mode 100644 src/ElectronNET/build/ElectronNET.Build.dll create mode 100644 src/ElectronNET/build/ElectronNET.Core.props create mode 100644 src/ElectronNET/build/ElectronNET.Core.targets create mode 100644 src/ElectronNET/build/ElectronNET.DesignTime.targets create mode 100644 src/ElectronNET/build/ElectronNET.LateImport.targets create mode 100644 src/ElectronNET/build/ElectronNET.props create mode 100644 src/ElectronNET/build/ElectronNET.targets create mode 100644 src/ElectronNET/build/ElectronNETRules.Project.xaml create mode 100644 src/ElectronNET/build/ElectronNETRules.Project2.xaml create mode 100644 src/ElectronNET/build/electron-builder.json create mode 100644 src/ElectronNET/build/package.template.json create mode 100644 src/ElectronNET/build/update_electron_versions.py diff --git a/src/ElectronNET/ElectronNET.csproj b/src/ElectronNET/ElectronNET.csproj new file mode 100644 index 0000000..c0a909e --- /dev/null +++ b/src/ElectronNET/ElectronNET.csproj @@ -0,0 +1,47 @@ + + + + + + net6.0;net8.0 + ..\..\artifacts + $(PackageNamePrefix) + $(PackageId) + $(DescriptionFirstPart) This package contains the ElectronNET project system. + false + false + + + + + + + + + + .electron\%(RecursiveDir)%(FileName)%(Extension) + Never + true + .electron\ + + + + + true + build\ + + + + + True + + + + + MSBuild:Compile + + + MSBuild:Compile + + + \ No newline at end of file diff --git a/src/ElectronNET.CLI/PackageIcon.png b/src/ElectronNET/PackageIcon.png similarity index 100% rename from src/ElectronNET.CLI/PackageIcon.png rename to src/ElectronNET/PackageIcon.png diff --git a/src/ElectronNET/build/ElectronNET.Build.dll b/src/ElectronNET/build/ElectronNET.Build.dll new file mode 100644 index 0000000000000000000000000000000000000000..b3794d9f7bb0bafe18af677f615c6d4daa980738 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/src/ElectronNET/build/ElectronNET.Core.props b/src/ElectronNET/build/ElectronNET.Core.props new file mode 100644 index 0000000..c9e1eed --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.Core.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/ElectronNET/build/ElectronNET.Core.targets b/src/ElectronNET/build/ElectronNET.Core.targets new file mode 100644 index 0000000..4bee510 --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.Core.targets @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/ElectronNET/build/ElectronNET.DesignTime.targets b/src/ElectronNET/build/ElectronNET.DesignTime.targets new file mode 100644 index 0000000..6f6adba --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.DesignTime.targets @@ -0,0 +1,129 @@ + + + + + True + + + + + + Project + + + + + + Project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(ElectronSplashScreen.Replace('$(MSBuildProjectDirectory)', '').TrimStart('\')) + + + + + + + + + + + + + + $(ElectronIcon.Replace('$(MSBuildProjectDirectory)', '').TrimStart('\')) + + + + + + + + + + + + + <_ProjectDir>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)'))\ + + $([System.String]::Substring($(ElectronSplashScreen), + $([System.String]::Length($(_ProjectDir))))) + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ElectronNET/build/ElectronNET.LateImport.targets b/src/ElectronNET/build/ElectronNET.LateImport.targets new file mode 100644 index 0000000..892f764 --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.LateImport.targets @@ -0,0 +1,480 @@ + + + + + + + + + + + + + + + + Never + Never + + + Never + Never + + + Never + Never + + + + + + + + + + + + + + + + + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\..\..\xxxxElectronNET.Host')) + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\..\.electron')) + .electron + $([System.IO.Path]::GetFileName($(ElectronSplashScreen))) + $([System.IO.Path]::GetFileName($(ElectronIcon))) + + + + + + + + + + + + + + + + + + + + + + + $(OutDir)$(ElectronDirName)\ + $(TargetDir)$(ElectronDirName)\ + $(IntermediateOutputPath)$(ElectronDirName)\ + $(ElectronIntermediateOutputPath)package.json + + + + + + + + <_ProjectPropertiesFolder>$(MSBuildProjectDirectory)\Properties\ + <_ElectronBuilderExpectedPath>$(_ProjectPropertiesFolder)$(ElectronBuilderJson) + <_NeedCopyElectronBuilderFile>True + <_NeedCopyElectronBuilderFile Condition="Exists($(_ElectronBuilderExpectedPath))">False + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + $(TargetName) + + + + + $([System.Text.RegularExpressions.Regex]::Replace('$(Version)', '^(\d+\.\d+\.\d+)(?:\.\d+)?(.*)$', '$1$2')) + + linux + $(Title) + $(Title.Replace(' ', '-')) + + + + + + + + + + + + + + + + + + + + + + + + + + + <_NonIntermediatePublishDir>$(PublishDir) + $(PublishDir) + $(IntermediateOutputPath)PubTmp\ + + + + + + + + + + + + + + + + false + true + + + + + + + + + + + + + $(ElectronDirName)\%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + + + + + + + + + + + + + + + + + + $(ElectronDirName)\%(RelativeDir)%(FileName)%(Extension) + + + + + + + + + + $(ElectronDirName)\%(FileName)%(Extension) + + + + + + + + + + + + + + + + + $(ElectronDirName)\%(DestinationRelativePath) + $(ElectronDirName)\%(DestinationRelativePath) + PreserveNewest + + + + + + + + + + <_ElectronFiles Include="$(ElectronSplashScreen)" Condition="'$(ElectronSplashScreen)'!=''" /> + <_ElectronFiles Include="$(ElectronIcon)" Condition="'$(ElectronIcon)'!=''" /> + + + + <_ElectronFiles Update="**"> + PreserveNewest + + + + + + + <_ElectronFilesToCopy Include="@(_ElectronFiles->'%(FullPath)')" /> + + + + + + <_ElectronFilesToCopyWithTargetPath Include="@(_ElectronFilesToCopy)"> + $(ElectronDirName)\%(FileName)%(Extension) + + + + + + + + + + + <_SourceItemsToCopyToOutputDirectoryIfDifferent Include="@(_ElectronFilesToCopyWithTargetPath)"/> + + + + + + + + $(OutDir)$(ElectronDirName)\node_modules\electron-host-hook + + + + + + + + + + + + + + + + + + $([System.IO.Path]::GetFullPath('$(ElectronOutDir)')) + linux + false + true + <_NpmCmd>npm install --no-bin-links + <_NpmCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmCmd)' + + + + + + + + + + + + + + + + + + + + + + <_OriginalPublishDir>$(PublishDir) + $(_OriginalPublishDir)bin\ + true + + + + + + + + + + + + + + <_PublishIntermediateOutputPathFiles Remove="@(_PublishIntermediateOutputPathFiles)"> + + + + + <_ElectronPublishAppAfterTarget Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true'">AfterPublish + <_ElectronPublishAppAfterTarget Condition="'$(UsingMicrosoftNETSdkWeb)' != 'true'">Publish + + + + + + $(_OriginalPublishDir) + $(_NonIntermediatePublishDir) + $(_OriginalPublishDir) + + + + + + x64 + ia32 + arm64 + x64 + armv7l + arm64 + x64 + arm64 + + win + linux + mac + + + + + + + + + + + + + + + + + + + + + + + + + + + $(ElectronPublishDir)%(RecursiveDir)%(FileName)%(Extension) + + + + + + + + + $([System.IO.Path]::GetFullPath('$(ElectronPublishDir)')) + $([System.IO.Path]::GetFullPath('$(PublishUrl.TrimEnd("\"))')) + + + + false + true + <_NpmCmd>npm install electron-builder@$(ElectronBuilderVersion) --save-dev + <_NpmCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmCmd)' + + + + + + + + + + + + + + + + + + $(ElectronPaParams) -c.appId "$(PackageId)" + $(ElectronPaParams) -c.buildVersion "$(Version)" + $(ElectronPaParams) -c.copyright "$(Copyright)" + $(ElectronPaParams) -c.extraResources "bin/**/*" + + + + <_NpxCmd>npx electron-builder --config=./$(ElectronBuilderJson) --$(ElectronPlatform) --$(ElectronArch) -c.electronVersion=$(ElectronVersion) -c.directories.output "$(ElectronPublishUrlFullPath)" $(ElectronPaParams) + <_NpxCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpxCmd)' + + + + + + + + + + + + + + + + diff --git a/src/ElectronNET/build/ElectronNET.props b/src/ElectronNET/build/ElectronNET.props new file mode 100644 index 0000000..f616fbb --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.props @@ -0,0 +1,32 @@ + + + + + 30.4.0 + 26.0 + win-x64 + true + + + + $(MSBuildProjectName.Replace(".", "-").ToLower()) + electron-builder.json + $(MSBuildProjectName) + + + + false + false + false + + + + $(MSBuildThisFileDirectory)ElectronNET.LateImport.targets + + + + $(CollectUpToDateCheckBuiltDesignTimeDependsOn);ElectronCollectUpToDateCheckBuiltDesignTime + $(FileSystemPublishDependsOn);ElectronFileSystemPublishClearItems + + + diff --git a/src/ElectronNET/build/ElectronNET.targets b/src/ElectronNET/build/ElectronNET.targets new file mode 100644 index 0000000..40c5872 --- /dev/null +++ b/src/ElectronNET/build/ElectronNET.targets @@ -0,0 +1,26 @@ + + + + + win + $(Title) + $(PackageId) + + + + <_IsMsAspNetProject>False + <_IsMsAspNetProject Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true'">True + + + + + + + + + + + + + + diff --git a/src/ElectronNET/build/ElectronNETRules.Project.xaml b/src/ElectronNET/build/ElectronNETRules.Project.xaml new file mode 100644 index 0000000..62fcb82 --- /dev/null +++ b/src/ElectronNET/build/ElectronNETRules.Project.xaml @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ElectronNET/build/ElectronNETRules.Project2.xaml b/src/ElectronNET/build/ElectronNETRules.Project2.xaml new file mode 100644 index 0000000..3a4d2f5 --- /dev/null +++ b/src/ElectronNET/build/ElectronNETRules.Project2.xaml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ElectronNET/build/electron-builder.json b/src/ElectronNET/build/electron-builder.json new file mode 100644 index 0000000..41f483c --- /dev/null +++ b/src/ElectronNET/build/electron-builder.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/refs/heads/master/packages/app-builder-lib/scheme.json", + "compression": "maximum", + "linux": { + "target": [ + "tar.xz" + ], + "executableArgs": [ "--no-sandbox" ], + "artifactName": "${name}-${arch}-${version}.${ext}" + }, + "win": { + "target": [ + { + "target": "portable", + "arch": "x64" + } + ] + } +} \ No newline at end of file diff --git a/src/ElectronNET/build/package.template.json b/src/ElectronNET/build/package.template.json new file mode 100644 index 0000000..156fab2 --- /dev/null +++ b/src/ElectronNET/build/package.template.json @@ -0,0 +1,48 @@ +{ + "name": "$(PackageId)", + "productName": "$(ElectronTitle)", + "build": { + "appId": "$(PackageId)", + "linux": { + "desktop": { + "entry": { "Name": "$(Title)" } + }, + "executableName": "$(PackageId)" + }, + "deb": { + "desktop": { + "entry": { "Name": "$(Title)" } + } + } + }, + "description": "$(Description)", + "version": "$(Version)", + "main": "main.js", + "author": { + "name": "$(Company)" + }, + "license": "$(License)", + "executable": "$(TargetName)", + "singleInstance": "$(ElectronSingleInstance)", + "homepage": "$(ProjectUrl)", + "splashscreen": { + "imageFile": "$(ElectronSplashScreen)" + }, + "scripts": { + "start": "tsc -p ." + }, + "dependencies": { + "dasherize": "^2.0.0", + "electron-updater": "^6.6.2", + "image-size": "^1.2.1", + "portscanner": "^2.2.0", + "socket.io": "^4.8.1", + "electron-host-hook": "file:./ElectronHostHook" + }, + "devDependencies": { + "@types/node": "^22.18", + "electron": "$(ElectronVersion)", + "eslint": "^9.37.0", + "typescript": "^5.9.3" + } +} \ No newline at end of file diff --git a/src/ElectronNET/build/update_electron_versions.py b/src/ElectronNET/build/update_electron_versions.py new file mode 100644 index 0000000..beeee44 --- /dev/null +++ b/src/ElectronNET/build/update_electron_versions.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +""" +Update Electron version list in ElectronNETRules.Project.xaml + +This script: +1. Downloads the Electron releases feed from GitHub +2. Filters for stable releases >= 23.0.0 +3. Generates the ElectronVersion enum XML +4. Updates the XAML file with the new version list +""" + +import json +import re +import urllib.request +from pathlib import Path + + +def download_releases(): + """Download Electron releases JSON from GitHub.""" + url = "https://releases.electronjs.org/releases.json" + print(f"Downloading releases from {url}...") + + with urllib.request.urlopen(url) as response: + data = response.read() + + print(f"Downloaded {len(data)} bytes") + return json.loads(data) + + +def filter_versions(releases, min_version="23.0.0"): + """Filter and sort stable Electron versions.""" + print(f"Filtering versions >= {min_version}...") + + # Regular expression for stable versions (major.minor.patch) + stable_pattern = re.compile(r'^\d+\.\d+\.\d+$') + + # Parse minimum version + min_parts = tuple(map(int, min_version.split('.'))) + + # Filter and collect versions + versions = set() + for release in releases: + version = release.get('version', '') + if stable_pattern.match(version): + parts = tuple(map(int, version.split('.'))) + if parts >= min_parts: + versions.add(version) + + # Sort versions + sorted_versions = sorted(versions, key=lambda v: tuple(map(int, v.split('.')))) + + print(f"Found {len(sorted_versions)} stable versions") + return sorted_versions + + +def generate_enum_xml(versions): + """Generate the ElectronVersion enum property XML.""" + lines = [ + ' ', + ' ', + ] + + for version in versions: + lines.append(f' ') + + lines.append(' ') + + return '\n'.join(lines) + + +def update_xaml_file(xaml_path, enum_xml): + """Update the XAML file with the new enum.""" + print(f"Updating {xaml_path}...") + + # Read the original file + content = Path(xaml_path).read_text(encoding='utf-8') + + # Find the ElectronVersion enum markers + start_marker = '