Developing an app in electron, everything is working fine with file path in development mode. I created the "documents" folder, in which documents will be stored.
var dir = path.join(__dirname, 'documents');
fs.readdir(dir, function (err, files) {
if (err) {
console.log('Unable to scan directory: ' + err);
}
var files_with_dirs = files.map(function(name) {
return (dir + '/'+ name);
});
This code return all files in "documents" folder.
But in production mode when i pack my app, a folder with many files is created, the path becomes like this.
How to solve this problem?
For paths pointing to internal resources, I'd suggest using a relative path and building it on the fly
var p = upath.toUnix(upath.join(__dirname, "documents", "this-image.jpg));
Where __dirname is the path to the currently executing file.
I use the upath toUnix function because it normalizes the path to use forward slashes – which has worked better for me with cross--platform apps..
Related
I was working on a project that need some files to be downloaded into storage and later works offline . I am using Expo's Filesystem api to download the file and then saving the file in Expo FileSystem.documentDirectory
let directory = FileSystem.documentDirectory + 'media/';
await FileSystem.downloadAsync(imageurl,
directory + 'filename.jpg'
)
.then(({ uri }) => {
console.log(uri,'uri of image')
});
The problem is when i was updating app in itunesconnect the data is not persisting.
I guess you are trying to recover that file with absolute path after the update. Use a relative path instead.
iOS will update UUID of directory each time you change your build (ex. different builds on TestFlight or different version on AppStore).
ref: https://github.com/expo/expo/issues/4261#issuecomment-494072115
What you need to do is to store the filename into some persistent storage and combine that with FileSystem.documentDirectory to recover that file later, because your file is saved and the relative path works fine but the absolute path has changed.
Here is an example of copying an image into the document directory and recover that file later.
const to = FileSystem.documentDirectory + filename
await FileSystem.copyAsync({
from: uri, // uri to the image file
to
})
dispatch({ type: 'STORE_FILENAME', filename }) // Anything that persists. I use redux-persist
// ...after you updated the app to a different build
const filename = props.filename // recovered from the previous build anyhow
const uri = FileSystem.documentDirectory + filename
// maybe you want to render that image
return <Image uri={uri} />
I have an Portable Electron App (packed with: electron-builder + asar, portable build) on Windows. I try to get the application path but it returns a path within the user\temp folder rather than the actual '.exe' file
Is there any way to get the original app.exe path?
I've tried the following:
app.getAppPath()
__dirname
require.main.filename
app-root-path
and a few node modules
The path I'm getting from my tests:
C:\Users\xxx\AppData\Local\Temp\xxxxxx.tmp\app
the actual .exe Path (where the app launched from, and what i need):
C:\Users\XXX\Documents\test\dist
I'm just starting with Electron.
I found a solution:
Use the Environment Variable (created by Electron-Builder)
process.env.PORTABLE_EXECUTABLE_DIR
to show the real Path of the App.exe.
Works only packed with Electron-Builder
From the main process:
// If not already defined...
const { app } = require ('electron');
const path = require ('path');
let execPath;
execPath = path.dirname (app.getPath ('exe'));
// or
execPath = path.dirname (process.execPath);
From a renderer process:
// If not already defined...
const { remote } = require ('electron');
const path = require ('path');
let execPath;
execPath = path.dirname (remote.app.getPath ('exe'));
// or
execPath = path.dirname (remote.process.execPath);
I had a lot of trouble with this and was finally able to solve the issue by replacing __dirname by '.', see working example below :
const path = require('path')
const myAppPath = path.resolve('.', 'myapp.exe');
Seems like PORTABLE_EXECUTABLE_FILE only works under certain Electron-Builder configurations; In particular, it won't work in apps deployed as a portable directory.
In such cases, the following will get you the application root path:
const path = require('path')
import { app } from 'electron'
let rootDir = app.getAppPath()
let last = path.basename(rootDir)
if (last == 'app.asar') {
rootDir = Path.dirname(app.getPath('exe'))
}
None of the above answers worked for me on Windows 10.
process.env.PORTABLE_EXECUTABLE_DIR returns the Temp directory path.
I got it to work using:
process.env.INIT_CWD
process.env.PORTABLE_EXECUTABLE_FILE
will give you the full path to the file.
As none of the methods above worked and I don't want to use an external lib for this, i tried following:
if (!fs.existsSync("../images")) {
fs.mkdirSync("./../images");
}
return path.resolve("./../images/") + "/";
You can use any directory that should exist at the top level or anywhere else. In my case I know that one level higher in the directory there must be a directory called "images".
This solution worked in my case for DEV build and prod (packaged).
Are there any drawbacks when using this approach?
I am using react-native-sqlite-storage and I can not find a way to get it to open a database that is already in documents directory (downloaded from internet). The file name specified seems to point to a file in the app bundle, which when running on iOS is copied by the library from the bundle to the app's Library folder (since you cant modify files in the iOS app bundle). How can I force it to make use of a file already in the documents folder (or library folder if i move it there)?
React-Native-Sqlite-Storage uses a subdirectory within the apps library folder. The directory is called localDatabase. Copy, or download, or move your database to that location (localDatabase), and then open the database using React-Native-Sqlite-Storage's openDatabase() function while giving it the database name.
var RNFS = require('react-native-fs');
var SQLite = require('react-native-sqlite-storage');
/*copy file from app bundle to library/localDatabase*/
var sourcePath = RNFS.MainBundlePath + '/' + 'myDatabase.sqlite';
var destinPath = RNFS.RNFS.LibraryDirectoryPath + '/LocalDatabase/' + 'myDatabase.sqlite';
RNFS.copyFile(sourcePath, destinPath)
.then(() =>{
var db = SQLite.openDatabase("myDatabase.sqlite", "1.0", "", 200000, me._openCB, me._errorCB);
})
Using PapaParse, I am trying to parse a CSV located locally on an iOS device. The sample code below is pretty straight forward except that it does not take a file path. I do have the path to the local file but I'm not sure how properly insert that in place of fileInput.files[0]. I tried using File() to create a file from the path but could not get anywhere. How can I parse a local csv, in react native using PapaParse?
Papa.parse(fileInput.files[0], {
complete: function(results) {
console.log(results);
}
});
Just to add to Answer above by #pnizzle.
For some reason you can access Image files as long as they are in your React Native project's directory, with a relative path from your current js file.
For CSV file I had to bundle them with my iOS project (I grouped the files in a Assets folder) then use RNFS to get the path for my MainBundleDirectory and access my .CSV files from there.
Hope this helps anyone else in a similar bind.
var mainBundlePath = RNFS.MainBundlePath;
var path = '/Assets/CSVData.csv';
Papa.parse(mainBundlePath+path, {
download: true,
delimiter: '\t',
complete: function(results) {
console.log('This is ME..');
console.log(results);
}
});
UPDATE: You must first import the file, just as you would a component.
import myDataset from '../path/to/myDataset.csv';
Then you will use myDataset as your file to download with Papa.parse like so...
Papa.parse(myDataset, {
download: true,
delimiter: '\t'
complete: function(results) {
console.log(results);
}
});
Specify a config value for download as true.
Delimiter should be auto-detected, as per Papa Parse documentation.
I'm using react-native-fetch-blob to download mp3 files and then playing them later. The problem is that the actual path for RNFetchBlob.fs.dirs.DocumentDir changes when I close the app and restart again, which means I can't use the absolute file path I stored right after downloading the files retrieve the files in the next run of the app.
Here's my code for downloading and storing the file paths:
export function downloadAudio(urlArray) { //download every section in the urlArray
return (dispatch) => {
Promise.all(urlArray.map(section => {
dispatch(startDownload(section.section_id))
console.log('download start for id = ',section.section_id ) //start download
return RNFetchBlob
.config({
path: RNFetchBlob.fs.dirs.DocumentDir + '/courseSections/' + section.section_id + '.mp3',
appendExt: 'mp3'
})
.fetch('GET', section.section_url, {
'Cache-Control': 'no-store'
})
.progress({ count: 10 }, (received, total) => {
console.log(`progress for section ${section.section_id}: `, Math.floor(received/total*100), '%')
dispatch(downloadProgress({id: section.section_id, progress: Math.floor(received/total*100)/100}))
})
.then(res => {
console.log(`section ${section.section_id} is saved to: `, res.path())
return { path: res.path(), id: section.section_id }
})
.then(pathInfo => dispatch(downloadSuccess(pathInfo))) //download finished
}))
.catch((error, statusCode) => {
console.log(statusCode, ' error: ', error)
})
}
}
I stored { path: res.path(), id: section.section_id } as part of persisted app state. But it's not useful cuz next time I open the app, the file path has been reassigned. For example, here's the path one file was downloaded to:
downloaded file path
But after I close the app and restart, the path is changed to:
/Users/NatashaChe/Library/Developer/CoreSimulator/Devices/830778DE-3CE3-4FC7-AA4B-DFBAE999751C/data/Containers/Data/Application/0C47E33F-ACF8-4539-9456-8FF3E8FBECB2/Documents/courseSections/14.mp3
i.e. the files got assigned to a different sub-folder under the Application folder.
Obviously the audio player (I'm using react-native-sound) can't find the file using the original path that the app has stored. So my question is: Is there a way I can fix the path? Or is there some other way of retrieving files that I'm not aware of?
And also, I'm using the iOS simulator on my computer. Haven't tried this on the phone yet. Does anyone know if the above code can be directly used on iphone and have the file saved to my app's directory? Or shall I set the file path in any other way?
I'm using react native 0.41.
I made the following change to make it work, at least on simulator for now. Not sure what'd happen on an actual phone.
When retrieving the file, instead of using the file path as returned by res.path() as in the code above, I now directly use filePath = RNFetchBlob.fs.dirs.DocumentDir + '/courseSections/' + sectionInfo.section.section_id + '.mp3' when retrieving the file.