Skip to content

Develop #886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 127 additions & 31 deletions src/ElectronNET.CLI/Commands/BuildCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using ElectronNET.CLI.Commands.Actions;

namespace ElectronNET.CLI.Commands
Expand Down Expand Up @@ -139,28 +140,138 @@ public Task<bool> ExecuteAsync()
File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true);
}

var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");
// Read electron version from manifest file and update package.json BEFORE npm install
string manifestFileName = "electron.manifest.json";

if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
if (parser.Arguments.ContainsKey(_manifest))
{
manifestFileName = parser.Arguments[_manifest].First();
}

Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install --production", tempPath);
// Read electron version from manifest file
string electronVersion = "23.2.0"; // default fallback version
string manifestPath = Path.Combine(Directory.GetCurrentDirectory(), manifestFileName);

Console.WriteLine($"Reading electronVersion from manifest file: {manifestPath}");

if (File.Exists(manifestPath))
{
try
{
string manifestContent = File.ReadAllText(manifestPath);
using (JsonDocument document = JsonDocument.Parse(manifestContent))
{
if (document.RootElement.TryGetProperty("electronVersion", out JsonElement electronVersionElement))
{
string manifestElectronVersion = electronVersionElement.GetString();
if (!string.IsNullOrWhiteSpace(manifestElectronVersion))
{
electronVersion = manifestElectronVersion;
Console.WriteLine($"Using Electron version {electronVersion} from manifest file");
}
else
{
Console.WriteLine($"electronVersion property found but empty in manifest file, using fallback version {electronVersion}");
}
}
else
{
Console.WriteLine($"electronVersion property not found in manifest file, using fallback version {electronVersion}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Warning: Could not read electronVersion from manifest file: {ex.Message}");
Console.WriteLine($"Using fallback Electron version {electronVersion}");
}
}
else
{
Console.WriteLine($"Warning: Manifest file not found at {manifestPath}");
Console.WriteLine($"Using fallback Electron version {electronVersion}");
}

Console.WriteLine("ElectronHostHook handling started...");
// Update package.json with electronVersion directly in C# before npm install
string packageJsonPath = Path.Combine(tempPath, "package.json");
if (File.Exists(packageJsonPath))
{
try
{
string packageJsonContent = File.ReadAllText(packageJsonPath);
using (JsonDocument packageDocument = JsonDocument.Parse(packageJsonContent))
{
var packageJsonObject = new Dictionary<string, object>();

// Copy existing properties
foreach (var property in packageDocument.RootElement.EnumerateObject())
{
if (property.Name == "devDependencies")
{
var devDeps = new Dictionary<string, object>();
foreach (var dep in property.Value.EnumerateObject())
{
devDeps[dep.Name] = dep.Value.GetString();
}
// Update electron version
devDeps["electron"] = $"^{electronVersion}";
packageJsonObject["devDependencies"] = devDeps;
}
else if (property.Value.ValueKind == JsonValueKind.String)
{
packageJsonObject[property.Name] = property.Value.GetString();
}
else if (property.Value.ValueKind == JsonValueKind.Object)
{
var subObject = new Dictionary<string, object>();
foreach (var subProp in property.Value.EnumerateObject())
{
subObject[subProp.Name] = subProp.Value.GetString();
}
packageJsonObject[property.Name] = subObject;
}
else
{
packageJsonObject[property.Name] = property.Value.ToString();
}
}

// Ensure devDependencies exists and contains electron
if (!packageJsonObject.ContainsKey("devDependencies"))
{
packageJsonObject["devDependencies"] = new Dictionary<string, object>();
}
var devDependencies = (Dictionary<string, object>)packageJsonObject["devDependencies"];
devDependencies["electron"] = $"^{electronVersion}";

string updatedPackageJson = JsonSerializer.Serialize(packageJsonObject, new JsonSerializerOptions
{
WriteIndented = true
});

File.WriteAllText(packageJsonPath, updatedPackageJson);
Console.WriteLine($"Updated package.json with Electron version {electronVersion}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Warning: Could not update package.json with electronVersion: {ex.Message}");
}
}

string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");

if (Directory.Exists(electronhosthookDir))
{
string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List<string>() { "node_modules" });
if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
Console.WriteLine("Start npm install...");

Console.WriteLine("Start npm install for hosthooks...");
ProcessHelper.CmdExecute("npm install", hosthookDir);
ProcessHelper.CmdExecute("npm install --production", tempPath);

// ToDo: Not sure if this runs under linux/macos
ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
}
// Update build helper and configuration files after npm install
Console.WriteLine("Create electron-builder configuration file...");
ProcessHelper.CmdExecute(
string.IsNullOrWhiteSpace(version)
? $"node build-helper.js {manifestFileName}"
: $"node build-helper.js {manifestFileName} {version}", tempPath);

Console.WriteLine("Build Electron Desktop Application...");

Expand Down Expand Up @@ -189,23 +300,8 @@ public Task<bool> ExecuteAsync()
electronParams = parser.Arguments[_paramElectronParams][0];
}

// ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :)
Console.WriteLine("Create electron-builder configuration file...");

string manifestFileName = "electron.manifest.json";

if (parser.Arguments.ContainsKey(_manifest))
{
manifestFileName = parser.Arguments[_manifest].First();
}

ProcessHelper.CmdExecute(
string.IsNullOrWhiteSpace(version)
? $"node build-helper.js {manifestFileName}"
: $"node build-helper.js {manifestFileName} {version}", tempPath);

Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=30.0.3 {electronParams}", tempPath);
ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion={electronVersion} {electronParams}", tempPath);

Console.WriteLine("... done");

Expand Down
106 changes: 106 additions & 0 deletions src/ElectronNET.CLI/Commands/StartElectronCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Text.Json;
using ElectronNET.CLI.Commands.Actions;

namespace ElectronNET.CLI.Commands
Expand Down Expand Up @@ -118,13 +119,118 @@ public Task<bool> ExecuteAsync()

DeployEmbeddedElectronFiles.Do(tempPath);

// Update package.json with electronVersion from manifest before npm install
string manifestFileName = "electron.manifest.json";
if (parser.Arguments.ContainsKey(_manifest))
{
manifestFileName = parser.Arguments[_manifest].First();
}

// Read electron version from manifest file
string electronVersion = "23.2.0"; // default fallback version
string manifestPath = Path.Combine(aspCoreProjectPath, manifestFileName);

if (File.Exists(manifestPath))
{
try
{
string manifestContent = File.ReadAllText(manifestPath);
using (JsonDocument document = JsonDocument.Parse(manifestContent))
{
if (document.RootElement.TryGetProperty("electronVersion", out JsonElement electronVersionElement))
{
string manifestElectronVersion = electronVersionElement.GetString();
if (!string.IsNullOrWhiteSpace(manifestElectronVersion))
{
electronVersion = manifestElectronVersion;
Console.WriteLine($"Using Electron version {electronVersion} from manifest file");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Warning: Could not read electronVersion from manifest file: {ex.Message}");
}
}

// Update package.json with electronVersion directly in C# before npm install
string packageJsonPath = Path.Combine(tempPath, "package.json");
if (File.Exists(packageJsonPath))
{
try
{
string packageJsonContent = File.ReadAllText(packageJsonPath);
using (JsonDocument packageDocument = JsonDocument.Parse(packageJsonContent))
{
var packageJsonObject = new Dictionary<string, object>();

// Copy existing properties
foreach (var property in packageDocument.RootElement.EnumerateObject())
{
if (property.Name == "devDependencies")
{
var devDeps = new Dictionary<string, object>();
foreach (var dep in property.Value.EnumerateObject())
{
devDeps[dep.Name] = dep.Value.GetString();
}
// Update electron version
devDeps["electron"] = $"^{electronVersion}";
packageJsonObject["devDependencies"] = devDeps;
}
else if (property.Value.ValueKind == JsonValueKind.String)
{
packageJsonObject[property.Name] = property.Value.GetString();
}
else if (property.Value.ValueKind == JsonValueKind.Object)
{
var subObject = new Dictionary<string, object>();
foreach (var subProp in property.Value.EnumerateObject())
{
subObject[subProp.Name] = subProp.Value.GetString();
}
packageJsonObject[property.Name] = subObject;
}
else
{
packageJsonObject[property.Name] = property.Value.ToString();
}
}

// Ensure devDependencies exists and contains electron
if (!packageJsonObject.ContainsKey("devDependencies"))
{
packageJsonObject["devDependencies"] = new Dictionary<string, object>();
}
var devDependencies = (Dictionary<string, object>)packageJsonObject["devDependencies"];
devDependencies["electron"] = $"^{electronVersion}";

string updatedPackageJson = JsonSerializer.Serialize(packageJsonObject, new JsonSerializerOptions
{
WriteIndented = true
});

File.WriteAllText(packageJsonPath, updatedPackageJson);
Console.WriteLine($"Updated package.json with Electron version {electronVersion}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Warning: Could not update package.json with electronVersion: {ex.Message}");
}
}

var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

Console.WriteLine("node_modules missing in: " + nodeModulesDirPath);

Console.WriteLine("Start npm install...");
ProcessHelper.CmdExecute("npm install", tempPath);

// Execute build-helper.js to setup other configurations after npm install
ProcessHelper.CmdExecute($"node build-helper.js {manifestFileName}", tempPath);

Console.WriteLine("ElectronHostHook handling started...");

string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");
Expand Down
18 changes: 14 additions & 4 deletions src/ElectronNET.Host/build-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ const builderConfiguration = { ...manifestFile.build };
if(process.argv.length > 3) {
builderConfiguration.buildVersion = process.argv[3];
}

// @ts-ignore
const packageJson = require('./package');

// Update package.json if buildVersion is provided
if(builderConfiguration.hasOwnProperty('buildVersion')) {
// @ts-ignore
const packageJson = require('./package');
packageJson.name = dasherize(manifestFile.name || 'electron-net');
packageJson.author = manifestFile.author || '';
packageJson.version = builderConfiguration.buildVersion;
packageJson.description = manifestFile.description || '';

fs.writeFile('./package.json', JSON.stringify(packageJson), (error) => {
// Write updated package.json
fs.writeFile('./package.json', JSON.stringify(packageJson, null, 2), (error) => {
if(error) {
console.log(error.message);
}
});

}

// Note: electronVersion is now handled directly in C# before npm install
// No need to update it here anymore

// Update package-lock.json if it exists
if(builderConfiguration.hasOwnProperty('buildVersion')) {
try {
// @ts-ignore
const packageLockJson = require('./package-lock');
Expand Down
1 change: 1 addition & 0 deletions src/ElectronNET.WebApp/electron.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
},
"environment": "Production",
"singleInstance": false,
"electronVersion": "25.9.0",
"build": {
"appId": "com.electronnetapidemos.app",
"productName": "ElectronNET API Demos",
Expand Down