How to get the current path of an electron js portable app? - electron

Hello fellow developers/programmers. Today I come to ask for help with something, and is that I'm making an app that if or if it has to be portable, the problem I'm having is that when writing a zip file the app does not find the directories or generates the zip corruptly.
My code that writes the zip file looks like this:
ipcMain.on("report-file", async (event, data) => {
let zipFilePath = "report.zip"
let output = fs.createWriteStream(zipFilePath);
let archive = archiver("zip")
archive.pipe(output);
if (data.saves) {
archive.directory(`game/saves`, false)
archive.directory(`game/cache`, false)
}
archive.append(fs.createReadStream(`log.txt`), {
name: `log.txt`,
})
archive.append(fs.createReadStream(`traceback.txt`), {
name: `traceback.txt`,
})
archive.finalize()
});
Electron Version: 21.2.3
SO: Windows 11
electron-builder Version: 23.6.0
Looking a little more in depth, I found that the app is using the address
C:\User\User\AppData\Local\Temp\[id]\resources\app.asar
and it is trying to compress the files as if they were in that path, however, the files to compress are located where the .exe is. (G:\myapp\dist)
I already tried to fix it by following an old post on the stackoverflow page, however, it didn't solve the problem, so today I decided to ask my question here, do you have any idea how to get the actual path of an electron js portable app?

I found the solution to this, and it was to create a dialog with electron, and load the folder location. Then use resolve together with the address of the executable, this way it loads correctly the address of the folder where the exe is located.
let dir
dir = await dialog.showOpenDialog(win, {
properties: ['openDirectory'],
defaultPath: path.resolve('.', process.env.PORTABLE_EXECUTABLE_DIR)
});

Related

Is there any way of loading local resource files in dart? (not flutter)

I want to load the bytes of a file into a variable while testing my flutter application.
I can't use the assets directory as those are bundled with the app and require WidgetsFlutterBinding.ensureInitialized();
I tried searching the file manually with the path package, but this did not seem to work and was rather hacky. That is why i'm searching for a more official approach.
I was thinking way to complicated ...
As Chuck Batson commented, you can just use the path from the projects root for passing it into the (dart:io) File:
File loadResource(String relativePath) {
final filePath = path.join("test", "resources", relativePath);
return File(filePath);
}
(Notice: The above code makes use of the path package for constructing a file path.)

How to read config file in electronjs app

It's my first time using Electron JS and nodejs. I've built a small app that reads some records from a database and updates them. Everything is working fine. I have a config file with the database credentials but when I build a portable win app, I cannot figure out how to read the config file that I would like to place next to the exe. I would like to have easy access to the file, so I could run the same app on different databases.
Can anyone tell me if what I want is possible and how? I already tried to get the exe location but I couldn't. I also read a lot of topics here but nothing seems to solve my problem (I might be doing something wrong).
I'm using electron-builder to build my app.
Thanks in advance.
Edit #1
My Config file is
{
"user" :"X",
"password" :"X",
"server":"X",
"database":"X",
"options":
{
"trustedconnection": true,
"enableArithAbort" : true,
"trustServerCertificate": true
}
}
This is what I've and works when I run the project with npm start
const configRootPath = path.resolve(__dirname,'dbConfig.json');
dbConfig = JSON.parse(fs.readFileSync(configRootPath, { encoding: 'utf-8' }));
However, when I build it, the app is looking for the file in another location different from the one where the executable is.
Use of Electron's app.getPath(name) function will get you the path(s) you are after, irrespective of which OS (Operating System) you are using.
Unless your application writes your dbConfig.json file, it may be difficult for your user to understand exactly where they should place their database config file as each OS will run and store your application data in a different directory. You would need to be explicit to the user as to where to place their config file(s). Alternatively, your application could create the config file(s) on the user's behalf (automatically or through a html form) and save it to a location 'known' to the application.
A common place where application specific config files are stored is in the user's application data directory. With the application name automatically amended to the directory, it can be found as shown below.
const electronApp = require('electron').app;
let appUserDataPath = electronApp.getPath('userData');
console.log(appUserDataPath );
In your use case, the below would apply.
const electronApp = require('electron').app;
const nodeFs = require('fs');
const nodePath = require('path');
const configRootPath = nodePath.join(electronApp.getPath('userData'), 'dbConfig.json');
dbConfig = JSON.parse(nodeFs.readFileSync(configRootPath, 'utf-8'));
console.log(configRootPath);
console.log(dbConfig);
You can try electron-store to store config.
Electron doesn't have a built-in way to persist user preferences and other data. This module handles that for you, so you can focus on building your app. The data is saved in a JSON file named config.json in app.getPath('userData').

Flutter ZipFile.extractToDirectory doesn't overwrite existing files on iOS

I am using flutter_archive 4.0.1 (just updated to 4.1.1) and attempting to unzip a file into an existing directory.
My scenario is that I am backing up this folder, sending to a web server, then at some point, I will want to restore into the same folder. This folder will have many files that are the same filenames as in the zip. I need to overwrite the local files with the ones in the zip.
This works perfect on Android. iOS has always had problems when it comes to working with Zip files.
The extractToDirectory does not have an overwrite switch, so I attempted to use the onExtracting, to check if the file already exists locally, delete the local one, then allow the zip one to take its place.
The problem I am experiencing is that to check if it exists, and to delete, I have to use a Future, but as they are async, I cannot get them to synchronise.
Here is what I have tried.
if (Platform.isIOS) {
await ZipFile.extractToDirectory(
zipFile: zipFile,
destinationDir: destinationDir,
onExtracting: (zipEntry, progress) {
exists(zipEntry.name).then((value) {
if (value) {
deleteFile(zipEntry.name).then((value) {
return ZipFileOperation.includeItem;
});
} else {
return ZipFileOperation.includeItem;
}
});
return ZipFileOperation.includeItem;
}
);
}
Both exists and deleteFile are local Futures, that uses the File functionality.
What I have tried, is that the zipEntry.name will be the same as the file I need to overwrite, so this aspect should work fine. It is now just trying to make things work in order.
The Android version is the same, apart from it does not have the onExtracting functionality.
Not sure if you have found the answer or even if there is a good answer. I ran into this issue myself, and it seems the alternative is delete the target dir before unzipping. There seems no override option for unzip. Here is some snip bits about deletion (as also suggested by the package's unit test code):
final _appDataDir = Directory.systemTemp; //from dart.io
final destinationDir = Directory("${_appDataDir.path}/unzip");
if (destinationDir.existsSync()) {
print("Deleting existing unzip directory: ${destinationDir.path}");
destinationDir.deleteSync(recursive: true);
}
Hope this solution helps others who may have similar issues.

How to add a File Picker plugin in Flutter?

I am creating a Flutter project in which, I have a piece of data (JSON) that I want to Import from and Export to a location the user wants to. In order to achieve this, I require a File Picker plugin in Flutter. Now, I searched the Dart Packages repository for "file picker" but didn't find one.
Is there a way to get a File Picker that looks like this:
or even this...
The first screenshot is preferable for me as it allows file selection from different sources (like Drive).
Also, since I want to Export the data, I might want a Folder Picker too. ;)
But, if there is any other alternative to Folder Picker. I'd be happy to know...
I've created a file_picker plugin some time ago in order to make it possible to pick (both on iOS and Android) absolute paths and then loaded it with Flutter.
You can check it here: https://pub.dev/packages/file_picker
I used file_picker library to pick files. you can use this for pick images as well.
Future getPdfAndUpload(int position) async {
File file = await FilePicker.getFile(
type: FileType.custom,
allowedExtensions: ['pdf','docx'], //here you can add any of extention what you need to pick
);
if(file != null) {
setState(() {
file1 = file; //file1 is a global variable which i created
});
}
}
here file_picker flutter library.
I'm in the exact same boat as you, haha!
I noticed documents_picker 0.0.2. It allows the user to pick multiple files, and it seems to fit the need!
check it out: https://pub.dartlang.org/packages/documents_picker#-readme-tab-
Here's a better document picker. It looks like the native document picker from the Storage Access Framework, which is what you have in your picture.
flutter_document_picker
Just found the FileSelector plugin from flutter.dev. Compatible with MacOS, Windows and Web.
From its pub.dev page:
Open a single file
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final file = await openFile(acceptedTypeGroups: [typeGroup]);
Open multiple files at once
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final files = await openFiles(acceptedTypeGroups: [typeGroup]);
Saving a file
final path = await getSavePath();
final name = "hello_file_selector.txt";
final data = Uint8List.fromList("Hello World!".codeUnits);
final mimeType = "text/plain";
final file = XFile.fromData(data, name: name, mimeType: mimeType);
await file.saveTo(path);
MacOS: Provide file read or/and write privileges
On target MacOS please provide sufficient rights using Xcode:
In case you don't provide file read or/and write permissions, the call to
final XFile? file =
await openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);
neither shows anything not returns.

firefox addon installation issue

After worked on many small addon i want to put those add on on my server so that people can download it and use it so that i can get the feedback from the people ..but when i am downloading it from my server(it is a xpi file) getting following error..
Firefox could not install the file at
http://abhimanyu.homeunix.com/Work/abhiman_2k5#yahoo.com.xpi
because: Install script not found
-204
but when i m putting these files manually in the path it works fine..After fiddling many hours couldn't figure it out whats the problem ...please help me.
I assume that you are letting the users download your add-on through some install button.
Unfortunately, its not as simple as pointing the browser to the xpi file on the server's file system. Below, I have pasted the script that installs Omture when the user presses on the "Download Omture" button on the add-on's website which you could also find using firebug.
function installExt()
{
var url="omture_current.xpi";
InstallTrigger.install({
"Omture": { URL: url,
toString : function() { return this.URL; } } });
return false;
}

Resources