mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-09-21 06:25:20 +00:00
Finished #1106
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
- Fixed cross-compilation behavior on same platform (#1098) @epsnm
|
||||
- Fixed resolution of unrelated target (#1099) @epsnm
|
||||
- Added target framework customization (#1095) @epsnm
|
||||
- Added configurable Electron root directory for custom packaging layouts (#1106) @DYH1319
|
||||
- Added build extensibility properties `ElectronSkipExecCommands` and `ElectronIntermediatePublishDir` (#1106) @DYH1319
|
||||
|
||||
# 0.5.2
|
||||
|
||||
|
||||
@@ -28,9 +28,53 @@ These are the current default values when you don't make any changes:
|
||||
<ElectronPackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</ElectronPackageId>
|
||||
<ElectronBuilderJson>electron-builder.json</ElectronBuilderJson>
|
||||
<Title>$(MSBuildProjectName)</Title>
|
||||
<ElectronRootDir>../..</ElectronRootDir>
|
||||
<ElectronSkipExecCommands>false</ElectronSkipExecCommands>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
### Custom Packaging Layout
|
||||
|
||||
`ElectronRootDir` tells the .NET app where to find the Electron binary when it is started first (DotNet-First startup of a packaged app). The path is resolved relative to the directory of the .NET executable; absolute paths are used as-is.
|
||||
|
||||
The default `../..` matches the standard Electron-First packaging layout produced by `dotnet publish`, where the .NET app is placed in `resources/bin` of the Electron package:
|
||||
|
||||
```
|
||||
<install-root>/
|
||||
MyApp # Electron executable
|
||||
resources/
|
||||
bin/
|
||||
MyApp # .NET executable
|
||||
```
|
||||
|
||||
If your own packaging pipeline places the .NET executable at the package root and Electron in a subdirectory, set `ElectronRootDir` accordingly:
|
||||
|
||||
```xml
|
||||
<ElectronRootDir>electron</ElectronRootDir>
|
||||
```
|
||||
|
||||
```
|
||||
<install-root>/
|
||||
MyApp # .NET executable
|
||||
electron/
|
||||
MyApp # Electron executable
|
||||
resources/
|
||||
locales/
|
||||
```
|
||||
|
||||
The property is also used to detect whether the app runs packaged or unpackaged, so it must point to the directory that actually contains the Electron binary.
|
||||
|
||||
### Build Extensibility
|
||||
|
||||
These properties are useful when Electron.NET is embedded into a custom build or CI pipeline:
|
||||
|
||||
| Property | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `ElectronSkipExecCommands` | `false` | Skips all `npm`/`npx` invocations of the Electron build and publish targets. Use it when the dependencies and the Electron distribution are provided by the pipeline itself (for example from a cache or an offline mirror). |
|
||||
| `ElectronIntermediatePublishDir` | `$(IntermediateOutputPath)PubTmp\` | Overrides the intermediate directory the .NET app is published to before it is assembled into the Electron package. |
|
||||
|
||||
`ElectronPackageId` and `Title` only fall back to the project name when they are not already set, so both can be defined by a `Directory.Build.props` or passed on the command line.
|
||||
|
||||
### Relation to package.json
|
||||
|
||||
ElectronNET.Core does not work with an `electron-manifest.json` file anymore.
|
||||
|
||||
@@ -222,6 +222,15 @@ The publish process will:
|
||||
> macOS builds can't be created on Windows machines because they require symlinks that aren't supported on Windows (per [this Electron issue](https://github.com/electron-userland/electron-packager/issues/71)). macOS builds can be produced on either Linux or macOS machines.
|
||||
|
||||
|
||||
## Custom Packaging Pipelines
|
||||
|
||||
The default layout is Electron-First: electron-builder produces the Electron package and the .NET app is placed in `resources/bin`. If you assemble the package yourself and put the .NET executable at the package root with Electron in a subdirectory, set `ElectronRootDir` so the .NET app can locate the Electron binary at runtime.
|
||||
|
||||
For pipelines that provide the npm dependencies themselves, `ElectronSkipExecCommands` suppresses all `npm`/`npx` invocations, and `ElectronIntermediatePublishDir` redirects the intermediate publish output.
|
||||
|
||||
See [Configuration](Configuration.md#custom-packaging-layout) for details.
|
||||
|
||||
|
||||
## 🚀 Next Steps
|
||||
|
||||
- **[Startup Methods](Startup-Methods.md)** - Understanding different launch modes for packaged apps
|
||||
|
||||
@@ -37,10 +37,18 @@
|
||||
public ProcessRunner(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
this.ExitWaitTimeout = DefaultExitWaitTimeout;
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ProcessExited;
|
||||
|
||||
/// <summary>Gets or sets the value <see cref="ExitWaitTimeout"/> is initialized with.</summary>
|
||||
public static int DefaultExitWaitTimeout { get; set; } = 5000;
|
||||
|
||||
/// <summary>Gets or sets the time in milliseconds to wait for the process and its I/O to finish
|
||||
/// after the exited event has been raised. Values of zero or less wait indefinitely.</summary>
|
||||
public int ExitWaitTimeout { get; set; }
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
private Process Process
|
||||
@@ -498,8 +506,17 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
var timeout = this.ExitWaitTimeout;
|
||||
|
||||
// This shouldn't throw here, but the mono process implementation doesn't always behave as it should.
|
||||
this.process.WaitForExit();
|
||||
if (timeout > 0)
|
||||
{
|
||||
this.process.WaitForExit(timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.process.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
public string ElectronVersion { get; internal set; }
|
||||
|
||||
public string ElectronRootDir { get; internal set; }
|
||||
|
||||
public string RuntimeIdentifier { get; internal set; }
|
||||
|
||||
public bool ElectronSingleInstance { get; internal set; }
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace ElectronNET.Runtime.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the directory that contains the Electron binary of a packaged application.
|
||||
/// </summary>
|
||||
internal static class ElectronRootDirResolver
|
||||
{
|
||||
/// <summary>The location of the Electron binary relative to the .NET application directory in the
|
||||
/// default (Electron-first) layout, where the .NET application is placed in 'resources/bin'.</summary>
|
||||
internal const string DefaultElectronRootDir = "../..";
|
||||
|
||||
/// <summary>Resolves the Electron root directory relative to the given .NET application directory.</summary>
|
||||
/// <param name="baseDirectory">The directory containing the .NET application.</param>
|
||||
/// <returns>The directory containing the Electron binary.</returns>
|
||||
public static DirectoryInfo Resolve(DirectoryInfo baseDirectory)
|
||||
{
|
||||
var rootDir = ElectronNetRuntime.BuildInfo?.ElectronRootDir;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(rootDir))
|
||||
{
|
||||
rootDir = DefaultElectronRootDir;
|
||||
}
|
||||
|
||||
// An absolute ElectronRootDir is used as-is by Path.Combine.
|
||||
return new DirectoryInfo(Path.GetFullPath(Path.Combine(baseDirectory.FullName, rootDir)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,15 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packaged, if the Electron binary is found where ElectronRootDir points to.
|
||||
var electronExecutable = ElectronNetRuntime.ElectronExecutable;
|
||||
|
||||
if (!string.IsNullOrEmpty(electronExecutable) &&
|
||||
File.Exists(Path.Combine(ElectronRootDirResolver.Resolve(dir).FullName, electronExecutable)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir.GetDirectories().Any(e => e.Name == ".electron"))
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using ElectronNET.Common;
|
||||
using ElectronNET.Runtime.Data;
|
||||
using ElectronNET.Runtime.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Launches and manages the Electron app process.
|
||||
@@ -87,7 +88,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = dir.Parent!.Parent!;
|
||||
dir = ElectronRootDirResolver.Resolve(dir);
|
||||
startCmd = Path.Combine(dir.FullName, this.electronBinaryName);
|
||||
args = $"-dotnetpacked -electronforcedport={this.socketPort:D} " + this.extraArguments;
|
||||
workingDir = dir.FullName;
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
{
|
||||
buildInfo.ElectronExecutable = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.ElectronExecutable))?.Value;
|
||||
buildInfo.ElectronVersion = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.ElectronVersion))?.Value;
|
||||
buildInfo.ElectronRootDir = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.ElectronRootDir))?.Value;
|
||||
buildInfo.RuntimeIdentifier = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.RuntimeIdentifier))?.Value;
|
||||
buildInfo.Title = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.Title))?.Value;
|
||||
buildInfo.Version = attributes.FirstOrDefault(e => e.Key == nameof(buildInfo.Version))?.Value;
|
||||
|
||||
Binary file not shown.
@@ -11,9 +11,14 @@
|
||||
<ElectronSplashScreen></ElectronSplashScreen>
|
||||
<ElectronIcon></ElectronIcon>
|
||||
<PackageIcon></PackageIcon>
|
||||
<ElectronPackageId>$(MSBuildProjectName.Replace(".", "-").ToLower())</ElectronPackageId>
|
||||
<ElectronPackageId Condition="'$(ElectronPackageId)' == ''">$(MSBuildProjectName.Replace(".", "-").ToLower())</ElectronPackageId>
|
||||
<ElectronBuilderJson>electron-builder.json</ElectronBuilderJson>
|
||||
<Title>$(MSBuildProjectName)</Title>
|
||||
<Title Condition="'$(Title)' == ''">$(MSBuildProjectName)</Title>
|
||||
<!-- Location of the Electron binary relative to the .NET application directory of a packaged app.
|
||||
The default matches the standard layout, where the .NET app is placed in 'resources/bin'. -->
|
||||
<ElectronRootDir Condition="'$(ElectronRootDir)' == ''">../..</ElectronRootDir>
|
||||
<!-- Set to true to suppress the npm/npx invocations of the Electron build and publish targets. -->
|
||||
<ElectronSkipExecCommands Condition="'$(ElectronSkipExecCommands)' == ''">false</ElectronSkipExecCommands>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<ItemGroup>
|
||||
<AssemblyMetadata Include="ElectronExecutable" Value="$(ElectronExecutable)" />
|
||||
<AssemblyMetadata Include="ElectronVersion" Value="$(ElectronVersion)" />
|
||||
<AssemblyMetadata Include="ElectronRootDir" Value="$(ElectronRootDir)" />
|
||||
<AssemblyMetadata Include="RuntimeIdentifier" Value="$(RuntimeIdentifier)" />
|
||||
<AssemblyMetadata Include="ElectronSingleInstance" Value="$(ElectronSingleInstance)" />
|
||||
<AssemblyMetadata Include="Title" Value="$(Title)" />
|
||||
|
||||
@@ -170,7 +170,9 @@
|
||||
<PropertyGroup Condition="'$(UsingMicrosoftNETSdkWeb)' != 'true'">
|
||||
<_NonIntermediatePublishDir>$(PublishDir)</_NonIntermediatePublishDir>
|
||||
<PublishUrl>$(PublishDir)</PublishUrl>
|
||||
<PublishDir>$(IntermediateOutputPath)PubTmp\</PublishDir>
|
||||
<!-- ElectronIntermediatePublishDir allows overriding the intermediate publish directory -->
|
||||
<PublishDir Condition="'$(ElectronIntermediatePublishDir)' != ''">$(ElectronIntermediatePublishDir)</PublishDir>
|
||||
<PublishDir Condition="'$(ElectronIntermediatePublishDir)' == ''">$(IntermediateOutputPath)PubTmp\</PublishDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<RemoveDir Directories="$(PublishDir);$(PublishUrl)" Condition="'$(UsingMicrosoftNETSdkWeb)' != 'true'" />
|
||||
@@ -459,13 +461,13 @@
|
||||
|
||||
<!--<Message Importance="High" Text="ElectronConfigureApp: CopiedFiles - @(_CopiedFiles)" />-->
|
||||
|
||||
<Message Importance="High" Text="Running command: $(_NpmCmd) in folder: $(ElectronOutputPath)" Condition="@(_CopiedFiles->Count()) > 0" />
|
||||
<Message Importance="High" Text="Running command: $(_NpmCmd) in folder: $(ElectronOutputPath)" Condition="'$(ElectronSkipExecCommands)' != 'true' AND @(_CopiedFiles->Count()) > 0" />
|
||||
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronOutputPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="@(_CopiedFiles->Count()) > 0">
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronOutputPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="'$(ElectronSkipExecCommands)' != 'true' AND @(_CopiedFiles->Count()) > 0">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '0'" />
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '' AND '$(ExecExitCode)' != '0'" />
|
||||
|
||||
<PropertyGroup>
|
||||
<_NpmCmd>node node_modules/electron/install.js</_NpmCmd>
|
||||
@@ -474,13 +476,13 @@
|
||||
<_NpmCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmCmd)'</_NpmCmd>
|
||||
</PropertyGroup>
|
||||
|
||||
<Message Importance="High" Text="Running command: $(_NpmCmd) in folder: $(ElectronOutputPath)" Condition="$(ElectronMajor) >= 42 AND @(_CopiedFiles->Count()) > 0" />
|
||||
<Message Importance="High" Text="Running command: $(_NpmCmd) in folder: $(ElectronOutputPath)" Condition="'$(ElectronSkipExecCommands)' != 'true' AND $(ElectronMajor) >= 42 AND @(_CopiedFiles->Count()) > 0" />
|
||||
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronOutputPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="$(ElectronMajor) >= 42 AND @(_CopiedFiles->Count()) > 0">
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronOutputPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="'$(ElectronSkipExecCommands)' != 'true' AND $(ElectronMajor) >= 42 AND @(_CopiedFiles->Count()) > 0">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<Message Importance="High" Text="Electron installation failed!" Condition="'$(ExecExitCode)' != '0'" />
|
||||
<Message Importance="High" Text="Electron installation failed!" Condition="'$(ExecExitCode)' != '' AND '$(ExecExitCode)' != '0'" />
|
||||
|
||||
<!-- Fix up incorrect symlinks created by npm on Windows when targeting macOS -->
|
||||
<PropertyGroup>
|
||||
@@ -615,11 +617,11 @@ For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migr
|
||||
<_NpmAppDepsCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmAppDepsCmd)'</_NpmAppDepsCmd>
|
||||
</PropertyGroup>
|
||||
|
||||
<Exec Command="$(_NpmAppDepsCmd)" WorkingDirectory="$(ElectronAppDirFullPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="@(CopiedFiles->Count()) > 0">
|
||||
<Exec Command="$(_NpmAppDepsCmd)" WorkingDirectory="$(ElectronAppDirFullPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="'$(ElectronSkipExecCommands)' != 'true' AND @(CopiedFiles->Count()) > 0">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<Message Importance="High" Text="Electron app dependency install failed!" Condition="'$(ExecExitCode)' != '0'" />
|
||||
<Message Importance="High" Text="Electron app dependency install failed!" Condition="'$(ExecExitCode)' != '' AND '$(ExecExitCode)' != '0'" />
|
||||
|
||||
<!-- Install electron-builder (the dev tool) into the publish root, which is the
|
||||
electron-builder projectDir (cwd). app metadata + runtime deps are read from
|
||||
@@ -645,11 +647,11 @@ For more information, see: https://github.com/ElectronNET/Electron.NET/wiki/Migr
|
||||
<_NpmCmd Condition="'$(IsLinuxWsl)' == 'true'">wsl bash -ic '$(_NpmCmd)'</_NpmCmd>
|
||||
</PropertyGroup>
|
||||
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronPublishDirFullPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="@(CopiedFiles->Count()) > 0">
|
||||
<Exec Command="$(_NpmCmd)" WorkingDirectory="$(ElectronPublishDirFullPath)" Timeout="600000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="'$(ElectronSkipExecCommands)' != 'true' AND @(CopiedFiles->Count()) > 0">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '0'" />
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '' AND '$(ExecExitCode)' != '0'" />
|
||||
|
||||
<!-- Transform ElectronPublishUrlFullPath to a wslpath if IsLinuxWsl is true -->
|
||||
<Exec Command="wsl wslpath '$(ElectronPublishUrlFullPath)'" ConsoleToMsBuild="true" Condition="'$(IsLinuxWsl)' == 'true'">
|
||||
@@ -673,11 +675,11 @@ 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="1800000" StandardOutputImportance="High" StandardErrorImportance="High" ContinueOnError="false" Condition="'$(ElectronSkipExecCommands)' != 'true' AND @(CopiedFiles->Count()) > 0">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '0'" />
|
||||
<Message Importance="High" Text="Electron setup failed!" Condition="'$(ExecExitCode)' != '' AND '$(ExecExitCode)' != '0'" />
|
||||
|
||||
</Target>
|
||||
|
||||
|
||||
@@ -553,6 +553,24 @@
|
||||
Category="General">
|
||||
</StringProperty>
|
||||
|
||||
<StringProperty Name="ElectronRootDir"
|
||||
DisplayName="Electron Root Directory"
|
||||
Description="Location of the Electron binary relative to the .NET application directory of a packaged app. Default: ../.. (the .NET app lives in resources/bin)"
|
||||
Category="General">
|
||||
</StringProperty>
|
||||
|
||||
<BoolProperty Name="ElectronSkipExecCommands"
|
||||
DisplayName="Skip npm/npx Commands"
|
||||
Description="If enabled, the npm and npx invocations of the Electron build and publish targets are skipped"
|
||||
Category="General">
|
||||
</BoolProperty>
|
||||
|
||||
<StringProperty Name="ElectronIntermediatePublishDir"
|
||||
DisplayName="Intermediate Publish Directory"
|
||||
Description="Overrides the intermediate publish directory used while packaging. Default: $(IntermediateOutputPath)PubTmp\"
|
||||
Category="General">
|
||||
</StringProperty>
|
||||
|
||||
<StringProperty Name="ElectronSplashScreen"
|
||||
DisplayName="Splash Screen Image"
|
||||
Description="Choose a PNG image to be shown as splash screen on startup"
|
||||
|
||||
Reference in New Issue
Block a user