TMSFNCEdgeWebBrowser -> DownloadStateChanged

The event is only triggered if all downloads are completed.

procedure TForm1.TMSFNCEdgeWebBrowser1DownloadStateChanged(Sender: TObject;
ADownload: TTMSFNCWebBrowserDownload; AState:
TTMSFNCWebBrowserDownloadState; var APause, AResume, ACancel: Boolean);
begin

Adownload points to a specific download Item.
Isn't the event ment to triigger this specific Download.

If you itterate throug the download Items they have all the same state,
no matter if they are completet or not ...

If I delete one of the download-Items it still remained in the download List.

I've tried this locally and this doesn't seem to be the case.

It can be that the events are too close to each other that the other one is already handled as well before the event is in. As the WebBrowser is an asynchronous control this might be the case.

The following code tested with two different downloads gave me the output I expected.

procedure TForm5.CheckBtnClick(Sender: TObject);
var
  I: Integer;
  st: string;
begin
  if TMSFNCEdgeWebBrowser1.Downloads.Count = 0 then
  begin
    TTMSFNCUtils.Log('No Downloads available');
  end
  else
  begin
    for I := 0 to TMSFNCEdgeWebBrowser1.Downloads.Count - 1 do
    begin
      case TMSFNCEdgeWebBrowser1.Downloads[I].State of
        dsInProgress: st := 'Progress';
        dsInterrupted: st := 'Interrupted';
        dsCompleted: st := 'Completed';
        dsCancelled: st := 'Cancelled';
      end;
      TTMSFNCUtils.Log(I.ToString + ' ' + st + ': ' + TMSFNCEdgeWebBrowser1.Downloads[I].URI);
    end;
  end;
end;

procedure TForm5.ClearBtnClick(Sender: TObject);
begin
  TMSFNCEdgeWebBrowser1.Downloads.ClearFinishedDownloads;
  TTMSFNCUtils.Log('Cleared Finished Downloads.');
  CheckBtnClick(Self);
end;

procedure TForm5.TMSFNCEdgeWebBrowser1DownloadStarted(Sender: TObject;
  ADownload: TTMSFNCWebBrowserDownload; var ASilent, APause, AResume,
  ACancel: Boolean);
begin
  TTMSFNCUtils.Log('Started: ' + ADownload.URI);
end;

procedure TForm5.TMSFNCEdgeWebBrowser1DownloadStateChanged(Sender: TObject;
  ADownload: TTMSFNCWebBrowserDownload; AState: TTMSFNCWebBrowserDownloadState;
  var APause, AResume, ACancel: Boolean);
var
  st: string;
begin
  case AState of
    dsInProgress: st := 'Progress';
    dsInterrupted: st := 'Interrupted';
    dsCompleted: st := 'Completed';
    dsCancelled: st := 'Cancelled';
  end;
  TTMSFNCUtils.Log(st + ': ' + ADownload.URI);
end;
--- First download started
Debug Output: Started: https://files.icyflamestudio.com/200MB.zip?_gl=1*4ssytq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIwNi4wLjAuMA.. Process Project1.exe (8960)
----- Second download started
Debug Output: Started: https://files.icyflamestudio.com/512MB.zip?_gl=1*f1hhiq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIxNC4wLjAuMA.. Process Project1.exe (8960)
----- Both are in progress
Debug Output: 0 Progress: https://files.icyflamestudio.com/200MB.zip?_gl=1*4ssytq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIwNi4wLjAuMA.. Process Project1.exe (8960)
Debug Output: 1 Progress: https://files.icyflamestudio.com/512MB.zip?_gl=1*f1hhiq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIxNC4wLjAuMA.. Process Project1.exe (8960)
---- StateChanged Event first download 
Debug Output: Completed: https://files.icyflamestudio.com/200MB.zip?_gl=1*4ssytq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIwNi4wLjAuMA.. Process Project1.exe (8960)
---- First completed second in progress
Debug Output: 0 Completed: https://files.icyflamestudio.com/200MB.zip?_gl=1*4ssytq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIwNi4wLjAuMA.. Process Project1.exe (8960)
Debug Output: 1 Progress: https://files.icyflamestudio.com/512MB.zip?_gl=1*f1hhiq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIxNC4wLjAuMA.. Process Project1.exe (8960)
---- StateChanged second download
Debug Output: Completed: https://files.icyflamestudio.com/512MB.zip?_gl=1*f1hhiq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIxNC4wLjAuMA.. Process Project1.exe (8960)
---- Both downloads completed
Debug Output: 0 Completed: https://files.icyflamestudio.com/200MB.zip?_gl=1*4ssytq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIwNi4wLjAuMA.. Process Project1.exe (8960)
Debug Output: 1 Completed: https://files.icyflamestudio.com/512MB.zip?_gl=1*f1hhiq*_ga*NzIzNTEzODIxLjE3MDgwMDY5NTg.*_ga_696EXTL0Q2*MTcwODAwNjk1OC4xLjEuMTcwODAwNzIxNC4wLjAuMA.. Process Project1.exe (8960)

When the ClearBtn is tested after completion I get the following:

Debug Output: Started: https://files.icyflamestudio.com/200MB.zip?_gl=1*1gvv3m5*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzMy4wLjAuMA.. Process Project1.exe (19108)
Debug Output: Started: https://files.icyflamestudio.com/512MB.zip?_gl=1*ks0grt*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzNS4wLjAuMA.. Process Project1.exe (19108)
---- Check 
Debug Output: 0 Progress: https://files.icyflamestudio.com/200MB.zip?_gl=1*1gvv3m5*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzMy4wLjAuMA.. Process Project1.exe (19108)
Debug Output: 1 Progress: https://files.icyflamestudio.com/512MB.zip?_gl=1*ks0grt*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzNS4wLjAuMA.. Process Project1.exe (19108)
---- StateChanged
Debug Output: Completed: https://files.icyflamestudio.com/200MB.zip?_gl=1*1gvv3m5*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzMy4wLjAuMA.. Process Project1.exe (19108)
---- Check
Debug Output: 0 Completed: https://files.icyflamestudio.com/200MB.zip?_gl=1*1gvv3m5*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzMy4wLjAuMA.. Process Project1.exe (19108)
Debug Output: 1 Progress: https://files.icyflamestudio.com/512MB.zip?_gl=1*ks0grt*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzNS4wLjAuMA.. Process Project1.exe (19108)
----
Debug Output: Cleared Finished Downloads. Process Project1.exe (19108)
----
Debug Output: 0 Progress: https://files.icyflamestudio.com/512MB.zip?_gl=1*ks0grt*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzNS4wLjAuMA.. Process Project1.exe (19108)
----
Debug Output: Completed: https://files.icyflamestudio.com/512MB.zip?_gl=1*ks0grt*_ga*MTA1NDQwMjExNS4xNzA4MDA4MjI4*_ga_696EXTL0Q2*MTcwODAwODIyOC4xLjAuMTcwODAwODIzNS4wLjAuMA.. Process Project1.exe (19108)
----
Debug Output: Cleared Finished Downloads. Process Project1.exe (19108)
----
Debug Output: No Downloads available Process Project1.exe (19108)

Hmm,

Over all it's the same code I used myself,
but the DownloadChanged Event isn't triggered until ALL downloads are Completed.

It's not so easy to debug, cause everything is asynchronous.
With breakpoints the behavior changes completely.

I will check everything again and come back here to report.

No, it doesn't work for me.
The only differenz between our code is,
that I rename the ADownload.URI in TMSFNCEdgeWebBrowser1DownloadStarted

I got a reply for : Started, Canceled, Interruptet and Progess but none for Completed

by the way, where can I find the Logfile ? ( I use a memo for the messages )

New knowledge :
Status is set for smaller downloads to : Completed.
Big downloads > 4GB stayed in : InProgress for ever ...

Size matters : Looks like a kind of overflow ( Int ? )

No solution ?
My application should start max. 2 download at the same time,
so I had to know if the previous downloads are finished or not.

Big downloads ( 11-15 GByte ) stuck [in processing] status for ever ...

No suggestions ?
I really debugged erverything and it turned out,
that the callbackfunctions who shoud return the recieved bytes crashes.

At least when the ADownload.ResultFilePath gets changed.

the downloads are still running ( native Download Window in Edge )
but only the last download had his callbackfunction ( revieded bytes ) running.

This means, that only the last download ever reaches completet Status.

If there is no solution I had to bury 3 weeks of hard work .. not lucky with that ...

@Gjalt_Vanhouwaert

Okay, I finally found the reason :

The Callback Funtions ( Bytes Recieved ) get lost
when the Web-Page ( the download started from ) changes.

for example with the [Back-Button] -> Download still running / onBytesRecieved dead

this is the reason why your demo works : Downloads are finished before leaving page

Can You please check this and provide at least a workaround.
The Callback funktion dosn't make sense if it get lost by leaving the Page ( not the site )

We'll investigate this as soon as possible.

After some more research we found a page with other users having similar problems.

There are some remarks of the events not being triggered. We'll further look and monitor and get some more information about what is going wrong exactly.

As long as I don't leave the webpage, every Event is fired as expected,
even the Bytes-Received counts from 0 to Max >>> Result = Completed.

But as soon as I leave the Download Page to carry on with the next download,
the callback function gets lost. The download kept in downloads ( still running )

In the Native Download Window ( Silent := False ) everything works fine.

At the moment, I end up with a Max of one running download,
LOL : not exact what I had in mind with my download manager :slight_smile:

Everything keeps running, but the events are not triggered. So basically right now in the current state, you could run a timer & periodically check the downloads, as my colleague showed:

procedure TForm5.CheckBtnClick(Sender: TObject);
var
  I: Integer;
  st: string;
begin
  if TMSFNCEdgeWebBrowser1.Downloads.Count = 0 then
  begin
    TTMSFNCUtils.Log('No Downloads available');
  end
  else
  begin
    for I := 0 to TMSFNCEdgeWebBrowser1.Downloads.Count - 1 do
    begin
      case TMSFNCEdgeWebBrowser1.Downloads[I].State of
        dsInProgress: st := 'Progress';
        dsInterrupted: st := 'Interrupted';
        dsCompleted: st := 'Completed';
        dsCancelled: st := 'Cancelled';
      end;
      TTMSFNCUtils.Log(I.ToString + ' ' + st + ': ' + TMSFNCEdgeWebBrowser1.Downloads[I].URI);
    end;
  end;
end;

That's exactly what I do,

but when the callback Function gets lost,
the download state sticks in "dsInProgress" forever ..

TMSFNCEdgeWebBrowser1.Downloads.ClearFinishedDownloads

doesn't work as well ( because everything seems in Progress even if it's finished )

Is there a possibility to cast ( TMSFNCEdgeWebBrowser1 )
and read the download progress from the native download window ?

No, the way it is implemented right now is the only way to access download information. We'll investigate this here more in detail, stay tuned.

Perhaps this can be a solution for the time, while we are investigating if we can find a work around for the issues in the WebView2 control.

It checks the size of the file (this only changes when initialized and when it is complete).

function FileSize(const name: string): LongInt;
var
  SRec: TSearchRec;
begin
  if FindFirst(name, faAnyfile, SRec) = 0 then
  begin
    Result := SRec.Size;
    FindClose(SRec);
  end
  else
    Result := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  I: Integer;
  f: string;
  curSize: Int64;
begin
  for I := 0 to TMSFNCEdgeWebBrowser1.Downloads.Count - 1 do
  begin
    f := TMSFNCEdgeWebBrowser1.Downloads[I].ResultFilePath;
    curSize := FileSize(f);

    if not (curSize < TMSFNCEdgeWebBrowser1.Downloads[I].TotalBytes) then
      TTMSFNCUtils.Log('Complete: '+ curSize.ToString + '/'+ TMSFNCEdgeWebBrowser1.Downloads[I].TotalBytes.ToString)
  end;
end;

This will solve at least one problem. :+1:

Subsequent, I had to clean up the Download[i] List.

The main problem is, that the download often gets interrupted
then I start a timer and force them to resume ( otherwise I had to restart at begin )

I'll be patience and wait for your insight :slight_smile:

Hi,

We have confirmed this issue as it's not working in Visual Studio as well with a WebView instance connected to the download state changed or bytes received event handlers. We have opened a report

Hi Pieter,

in the meantime, I tried to handle the downloads with :slight_smile:

    var LBase : TTMSFNCCloudBase;

    try
      LBase := TTMSFNCCloudBase.Create;
      LBase.SimpleGETSyncAsStream(Edit1.Text).SaveToFile(FileName);
      // LStream := LBase.SimpleGETSyncAsStream(Edit1.Text);
      // LStream.SaveToFile(FileName);
    finally
      // LStream.Clear;
      LBase.Free;
    end;

But there are problems as well.

First try : ( with LStream)
without LStream.Clear my App runs out of memory ??

Second try : ( Write direct to File)
with Filesize > 4 GB LBase Crashes with Buffer Overflow ...