-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Version 141.0.110
I founded a bug in my code, when I use this DownloadHanlder, Whenever the front end calls for a download, like this:
cef.browserFileDownload(downloadUrl, path, filename, subDirectories).then(() => {
const downloadLink = document.createElement('a')
downloadLink.download = filename
downloadLink.href = downloadUrl
downloadLink.click()
})
When the download is complete, the method ExecuteJavaScriptCallback is triggered, and then the next download begins. However, I found that this only downloads one or two files before stopping for no reason, as if it was interrupted. But when I use version 119, the downloads complete normally.
Here is my code:
public class DownloadHandler : IDownloadHandler {
public delegate void DownLoadCompleteHandler(string SuggestedFileName);
public static DownLoadCompleteHandler DownLoadCompleteEvent;
public static ConcurrentDictionary<string, string> downLoadDict = new ConcurrentDictionary<string, string>();
public static void DownLoadQueueEnqueue(KeyValuePair<string, string> keyValue) {
try {
downLoadDict[keyValue.Key] = keyValue.Value;
LogHelper.WriteWeb($"Enqueued download: {keyValue.Key} -> {keyValue.Value}");
} catch (Exception ex) {
LogHelper.WriteError($"DownLoadQueueEnqueue error: {ex.Message}");
}
}
public static void ClearAll() {
try {
downLoadDict.Clear();
LogHelper.WriteWeb("DownloadHandler.ClearAll called");
} catch (Exception ex) {
LogHelper.WriteError($"ClearAll error: {ex.Message}");
}
}
public bool OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser,
DownloadItem downloadItem, IBeforeDownloadCallback callback) {
try {
if (callback == null || callback.IsDisposed) {
LogHelper.WriteWeb("OnBeforeDownload: callback is null or disposed");
return false;
}
string downloadPath;
bool showDialog = true;
LogHelper.WriteWeb($"OnBeforeDownload called for: {downloadItem.OriginalUrl}");
if (downLoadDict.TryGetValue(downloadItem.OriginalUrl, out string customPath)) {
if (!string.IsNullOrEmpty(customPath)) {
if (!Directory.Exists(customPath)) {
Directory.CreateDirectory(customPath);
}
downloadPath = Path.Combine(customPath, downloadItem.SuggestedFileName);
showDialog = false;
LogHelper.WriteWeb($"Custom download path: {downloadPath}");
} else {
downloadPath = GetDefaultDownloadPath(downloadItem.SuggestedFileName);
LogHelper.WriteWeb($"Default download path: {downloadPath}");
}
} else {
downloadPath = GetDefaultDownloadPath(downloadItem.SuggestedFileName);
LogHelper.WriteWeb($"Not in dict, using default: {downloadPath}");
}
callback.Continue(downloadPath, showDialog);
return true;
} catch (Exception ex) {
LogHelper.WriteError($"OnBeforeDownload error: {ex.Message}");
return false;
}
}
private string GetDefaultDownloadPath(string suggestedFileName) {
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"Downloads",
suggestedFileName
);
}
public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser,
DownloadItem downloadItem, IDownloadItemCallback callback) {
try {
LogHelper.WriteWeb($"OnDownloadUpdated: Url={downloadItem.OriginalUrl}, Complete={downloadItem.IsComplete}, Progress={downloadItem.PercentComplete}, Received={downloadItem.ReceivedBytes}, Total={downloadItem.TotalBytes}");
if (downloadItem.IsComplete) {
try {
if (downLoadDict.TryRemove(downloadItem.OriginalUrl, out string removedPath)) {
LogHelper.WriteWeb($"Removed mapping for {downloadItem.OriginalUrl} -> {removedPath}");
} else {
LogHelper.WriteWeb($"No mapping found to remove for {downloadItem.OriginalUrl}");
}
} catch (Exception ex) {
LogHelper.WriteError($"Error removing mapping: {ex.Message}");
}
try {
if (chromiumWebBrowser != null) {
ExecuteJavaScriptCallback(chromiumWebBrowser, downloadItem.OriginalUrl);
} else if (browser != null) {
ExecuteJavaScriptCallback(browser, downloadItem.OriginalUrl);
} else {
LogHelper.WriteWeb("No browser reference available to execute JS callback.");
}
} catch (Exception ex) {
LogHelper.WriteError($"Error executing JS callback: {ex.Message}");
}
}
} catch (Exception ex) {
LogHelper.WriteError($"OnDownloadUpdated error: {ex.Message}");
}
}
// Execute JS using IWebBrowser
private void ExecuteJavaScriptCallback(IWebBrowser chromiumWebBrowser, string downloadUrl) {
try {
string js = string.Format("browserFileDownloadCallback('{0}')", downloadUrl);
chromiumWebBrowser.GetMainFrame().ExecuteJavaScriptAsync(js);
LogHelper.WriteWeb(js);
} catch (Exception ex) {
LogHelper.WriteError($"ExecuteJavaScriptCallback error (IWebBrowser): {ex.Message}");
}
}
private void ExecuteJavaScriptCallback(IBrowser browser, string downloadUrl) {
try {
string safe = downloadUrl.Replace("\\", "\\\\").Replace("'", "\\'").Replace("\"", "\\\"");
string js = string.Format("browserFileDownloadCallback('{0}')", safe);
var frame = browser?.MainFrame;
frame?.ExecuteJavaScriptAsync(js);
LogHelper.WriteWeb(js);
} catch (Exception ex) {
LogHelper.WriteError($"ExecuteJavaScriptCallback error (IBrowser): {ex.Message}");
}
}
public bool CanDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, string url, string requestMethod) {
return true;
}
}