18

I need to download a file to a specific location in my Electron program.
I tried implementing this API but failed.
Then I tried implementing the official API, but couldn't realize how to actually start downloading the file.

How can I download a file to a specific location, say C:\Folder?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
avi12
  • 2,000
  • 5
  • 24
  • 41
  • What do you mean by failed.Saring code sample will be helpful to figure out the issue.Are you using download tag in your html. From where you are using that official API main process or render process – Jeya Kumar Sep 09 '17 at 20:50
  • From what I understood, as examples use `ipcMain`, I passed a message from the `renderer.js` to the `main.js`, then when received the message - immediately attempted to start downloading the specific file to the sent location - except nothing happened, i.e. the attempt has failed. – avi12 Sep 10 '17 at 21:55

3 Answers3

46

I ended up using electron-dl.
To send a download request (from the renderer.js):

ipcRenderer.send("download", {
    url: "URL is here",
    properties: {directory: "Directory is here"}
});

In the main.js, your code would look something like this:

const {app, BrowserWindow, ipcMain} = require("electron");
const {download} = require("electron-dl");
let window;
app.on("ready", () => {
    window = new BrowserWindow({
        width: someWidth,
        height: someHeight
    });
    window.loadURL(`file://${__dirname}/index.html`);
    ipcMain.on("download", (event, info) => {
        download(BrowserWindow.getFocusedWindow(), info.url, info.properties)
            .then(dl => window.webContents.send("download complete", dl.getSavePath()));
    });
});

The "download complete" listener is in the renderer.js, and would look like:

const {ipcRenderer} = require("electron");
ipcRenderer.on("download complete", (event, file) => {
    console.log(file); // Full file path
});

If you want to track your download's progress:

In main.js:

ipcMain.on("download", (event, info) => {
    info.properties.onProgress = status => window.webContents.send("download progress", status);
    download(BrowserWindow.getFocusedWindow(), info.url, info.properties)
        .then(dl => window.webContents.send("download complete", dl.getSavePath()));
});

In renderer.js:

ipcRenderer.on("download progress", (event, progress) => {
    console.log(progress); // Progress in fraction, between 0 and 1
    const progressInPercentages = progress * 100; // With decimal point and a bunch of numbers
    const cleanProgressInPercentages = Math.floor(progress * 100); // Without decimal point
});
avi12
  • 2,000
  • 5
  • 24
  • 41
  • How to speed downloading up ! for example, let's say we I wanted to download a file. if gonna download it like chrome which is very slow it become useless. I wanted it to work like idm. And how to pause and resume . – Raja Osama Jul 28 '18 at 09:39
6

To allow a user to download a file in an Electron application, you need to do the following:

  1. Get either the default session or the session of the user from the partition. See Session

  2. Once you have an instance of the session object, you can then listen for events like will-download which is emitted on Session object when the user clicks on a link to download a file and the file is going to be downloaded.

  3. The will-download event returns the item which is going to be downloaded. This item contains the necessary events (downloaded, failed, paused etc.) and necessary methods (where to save the file) etc.

Now, regarding the query on How to download a file to C:/folder ?

You have 2 choices regarding that:

  1. You can either ask the user to set the download location (Default behavior)
  2. You can set the download location for the file using item object, that you get from the event will-download. Use the method setSavePath on the item object.

If you rather want to set the default download location for all the files, then you can use, setDownloadPath on the session object. Then that will be the default path for that session.

Akshay Anurag
  • 724
  • 1
  • 8
  • 27
4

as you mentioned yourself, electron-dl seems to be the popular way to do that. Mainly from the github page: npm i -S electron-dl

const {BrowserWindow} = require('electron');
const {download} = require('electron-dl');
download(BrowserWindow.getFocusedWindow(), "http://url-to-asset", {directory:"c:/Folder"})
mbehzad
  • 3,758
  • 3
  • 22
  • 29
  • The thing is, I have to call the API from the renderer page, so I have to pass messages and things like that. Also, I must be able to track the download progress, in order to update a `` element, and finally - I must have an event that will be fired when the download will be finished. When I called `.then()`, Electron threw an exception, as ".then() is undefined". – avi12 Sep 08 '17 at 10:36
  • I implemented this code, But I need to give the local computer folder path from which I need to download the files. For example "\\192.168.XX.XXX\\D001\\P001\\sample.pdf". It gives me error "cannot read property 'get typeof null ". – Ravindra Vairagi Jun 24 '19 at 14:51
  • 1
    Can you please help! – Ravindra Vairagi Jun 24 '19 at 14:51
  • Hello. I am also facing the same problem and thanks to you. On multiple files, the progress bar considers downloading small positive comments 100%. How do I get through this? – Tolga Günaydın Jul 13 '21 at 07:58