Closed yoroshikun closed 3 years ago
Hello ! My solution may not be the best, but I did bundle an exe ! But I recognise it's a weird solution haha.
If you put the exe into a node module (I have a script that replace a node module folder by another one I made. I also created the orignal node module, so I have control over whatever is in it in the first place anyway), it will get into the bundle. :)
@Psycokwet
Thanks for the prompt reply!
Could you explain how you were able to reference the .exe and exactly what the module looked like, I tried your solution however did not have much luck, it is quite likely I am missing 1 line to reference it correctly.
Hello again ! Yes, I can develop my answer. First of all, I did package an exe, and dll files like that. However, I had issues accessing the dlls files from the archives, so, I had to play with path while in production, to get access to the unzipped asar folder. I did the same with the exe, without knowing if it was affecting the exe the same way. Did you check if the exe got into the asar archive ?
If it did, maybe try to access to the unzipped exe ?
I used this package : https://www.npmjs.com/package/bassaudio-updated
I have one local version with a few lines modified to change the path like needed while in production.
Basically, from the bass file :
function getEndPath(osLibFolder) {
return path.join(
"app.asar.unpacked",
"node_modules",
"bassaudio-updated",
"lib"
);
}
function getBasePath(isDev) {
const osLibFolder = getPlatformDependencies().path;
if (isDev) return path.join(__dirname, "lib", osLibFolder);
if (osLibFolder === "macOs")
return path.join(
"/Applications/Vestalive.app/Contents/Resources",
// path.resolve(path.resolve(__dirname, ".."), ".."),
getEndPath(),
osLibFolder
);
else return path.join(process.cwd(), "resources", getEndPath(), osLibFolder);
}
function Bass(isDev) {
const options = {};
const platformDependencies = getPlatformDependencies();
this.libFiles = platformDependencies.libFiles;
// const basePath = path.join(__dirname, "lib", platformDependencies.path);
this.basePath = getBasePath(isDev);
I did add the exe in my local project, so it's absent from the package, but, I managed it the same way as my dlls
Hi, I am only somewhat following,
I'm uncertain what this means getPlatformDependencies().path;
even though I have the node module it is not being bundled into the asar no. I think it might be shaking it.
And it looks like it is required for the exe to be copied into the app dir before bundling. is there a way to inject that build step in between the normal steps that nextron build does?
other than that it might be possible if I inject the exe into the renderer static however I dont want to do so that if possible.
getPlatformSependencies is a function in the package https://www.npmjs.com/package/bassaudio-updated
If you do a new project, install bassaudio-update, copy paste it in your main folder, add this script to your package.json :
"dev": "npm run switchBassAudio && nextron",
"build": "npm run switchBassAudio && nextron build",
"switchBassAudio": "node bassaudioInstall.js"
bassaudioInstall.js
var fs = require("fs");
var path = require("path");
// directory path
const dir = path.join("node_modules", "bassaudio-updated");
// delete directory recursively
try {
fs.rmdirSync(dir, { recursive: true });
console.log(`${dir} is deleted!`);
} catch (err) {
console.error(`Error while deleting ${dir}.`);
}
copyFolderRecursiveSync("bassaudio-updated", "node_modules");
console.log("bassaudio-updated module successfully updated");
function copyFileSync(source, target) {
var targetFile = target;
// If target is a directory, a new file with the same name will be created
if (fs.existsSync(target)) {
if (fs.lstatSync(target).isDirectory()) {
targetFile = path.join(target, path.basename(source));
}
}
fs.writeFileSync(targetFile, fs.readFileSync(source));
}
function copyFolderRecursiveSync(source, target) {
var files = [];
// Check if folder needs to be created or integrated
var targetFolder = path.join(target, path.basename(source));
if (!fs.existsSync(targetFolder)) {
fs.mkdirSync(targetFolder);
}
// Copy
if (fs.lstatSync(source).isDirectory()) {
files = fs.readdirSync(source);
files.forEach(function (file) {
var curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
copyFolderRecursiveSync(curSource, targetFolder);
} else {
copyFileSync(curSource, targetFolder);
}
});
}
}
You should have the dlls in the bundle, and whatever exe you add too in the pasted folder.
But yeah, it's a weird workaround
Hi, thanks for the detailed report, I think I finally was able to do a similar ugly workaround by doing the following
const execFilePath = isDev ? join(process.cwd(), "node_modules", "watcher", "watcher.exe") :
join(process.cwd(), "resources", join(
"app.asar.unpacked",
"node_modules",
"watcher",
"watcher.exe"
));
I think i can avoid the yarn linking however that was the process I did.
I think a build step that can copy a file into the app folder during a build might solve a lot of these work arounds. I may look into a patch if i get time
Great !
Yes I agree, i was thinking of doing something similar when I get the time too haha. It's pretty ugly otherwise !
Good to know it worked for you in the end !
@Psycokwet I had another look to making a cleaner workaround and I found an option in the electron-builder to help
Now there is no need to make a package to trick the builder. Clean 2 line config update & easier resource referencing.
files:
- from: .
filter:
- package.json
- app
- lib < I added this
asarUnpack
config option documented Here
Example:
win:
asarUnpack: "**/lib/*.exe" < This can be any glob as explained in the documentation
const execFilePath = join(
__dirname,
"..",
"lib",
"your-program.exe"
).replace("app.asar", "app.asar.unpacked"); // asar only exists to replace in production build
I really hope this helps people who have the same issue with needing spawn able processes bundled and unpacked in nextron projects.
@yoroshikun thank you so much, worked properly for me.
It seems like a great solution yes ! Thank your for the updated answer :)
It worked like a charm ! Thank you, it's really a neat solution. I think maybe we can close this one ?
Closing since no new answers since then :)
This issue is similar to #120
Hi, I have been trying to bundle an .exe file within the build. I have been successful in dev mode with the following code in the electron-builder.yml
Referenced in the main process with
However this does not seem to work when building for release as the file is nowhere to be found nor in the asar file.
I have been able to bundle this .exe for production utilizing the
__static
feature that is available in the electron-webpack package however I cannot find a similar option for this project.I would really love to use this project in production over the electron-webpack as it is a much cleaner resolution comparatively.
As of now this is the only thing that is preventing me from utilizing this project fully.
Thanks for any guidance in advance