Compare commits

..

1 Commits

Author SHA1 Message Date
Florian Rappl
bdfbcd5b77 Merge pull request #986 from ElectronNET/develop
Release 0.3.0
2025-12-14 22:13:10 +01:00
31 changed files with 93 additions and 498 deletions

View File

@@ -27,23 +27,24 @@ jobs:
run: |
echo "Inspecting jobs of workflow run $RUN_ID in $REPO"
jobs_json="$(gh api -R $REPO repos/$REPO/actions/runs/$RUN_ID/jobs)"
jobs_json="$(gh api repos/$REPO/actions/runs/$RUN_ID/jobs)"
echo "Jobs and conclusions:"
echo "$jobs_json" | jq '.jobs[] | {name: .name, conclusion: .conclusion}'
failed_matrix_jobs=$(echo "$jobs_json" | jq -r '
failed_matrix_jobs=$(echo "$jobs_json" | jq '
[ .jobs[]
| select(.conclusion == "failure"
and (.name | contains(" API-")))
]
| length // 0
| length
')
failed_matrix_jobs=${failed_matrix_jobs:-0}
if [ "${failed_matrix_jobs}" -gt 0 ]; then
echo "Failed Integration Tests matrix jobs: $failed_matrix_jobs"
if [ "$failed_matrix_jobs" -gt 0 ]; then
echo "Detected failing Integration Tests jobs re-running failed jobs for this run."
gh run rerun -R "$REPO" "$RUN_ID" --failed
gh run rerun "$RUN_ID" --failed
else
echo "Only non-matrix jobs (like Test Results) failed not auto-rerunning."
fi

View File

@@ -1,24 +1,3 @@
# 0.4.1
## ElectronNET.Core
- Fixed handling of `Center` property for windows (#1001)
- Added missing methods on `Cookies` (#1000)
# 0.4.0
## ElectronNET.Core
- Fixed ElectronSingleInstance handling (#996) @softworkz
- Fixed `PackageId` handling (#993) @softworkz
- Added cross-platform npm restore and check mismatch on publish (#988) @softworkz
# 0.3.1
## ElectronNET.Core
- Fixed issue transforming the project ID (#989, #990) @softworkz
# 0.3.0
## ElectronNET.Core

View File

@@ -8,9 +8,7 @@ When you build an Electron.NET project, the following validation checks are perf
| Code | Check | Description |
|------|-------|-------------|
| [ELECTRON001](#1-packagejson-rules) | package.json location rules | Ensures `package.json`/`package-lock.json` arent present in unsupported locations (root `package.json` handled separately) |
| [ELECTRON008](#1-packagejson-rules) | root package.json contains electron | Warns when root `package.json` contains the word `electron` (case-insensitive) |
| [ELECTRON009](#1-packagejson-rules) | root package.json copied to output | Warns when root `package.json` is configured to be copied to output/publish |
| [ELECTRON001](#1-packagejson-not-allowed) | package.json not allowed | Ensures no package.json exists outside ElectronHostHook |
| [ELECTRON002](#2-electron-manifestjson-not-allowed) | electron-manifest.json not allowed | Detects deprecated manifest files |
| [ELECTRON003](#3-electron-builderjson-location) | electron-builder.json location | Verifies electron-builder.json exists in Properties folder |
| [ELECTRON004](#3-electron-builderjson-location) | electron-builder.json wrong location | Warns if electron-builder.json is found in incorrect locations |
@@ -20,44 +18,30 @@ When you build an Electron.NET project, the following validation checks are perf
---
## 1. package.json rules
## 1. package.json not allowed
**Warning Codes:** `ELECTRON001`, `ELECTRON008`, `ELECTRON009`
**Warning Code:** `ELECTRON001`
### What is checked
The build system scans for `package.json` and `package-lock.json` files in your project directory.
Rules:
- **ELECTRON001**: `package.json` / `package-lock.json` must not exist in the project directory or subdirectories
- Exception: `ElectronHostHook` folder is allowed
- Note: a **root** `package.json` is **excluded** from `ELECTRON001` and validated by `ELECTRON008` / `ELECTRON009`
- **ELECTRON008**: If a root `package.json` exists, it must **not** contain electron-related dependencies or configuration.
- **ELECTRON009**: If a root `package.json` exists, it must **not** be configured to be copied to output/publish (for example via `CopyToOutputDirectory` / `CopyToPublishDirectory` metadata)
The build system scans for `package.json` and `package-lock.json` files in your project directory. These files should not exist in the project root or subdirectories (with one exception).
### Why this matters
Electron.NET generates its Electron-related `package.json` during publishing based on MSBuild properties. A user-maintained Electron-related `package.json` can conflict with that process.
Also, ensuring the root `package.json` is not copied prevents accidentally shipping it with the published app.
In previous versions of Electron.NET, a `package.json` file was required in the project. The new version generates this file automatically from MSBuild properties defined in your `.csproj` file.
### Exception
A `package.json` / `package-lock.json` file **is allowed** in the `ElectronHostHook` folder if you're using custom host hooks.
A `package.json` file **is allowed** in the `ElectronHostHook` folder if you're using custom host hooks. This is the only valid location for a manually maintained package.json.
### How to fix
If you have an Electron-related `package.json` from older Electron.NET versions:
1. **Open your project's `.csproj` file**
2. **Add the required properties** to a PropertyGroup with the label `ElectronNetCommon`:
```xml
<PropertyGroup Label="ElectronNetCommon">
<ElectronPackageId>my-electron-app</ElectronPackageId>
<PackageId>my-electron-app</PackageId>
<Title>My Electron App</Title>
<Version>1.0.0</Version>
<Description>My awesome Electron.NET application</Description>
@@ -67,12 +51,7 @@ If you have an Electron-related `package.json` from older Electron.NET versions:
</PropertyGroup>
```
3. **Delete** Electron-related `package.json` / `package-lock.json` files (except those under `ElectronHostHook` if applicable)
If you keep a root `package.json` for non-Electron reasons:
- Ensure it does **not** contain electron dependencies or configuration (fixes `ELECTRON008`)
- Ensure it is **not** copied to output/publish (fixes `ELECTRON009`)
3. **Delete the old `package.json`** file from your project root
> **See also:** [Migration Guide](Migration-Guide.md) for complete migration instructions.

View File

@@ -54,7 +54,7 @@ Add the Electron.NET configuration to your `.csproj` file:
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.Core" Version="0.4.1" />
<PackageReference Include="ElectronNET.Core" Version="0.3.0" />
</ItemGroup>
```

View File

@@ -25,7 +25,7 @@ These are the current default values when you don't make any changes:
<ElectronSingleInstance>true</ElectronSingleInstance>
<ElectronSplashScreen></ElectronSplashScreen>
<ElectronIcon></ElectronIcon>
<ElectronPackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</ElectronPackageId>
<PackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</PackageId>
<ElectronBuilderJson>electron-builder.json</ElectronBuilderJson>
<Title>$(MSBuildProjectName)</Title>
</PropertyGroup>
@@ -38,15 +38,15 @@ Since electron builder still expects a `package.json` file to exist, ElectronNET
```json
{
"name": "$(ElectronPackageId)",
"name": "$(PackageId)",
"productName": "$(ElectronTitle)",
"build": {
"appId": "$(ElectronPackageId)",
"appId": "$(PackageId)",
"linux": {
"desktop": {
"entry": { "Name": "$(Title)" }
},
"executableName": "$(ElectronPackageId)"
"executableName": "$(PackageId)"
},
"deb": {
"desktop": {

View File

@@ -314,9 +314,7 @@ namespace ElectronNET.API
{
if (this.tcs != null)
{
var ex = new TimeoutException(
$"No response after {(long)timeout.TotalMilliseconds}ms trying to retrieve value {apiBase.objectName}.{callerName}()"
);
var ex = new TimeoutException($"No response after {timeout:D}ms trying to retrieve value {apiBase.objectName}.{callerName}()");
this.tcs.TrySetException(ex);
this.tcs = null;
}

View File

@@ -186,19 +186,6 @@ public class BrowserWindow : ApiBase
remove => RemoveEvent(value, Id);
}
/// <summary>
/// Emitted when the window is moved or resized.
/// </summary>
/// <remarks>
/// While not being an original Electron event, this one includes the bounds values,
/// saving the additional roundtrip for calling <see cref="GetBoundsAsync"/>.
/// </remarks>
public event Action<Rectangle> OnBoundsChanged
{
add => AddEvent(value, Id);
remove => RemoveEvent(value, Id);
}
/// <summary>
/// macOS: Emitted once when the window is moved to a new position.
/// </summary>

View File

@@ -2,7 +2,6 @@ using ElectronNET.API.Entities;
using ElectronNET.API.Serialization;
using System;
using System.Text.Json;
using System.Threading.Tasks;
namespace ElectronNET.API
{
@@ -55,79 +54,10 @@ namespace ElectronNET.API
_changed -= value;
if (_changed == null)
{
BridgeConnector.Socket.Off("webContents-session-cookies-changed" + Id);
}
}
}
private event Action<Cookie, CookieChangedCause, bool> _changed;
/// <summary>
/// Sends a request to get all cookies matching filter, and resolves a callack with the response.
/// </summary>
/// <param name="filter">
/// </param>
/// <returns>A task which resolves an array of cookie objects.</returns>
public Task<Cookie[]> GetAsync(CookieFilter filter)
{
var tcs = new TaskCompletionSource<Cookie[]>();
var guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<Cookie[]>("webContents-session-cookies-get-completed" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("webContents-session-cookies-get", Id, filter, guid);
return tcs.Task;
}
/// <summary>
///
/// </summary>
/// <param name="details"></param>
/// <returns></returns>
public Task SetAsync(CookieDetails details)
{
var tcs = new TaskCompletionSource<object>();
var guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<object>("webContents-session-cookies-set-completed" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("webContents-session-cookies-set", Id, details, guid);
return tcs.Task;
}
/// <summary>
/// Removes the cookies matching url and name
/// </summary>
/// <param name="url">The URL associated with the cookie.</param>
/// <param name="name">The name of cookie to remove.</param>
/// <returns>A task which resolves when the cookie has been removed</returns>
public Task RemoveAsync(string url, string name)
{
var tcs = new TaskCompletionSource<object>();
var guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<object>("webContents-session-cookies-remove-completed" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("webContents-session-cookies-remove", Id, url, name, guid);
return tcs.Task;
}
/// <summary>
/// Writes any unwritten cookies data to disk.
/// </summary>
/// <returns>A task which resolves when the cookie store has been flushed</returns>
public Task FlushStoreAsync()
{
var tcs = new TaskCompletionSource<object>();
var guid = Guid.NewGuid().ToString();
BridgeConnector.Socket.Once<object>("webContents-session-cookies-flushStore-completed" + guid, tcs.SetResult);
BridgeConnector.Socket.Emit("webContents-session-cookies-flushStore", Id, guid);
return tcs.Task;
}
}
}

View File

@@ -24,13 +24,13 @@ namespace ElectronNET.API.Entities
/// ( if y is used) Window's left offset from screen. Default is to center the
/// window.
/// </summary>
public int? X { get; set; }
public int X { get; set; } = -1;
/// <summary>
/// ( if x is used) Window's top offset from screen. Default is to center the
/// window.
/// </summary>
public int? Y { get; set; }
public int Y { get; set; } = -1;
/// <summary>
/// The width and height would be used as web page's size, which means the actual

View File

@@ -24,7 +24,7 @@
/// <summary>
/// Gets or sets a value indicating whether the cookie is a host-only cookie; this will only be true if no domain was passed.
/// </summary>
public bool? HostOnly { get; set; }
public bool HostOnly { get; set; }
/// <summary>
/// Gets or sets the path of the cookie.
@@ -34,22 +34,22 @@
/// <summary>
/// Gets or sets a value indicating whether the cookie is marked as secure.
/// </summary>
public bool? Secure { get; set; }
public bool Secure { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the cookie is marked as HTTP only.
/// </summary>
public bool? HttpOnly { get; set; }
public bool HttpOnly { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the cookie is a session cookie or a persistent cookie with an expiration date.
/// </summary>
public bool? Session { get; set; }
public bool Session { get; set; }
/// <summary>
/// Gets or sets the expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies.
/// </summary>
public double? ExpirationDate { get; set; }
public double ExpirationDate { get; set; }
/// <summary>
/// Gets or sets the SameSite policy applied to this cookie. Can be "unspecified", "no_restriction", "lax" or "strict".

View File

@@ -29,16 +29,16 @@
/// <summary>
/// (optional) - Filters cookies by their Secure property.
/// </summary>
public bool? Secure { get; set; }
public bool Secure { get; set; }
/// <summary>
/// (optional) - Filters out session or persistent cookies.
/// </summary>
public bool? Session { get; set; }
public bool Session { get; set; }
/// <summary>
/// (optional) - Filters cookies by httpOnly.
/// </summary>
public bool? HttpOnly { get; set; }
public bool HttpOnly { get; set; }
}
}

View File

@@ -130,8 +130,11 @@ namespace ElectronNET.API
options.Height += 7;
}
if (!options.X.HasValue && !options.Y.HasValue)
if (options.X == -1 && options.Y == -1)
{
options.X = 0;
options.Y = 0;
await BridgeConnector.Socket.Emit("createBrowserWindow", options, loadUrl).ConfigureAwait(false);
}
else

View File

@@ -8,7 +8,7 @@
public string RuntimeIdentifier { get; internal set; }
public bool ElectronSingleInstance { get; internal set; }
public string ElectronSingleInstance { get; internal set; }
public string Title { get; internal set; }

View File

@@ -1,13 +1,12 @@
namespace ElectronNET.Runtime.Services.ElectronProcess
{
using ElectronNET.Common;
using ElectronNET.Runtime.Data;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ElectronNET.Common;
using ElectronNET.Runtime.Data;
/// <summary>
/// Launches and manages the Electron app process.
@@ -34,42 +33,14 @@
this.socketPort = socketPort;
}
protected override async Task StartCore()
protected override Task StartCore()
{
var dir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
string startCmd, args, workingDir;
if (this.isUnpackaged)
{
this.CheckRuntimeIdentifier();
var electrondir = Path.Combine(dir.FullName, ".electron");
ProcessRunner chmodRunner = null;
try
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var distFolder = Path.Combine(electrondir, "node_modules", "electron", "dist");
chmodRunner = new ProcessRunner("ElectronRunner-Chmod");
chmodRunner.Run("chmod", "-R +x " + distFolder, electrondir);
await chmodRunner.WaitForExitAsync().ConfigureAwait(true);
if (chmodRunner.LastExitCode != 0)
{
throw new Exception("Failed to set executable permissions on Electron dist folder.");
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine("[StartCore]: Exception: " + chmodRunner?.StandardError);
Console.Error.WriteLine("[StartCore]: Exception: " + chmodRunner?.StandardOutput);
Console.Error.WriteLine("[StartCore]: Exception: " + ex);
}
startCmd = Path.Combine(electrondir, "node_modules", "electron", "dist", "electron");
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
@@ -82,71 +53,17 @@
}
else
{
dir = dir.Parent!.Parent!;
dir = dir.Parent?.Parent;
startCmd = Path.Combine(dir.FullName, this.electronBinaryName);
args = $"-dotnetpacked -electronforcedport={this.socketPort:D} " + this.extraArguments;
workingDir = dir.FullName;
}
// We don't await this in order to let the state transition to "Starting"
Task.Run(async () => await this.StartInternal(startCmd, args, workingDir).ConfigureAwait(false));
}
private void CheckRuntimeIdentifier()
{
var buildInfoRid = ElectronNetRuntime.BuildInfo.RuntimeIdentifier;
if (string.IsNullOrEmpty(buildInfoRid))
{
return;
}
var osPart = buildInfoRid.Split('-').First();
var mismatch = false;
switch (osPart)
{
case "win":
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
mismatch = true;
}
break;
case "linux":
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
mismatch = true;
}
break;
case "osx":
if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
mismatch = true;
}
break;
case "freebsd":
if (!RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
{
mismatch = true;
}
break;
}
if (mismatch)
{
throw new PlatformNotSupportedException($"This Electron.NET application was built for '{buildInfoRid}'. It cannot run on this platform.");
}
return Task.CompletedTask;
}
protected override Task StopCore()

View File

@@ -165,9 +165,13 @@
ElectronNetRuntime.DotnetAppType = DotnetAppType.AspNetCoreApp;
}
if (bool.TryParse(isSingleInstance, out var parsedBool))
if (isSingleInstance?.Length > 0 && bool.TryParse(isSingleInstance, out var isSingleInstanceActive) && isSingleInstanceActive)
{
buildInfo.ElectronSingleInstance = parsedBool;
buildInfo.ElectronSingleInstance = "yes";
}
else
{
buildInfo.ElectronSingleInstance = "no";
}
if (httpPort?.Length > 0 && int.TryParse(httpPort, out var port))

View File

@@ -70,7 +70,7 @@
<ProjectReference Include="..\ElectronNET.API\ElectronNET.API.csproj" Condition="$(ElectronNetDevMode)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.Core" Version="0.4.1" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core" Version="0.3.0" Condition="'$(ElectronNetDevMode)' != 'true'" />
</ItemGroup>
<Import Project="..\ElectronNET\build\ElectronNET.Core.targets" Condition="$(ElectronNetDevMode)" />

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.3864779">
<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.4110890">
<ItemGroup>
<None Include=".vscode\tasks.json" />
</ItemGroup>

View File

@@ -112,12 +112,6 @@ module.exports = (socket, app) => {
electronSocket.emit("browserWindow-move" + id);
});
});
socket.on("register-browserWindow-bounds-changed", (id) => {
const window = getWindowById(id);
const cb = () => electronSocket.emit("browserWindow-bounds-changed" + id, window.getBounds());
window.on("resize", cb);
window.on("move", cb);
});
socket.on("register-browserWindow-moved", (id) => {
getWindowById(id).on("moved", () => {
electronSocket.emit("browserWindow-moved" + id);

File diff suppressed because one or more lines are too long

View File

@@ -139,13 +139,6 @@ export = (socket: Socket, app: Electron.App) => {
});
});
socket.on("register-browserWindow-bounds-changed", (id) => {
const window = getWindowById(id);
const cb = () => electronSocket.emit("browserWindow-bounds-changed" + id, window.getBounds());
window.on("resize", cb);
window.on("move", cb);
});
socket.on("register-browserWindow-moved", (id) => {
getWindowById(id).on("moved", () => {
electronSocket.emit("browserWindow-moved" + id);

View File

@@ -93,7 +93,7 @@ app.on('will-finish-launching', () => {
const manifestJsonFile = require(manifestJsonFilePath);
if (manifestJsonFile.singleInstance) {
if (manifestJsonFile.singleInstance === "yes") {
const mainInstance = app.requestSingleInstanceLock();
app.on('second-instance', (events, args = []) => {
args.forEach((parameter) => {

View File

@@ -257,57 +257,5 @@ namespace ElectronNET.IntegrationTests.Tests
win.SetDocumentEdited(false);
}
[IntegrationFact]
public async Task BoundsChanged_event_fires_with_updated_bounds()
{
BrowserWindow window = null;
try
{
window = await Electron.WindowManager.CreateWindowAsync(
new BrowserWindowOptions { Show = false, Width = 300, Height = 200 },
"about:blank");
var tcs = new TaskCompletionSource<Rectangle>(TaskCreationOptions.RunContinuationsAsynchronously);
window.OnBoundsChanged += bounds => tcs.TrySetResult(bounds);
await Task.Delay(500.ms());
var target = new Rectangle { X = 25, Y = 35, Width = 420, Height = 310 };
window.SetBounds(target);
var completed = await Task.WhenAny(tcs.Task, Task.Delay(3.seconds()));
completed.Should().Be(tcs.Task);
var observed = await tcs.Task;
observed.Width.Should().Be(target.Width);
observed.Height.Should().Be(target.Height);
}
finally
{
window?.Destroy();
}
}
[IntegrationFact]
public async Task BoundsChanged_event_can_fire_on_resize_of_existing_window()
{
var win = this.MainWindow;
var tcs = new TaskCompletionSource<Rectangle>(TaskCreationOptions.RunContinuationsAsynchronously);
win.OnBoundsChanged += bounds => tcs.TrySetResult(bounds);
await Task.Delay(500.ms());
win.SetBounds(new Rectangle { X = 10, Y = 10, Width = 560, Height = 440 });
var completed = await Task.WhenAny(tcs.Task, Task.Delay(3.seconds()));
completed.Should().Be(tcs.Task);
var boundsObserved = await tcs.Task;
boundsObserved.Width.Should().Be(560);
boundsObserved.Height.Should().Be(440);
}
}
}

View File

@@ -27,8 +27,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.Core" Version="0.4.1" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core.AspNet" Version="0.4.1" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core" Version="0.2.0" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core.AspNet" Version="0.2.0" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.9.3" />
</ItemGroup>

View File

@@ -76,8 +76,8 @@
<ProjectReference Include="..\ElectronNET.AspNet\ElectronNET.AspNet.csproj" Condition="$(ElectronNetDevMode)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.Core" Version="0.4.1" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core.AspNet" Version="0.4.1" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core" Version="0.3.0" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="ElectronNET.Core.AspNet" Version="0.3.0" Condition="'$(ElectronNetDevMode)' != 'true'" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.9.3" />
</ItemGroup>

View File

@@ -9,7 +9,7 @@
<ElectronSplashScreen></ElectronSplashScreen>
<ElectronIcon></ElectronIcon>
<PackageIcon></PackageIcon>
<ElectronPackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</ElectronPackageId>
<PackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</PackageId>
<ElectronBuilderJson>electron-builder.json</ElectronBuilderJson>
<Title>$(MSBuildProjectName)</Title>
</PropertyGroup>

View File

@@ -4,7 +4,7 @@
<PropertyGroup Condition="'$(ElectronExecutable)' == ''">
<WinPrefix>win</WinPrefix>
<ElectronExecutable Condition="'$(RuntimeIdentifier.StartsWith($(WinPrefix)))' == 'true'">$(Title)</ElectronExecutable>
<ElectronExecutable Condition="'$(RuntimeIdentifier.StartsWith($(WinPrefix)))' != 'true'">$(ElectronPackageId)</ElectronExecutable>
<ElectronExecutable Condition="'$(RuntimeIdentifier.StartsWith($(WinPrefix)))' != 'true'">$(PackageId)</ElectronExecutable>
</PropertyGroup>
<PropertyGroup>
@@ -12,10 +12,6 @@
<_IsMsAspNetProject Condition="'$(UsingMicrosoftNETSdkWeb)' == 'true'">True</_IsMsAspNetProject>
</PropertyGroup>
<PropertyGroup>
<PackageId Condition="'$(PackageId)' == ''">$(ElectronPackageId)</PackageId>
</PropertyGroup>
<ItemGroup>
<AssemblyMetadata Include="ElectronExecutable" Value="$(ElectronExecutable)" />
<AssemblyMetadata Include="ElectronVersion" Value="$(ElectronVersion)" />

View File

@@ -124,7 +124,7 @@
</PropertyGroup>
<ItemGroup>
<TemplateProperty Include="ElectronPackageId" Value="$(ElectronPackageId)" />
<TemplateProperty Include="PackageId" Value="$(PackageId)" />
<TemplateProperty Include="Title" Value="$(Title)" />
<TemplateProperty Include="ElectronTitle" Value="$(ElectronTitle)" />
<TemplateProperty Include="Version" Value="$(Version)" />
@@ -135,7 +135,7 @@
<TemplateProperty Include="ElectronSplashScreen" Value="$(ElectronSplashScreenFileName)" />
<TemplateProperty Include="ElectronVersion" Value="$(ElectronVersion)" />
<TemplateProperty Include="TargetName" Value="$(ElectronTargetName)" />
<TemplateProperty Include="ElectronSingleInstance" Value="$(ElectronSingleInstance.ToLower())" />
<TemplateProperty Include="ElectronSingleInstance" Value="$(ElectronSingleInstance)" />
</ItemGroup>
<MakeDir Directories="$(ElectronIntermediateOutputPath)" />
@@ -297,58 +297,12 @@
<RemoveDir Directories="$(ElectronHookTargetModuleDir)" Condition="Exists($(ElectronHookTargetModuleDir))" />
</Target>
<Target Name="ElectronCheckVersionMismatch">
<PropertyGroup>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-x86'">ia32</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-arm64'">arm64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-arm'">armv7l</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">arm64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'osx-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'osx-arm64'">arm64</ElectronArch>
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-x86' OR '$(RuntimeIdentifier)' == 'win-arm64'">win</ElectronPlatform>
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm' OR '$(RuntimeIdentifier)' == 'linux-arm64'">linux</ElectronPlatform>
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'">mac</ElectronPlatform>
<!-- npm uses different OS names than Electron -->
<NpmOs Condition="'$(ElectronPlatform)' == 'win'">win32</NpmOs>
<NpmOs Condition="'$(ElectronPlatform)' == 'linux'">linux</NpmOs>
<NpmOs Condition="'$(ElectronPlatform)' == 'mac'">darwin</NpmOs>
<!-- npm CPU is same as ElectronArch except for linux-arm -->
<NpmCpu>$(ElectronArch)</NpmCpu>
<NpmCpu Condition="'$(RuntimeIdentifier)' == 'linux-arm'">arm</NpmCpu>
<_CurrentOSPlatform Condition="$([MSBuild]::IsOSPlatform('Windows'))">win</_CurrentOSPlatform>
<_CurrentOSPlatform Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux</_CurrentOSPlatform>
<_CurrentOSPlatform Condition="$([MSBuild]::IsOSPlatform('OSX'))">mac</_CurrentOSPlatform>
</PropertyGroup>
<!-- Validate that the target platform matches the current OS -->
<PropertyGroup>
<IsLinuxWsl>false</IsLinuxWsl>
<IsLinuxWsl Condition="'$(ElectronPlatform)' == 'linux' AND '$(_CurrentOSPlatform)' == 'win'">true</IsLinuxWsl>
<_IsCrossCompileAllowed>false</_IsCrossCompileAllowed>
<!-- Allow Linux builds on Windows via WSL -->
<_IsCrossCompileAllowed Condition="'$(_CurrentOSPlatform)' == 'win' AND '$(ElectronPlatform)' == 'linux' AND '$(IsLinuxWsl)' == 'true'">true</_IsCrossCompileAllowed>
<_IsPlatformMismatch>false</_IsPlatformMismatch>
<_IsPlatformMismatch Condition="'$(_CurrentOSPlatform)' != '$(ElectronPlatform)' AND '$(_IsCrossCompileAllowed)' != 'true'">true</_IsPlatformMismatch>
</PropertyGroup>
</Target>
<Target Name="ElectronConfigureApp"
Inputs="@(ElectronPackageJsonFiles)"
Outputs="@(ElectronPackageJsonFiles->'$(OutDir)%(TargetPath)')"
AfterTargets="CopyFilesToOutputDirectory"
DependsOnTargets="ElectronResetHostHook;ElectronCheckVersionMismatch"
DependsOnTargets="ElectronResetHostHook"
>
<Copy SourceFiles="@(ElectronPackageJsonFiles)" DestinationFiles="@(ElectronPackageJsonFiles->'$(OutDir)%(TargetPath)')" >
@@ -362,9 +316,10 @@
<PropertyGroup>
<ElectronOutputPath>$([System.IO.Path]::GetFullPath('$(ElectronOutDir)'))</ElectronOutputPath>
<LinuxPrefix>linux</LinuxPrefix>
<IsLinuxWsl>false</IsLinuxWsl>
<IsLinuxWsl Condition="'$(RuntimeIdentifier.StartsWith($(LinuxPrefix)))' == 'true'AND $([MSBuild]::IsOSPlatform('Windows'))">true</IsLinuxWsl>
<_NpmCmd>npm install --no-bin-links</_NpmCmd>
<!-- Add cross-platform parameters when there's a platform mismatch (for remote debugging preparation) -->
<_NpmCmd Condition="'$(_IsPlatformMismatch)' == 'true'">$(_NpmCmd) --os=$(NpmOs) --cpu=$(NpmCpu) --arch=$(NpmCpu) --platform=$(NpmOs)</_NpmCmd>
<_NpmCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmCmd)'</_NpmCmd>
</PropertyGroup>
@@ -380,23 +335,6 @@
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '0'" />
<!-- Fix up incorrect symlinks created by npm on Windows when targeting macOS -->
<PropertyGroup>
<_ElectronFrameworksDir>$(ElectronOutDir)node_modules\electron\dist\Electron.app\Contents\Frameworks</_ElectronFrameworksDir>
</PropertyGroup>
<ItemGroup>
<_ElectronFrameworkDirs Include="$(_ElectronFrameworksDir)\Electron Framework.framework" />
<_ElectronFrameworkDirs Include="$(_ElectronFrameworksDir)\Mantle.framework" />
<_ElectronFrameworkDirs Include="$(_ElectronFrameworksDir)\ReactiveObjC.framework" />
<_ElectronFrameworkDirs Include="$(_ElectronFrameworksDir)\Squirrel.framework" />
</ItemGroup>
<!-- Only execute on Windows host when targeting macOS -->
<Message Importance="High" Text="Fixing macOS framework Resources symlinks" Condition="'$(ElectronPlatform)' == 'mac' AND '$(_CurrentOSPlatform)' == 'win'" />
<Exec Command="cmd /c del Resources &amp;&amp; mklink /D Resources &quot;Versions\Current\Resources&quot;" WorkingDirectory="%(_ElectronFrameworkDirs.Identity)" Condition="'$(ElectronPlatform)' == 'mac' AND '$(_CurrentOSPlatform)' == 'win'" />
</Target>
<Target Name="BeforePublishElectronApp" BeforeTargets="PrepareForPublish">
@@ -429,7 +367,7 @@
<_ElectronPublishAppAfterTarget Condition="'$(UsingMicrosoftNETSdkWeb)' != 'true'">Publish</_ElectronPublishAppAfterTarget>
</PropertyGroup>
<Target Name="ElectronPublishApp" AfterTargets="$(_ElectronPublishAppAfterTarget)" DependsOnTargets="ElectronCheckVersionMismatch">
<Target Name="ElectronPublishApp" AfterTargets="$(_ElectronPublishAppAfterTarget)">
<PropertyGroup>
<PublishDir>$(_OriginalPublishDir)</PublishDir>
@@ -438,18 +376,21 @@
</PropertyGroup>
<Error Condition="'$(_IsPlatformMismatch)' == 'true'"
Code="ELECTRON100"
Text="The target RuntimeIdentifier '$(RuntimeIdentifier)' (platform: $(ElectronPlatform)) does not match the current operating system ($(_CurrentOSPlatform)).
<PropertyGroup>
<!-- Default values -->
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-x86'">ia32</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'win-arm64'">arm64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-arm'">armv7l</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'linux-arm64'">arm64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'osx-x64'">x64</ElectronArch>
<ElectronArch Condition="'$(RuntimeIdentifier)' == 'osx-arm64'">arm64</ElectronArch>
Electron applications must be built on the target operating system:
- Windows targets (win-x64, win-x86, win-arm64) must be built on Windows
- Linux targets (linux-x64, linux-arm, linux-arm64) must be built on Linux (or Windows with WSL)
- macOS targets (osx-x64, osx-arm64) must be built on macOS
EXCEPTION: Linux targets can be built on Windows using WSL (Windows Subsystem for Linux).
For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migration-Checks#8-cross-platform-build-validation" />
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'win-x64' OR '$(RuntimeIdentifier)' == 'win-x86' OR '$(RuntimeIdentifier)' == 'win-arm64'">win</ElectronPlatform>
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm' OR '$(RuntimeIdentifier)' == 'linux-arm64'">linux</ElectronPlatform>
<ElectronPlatform Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'">mac</ElectronPlatform>
</PropertyGroup>
<RemoveEnvironmentVariables Variables="BUILD_BUILDNUMBER;BUILD_NUMBER;TRAVIS_BUILD_NUMBER;APPVEYOR_BUILD_NUMBER;CIRCLE_BUILD_NUM;CI_PIPELINE_IID" />
@@ -511,7 +452,7 @@ For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migr
<PropertyGroup>
<ElectronPaParams></ElectronPaParams>
<ElectronPaParams Condition="'$(ElectronPackageId)' != ''">$(ElectronPaParams) -c.appId &quot;$(ElectronPackageId)&quot;</ElectronPaParams>
<ElectronPaParams Condition="'$(PackageId)' != ''">$(ElectronPaParams) -c.appId &quot;$(PackageId)&quot;</ElectronPaParams>
<ElectronPaParams Condition="'$(Version)' != ''">$(ElectronPaParams) -c.buildVersion &quot;$(Version)&quot;</ElectronPaParams>
<ElectronPaParams Condition="'$(Copyright)' != ''">$(ElectronPaParams) -c.copyright &quot;$(Copyright)&quot;</ElectronPaParams>
<ElectronPaParams>$(ElectronPaParams) -c.extraResources &quot;bin/**/*&quot;</ElectronPaParams>
@@ -522,7 +463,7 @@ For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migr
<_NpxCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpxCmd)'</_NpxCmd>
</PropertyGroup>
<Exec Command="$(_NpxCmd)" WorkingDirectory="$(ElectronPublishDirFullPath)" Timeout="1800000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="@(CopiedFiles->Count()) > 0">
<Exec Command="$(_NpxCmd)" WorkingDirectory="$(ElectronPublishDirFullPath)" Timeout="900000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="@(CopiedFiles->Count()) > 0">
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
</Exec>

View File

@@ -4,8 +4,6 @@
<PropertyGroup>
<ElectronMigrationChecksDependsOn>
ElectronCheckNoPackageJson;
ElectronCheckRootPackageJsonNoElectron;
ElectronCheckRootPackageJsonNotCopied;
ElectronCheckNoManifestJson;
ElectronCheckElectronBuilderJson;
ElectronCheckNoParentPaths;
@@ -21,17 +19,14 @@
</Target>
<!--
Check 1: No package.json/package-lock.json must be present in the project (except ElectronHostHook folder)
NOTE: Root package.json is excluded from ELECTRON001 and checked by separate targets.
Check 1: No package.json must be present in the project (except ElectronHostHook folder)
-->
<Target Name="ElectronCheckNoPackageJson">
<!-- Find all package.json files, excluding ElectronHostHook folder, root, and output directories -->
<!-- Find all package.json files, excluding ElectronHostHook folder and output directories -->
<ItemGroup>
<_InvalidPackageJson Include="$(MSBuildProjectDirectory)\**\package.json"
Exclude="$(MSBuildProjectDirectory)\package.json;
$(MSBuildProjectDirectory)\ElectronHostHook\**\package.json;
Exclude="$(MSBuildProjectDirectory)\ElectronHostHook\**\package.json;
$(MSBuildProjectDirectory)\bin\**\package.json;
$(MSBuildProjectDirectory)\obj\**\package.json;
$(MSBuildProjectDirectory)\publish\**\package.json;
@@ -51,87 +46,17 @@
<Warning Condition="'$(_HasInvalidPackageJson)' == 'true'"
Code="ELECTRON001"
Text="Found package.json or package-lock.json file(s) in unsupported location(s). These files are no longer supported in this location.
Text="Found package.json or package-lock.json file(s) in the project root or subdirectories. These files are no longer supported in this location.
Files found:
@(_InvalidPackageJson, '%0A')@(_InvalidPackageLockJson, '%0A')
MIGRATION REQUIRED:
All Electron.NET-related properties from an existing package.json must now be specified as MSBuild properties in the project file.
All properties from an existing package.json file must now be specified as MSBuild properties in the project file.
For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migration-Checks#1-packagejson-not-allowed
EXCEPTION:
- package.json and package-lock.json files ARE allowed in the 'ElectronHostHook' folder for custom host hook implementations.
- A package.json in the project root is handled by separate migration checks." />
</Target>
<!--
Check 1b: Root package.json must not contain Electron-related configuration
-->
<Target Name="ElectronCheckRootPackageJsonNoElectron"
Condition="Exists('$(MSBuildProjectDirectory)\package.json')">
<ItemGroup>
<_RootPackageJsonLines Include="$([System.IO.File]::ReadAllLines('$(MSBuildProjectDirectory)\package.json'))" />
</ItemGroup>
<PropertyGroup>
<_RootPackageJsonContent>@(_RootPackageJsonLines, ' ')</_RootPackageJsonContent>
<_RootPackageJsonHasElectron>false</_RootPackageJsonHasElectron>
<_RootPackageJsonHasElectron Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(_RootPackageJsonContent)', 'electron', System.Text.RegularExpressions.RegexOptions.IgnoreCase))">true</_RootPackageJsonHasElectron>
</PropertyGroup>
<Warning
Condition="'$(_RootPackageJsonHasElectron)' == 'true'"
Code="ELECTRON008"
Text="The project contains a root package.json that references 'electron' (case-insensitive).
File:
$(MSBuildProjectDirectory)\package.json
MIGRATION REQUIRED:
Electron.NET configuration must be defined via MSBuild properties and electron-builder.json (not via a user-provided package.json).
HOW TO FIX:
- Remove Electron-related entries from the root package.json, or delete the file if it's only used for Electron configuration.
For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migration-Checks#1-packagejson-not-allowed" />
</Target>
<!--
Check 1c: Root package.json must not be copied to output/publish
-->
<Target Name="ElectronCheckRootPackageJsonNotCopied"
Condition="Exists('$(MSBuildProjectDirectory)\package.json')">
<ItemGroup>
<_RootPackageJsonFile Include="@(Content);@(None)"
Condition="'%(Identity)' == 'package.json' OR '%(Identity)' == '$(MSBuildProjectDirectory)\package.json'" />
</ItemGroup>
<PropertyGroup>
<_RootPackageJsonIsCopied>false</_RootPackageJsonIsCopied>
<_RootPackageJsonIsCopied Condition="'@(_RootPackageJsonFile)' != '' AND ( '%(_RootPackageJsonFile.CopyToOutputDirectory)' != '' OR '%(_RootPackageJsonFile.CopyToPublishDirectory)' != '' )">true</_RootPackageJsonIsCopied>
</PropertyGroup>
<Warning
Condition="'$(_RootPackageJsonIsCopied)' == 'true'"
Code="ELECTRON009"
Text="The project contains a root package.json that is configured to be copied to the output/publish directory.
File:
$(MSBuildProjectDirectory)\package.json
MIGRATION REQUIRED:
Root package.json must not be copied during build/publish.
HOW TO FIX:
- Remove CopyToOutputDirectory / CopyToPublishDirectory metadata for package.json in your project file.
For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migration-Checks#1-packagejson-not-allowed" />
EXCEPTION: package.json and package-lock.json files ARE allowed in the 'ElectronHostHook' folder for custom host hook implementations." />
</Target>

View File

@@ -479,7 +479,7 @@
Description="The version of the app, following the major.minor.patch pattern. Version numbers may include a pre-release suffix."
Category="AppInfo" />
<StringProperty Name="ElectronPackageId"
<StringProperty Name="PackageId"
DisplayName="App Identifier"
Category="AppInfo">
</StringProperty>

View File

@@ -1,13 +1,13 @@
{
"name": "$(ElectronPackageId)",
"name": "$(PackageId)",
"productName": "$(ElectronTitle)",
"build": {
"appId": "$(ElectronPackageId)",
"appId": "$(PackageId)",
"linux": {
"desktop": {
"entry": { "Name": "$(Title)" }
},
"executableName": "$(ElectronPackageId)"
"executableName": "$(PackageId)"
},
"deb": {
"desktop": {
@@ -23,7 +23,7 @@
},
"license": "$(License)",
"executable": "$(TargetName)",
"singleInstance": $(ElectronSingleInstance),
"singleInstance": "$(ElectronSingleInstance)",
"homepage": "$(ProjectUrl)",
"splashscreen": {
"imageFile": "$(ElectronSplashScreen)"

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>0.4.1</Version>
<Version>0.3.0</Version>
<PackageNamePrefix>ElectronNET.Core</PackageNamePrefix>
<Authors>Gregor Biswanger, Florian Rappl, softworkz</Authors>
<Product>Electron.NET</Product>