Finished Async download goes off twice instead of once - c#

I have this code in my application that allows user to download the newest version of the application. When the application download is finished, it opens a prompt if user wants to open the file location to see the file.
However, the tool launches two Message boxes instead of only once. I'm not sure if I'm missing something.
private void BTN_GNV_MouseUp(object sender, MouseButtonEventArgs e)
{
string URLDir = "http://shard.combatkingz.com/downloads/";
string URLName = "DayZ Config Tweak tool v" + Properties.Settings.Default.AvailableVersion + ".exe";
string URLFull = "";
using (WebClient DLWC = new WebClient())
{
URLFull = URLDir + URLName;
GlobalVars.DLPath = System.Environment.CurrentDirectory + "\\" + URLName;
try
{
DLWC.DownloadFileAsync(new Uri(URLFull), GlobalVars.DLPath);
DLWC.DownloadProgressChanged += DLWC_DownloadProgressChanged;
}
catch
{
MessageBox.Show("There was an error downloading the file.", GlobalVars.APPNAME, MessageBoxButton.OK, MessageBoxImage.Error);
#if DEBUG
#else
AddDownloadToDB("Failed");
#endif
}
}
}
void DLWC_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
PB_GNV.Width = (BTN_GNV.Width / 100) * e.ProgressPercentage;
if (PB_GNV.Width == BTN_GNV.Width && e.TotalBytesToReceive == e.BytesReceived)
{
MessageBoxResult nav = MessageBox.Show("New version downloaded. Do you want to navigate to the folder?", GlobalVars.APPNAME, MessageBoxButton.YesNo, MessageBoxImage.Error);
if (nav == MessageBoxResult.Yes)
{
string argument = #"/select, " + #GlobalVars.DLPath;
System.Diagnostics.Process.Start("explorer.exe", argument);
#if DEBUG
#else
AddDownloadToDB("Success");
#endif
}
}
}

I suspect that the DownloadProgressChanged event is firing on receiving the last byte and on the file completed. Using the DownloadFileCompleted event should resolve the problem.

Related

C#Webclient downloadfileasync not working

/// <summary>
/// 下载更新
/// </summary>
public string Update()
{
string result = "";
try
{
if (!isUpdate)
return result;
WebClient wc = new WebClient();
string filename = "Update_NewVersion.zip";
filename = Path.GetDirectoryName(loadFile) + "\\" + filename;
FinalZipName = filename;
//wc.DownloadFile(download, filename);//能下载成功
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileAsync(new Uri(download), filename);//使用DownloadFileAsync下载不成功,能正常运行代码,但是执行后没有下载到zip文件,
//wc.Dispose();
return result = "download:" + download + ",filename:" + filename;
}
catch (Exception ex)
{
throw new Exception("更新出现错误,网络连接失败!" + ex.Message);
}
}
void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
(sender as WebClient).Dispose();
if (e.Error != null)
throw e.Error;
else
isFinish();
}
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
CommonMethod.autostep = e.ProgressPercentage;
//Thread.Sleep(100);
}
The download file code using downloadfileasync works normally, but it is not downloaded to the file after execution. It has been tested that downloadfile can be downloaded to the file normally。
Is it because the program completed the running before the download finished? It is a possible reason if your app is a console application.
Following comes from mdsn:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfileasync?view=net-5.0
This method does not block the calling thread while the resource is being downloaded. To block while waiting for the download to complete, use one of the DownloadFile methods.

message id went wrong when using CEF devtools ExecuteDevToolsMethodAsync and Page.captureScreenshot

I have added a CEF control into a WinForm. And I have added an invokeCapture method that is expected to capture the screen shot of the entire page of the CEF. It works fine when first invoking. But errors are encountered since second invoking and more, which the message is "Generated MessageID 100002 doesn't match returned Message Id 100001". How can I capture screen shot more than once?
I have copied the screenshot function code from https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/DevTools/DevToolsExtensions.cs to my project and renamed the namespace of it to winformcefdemo.CefSharp.Example.
The variable lastMessageId of the class DevToolsClient, in which class CaptureScreenshot executes ExecuteDevToolsMethodAsync in order to run command "Page.CaptureScreenshot", is private and there are either no getter nor setter to it. It seems to be annoying. The method ExecuteDevToolsMethodAsync would want to compare the message ID of what the method ExecuteDevToolsMethod returns to the automatically increased message ID of the DevToolsClient itself. The DevtoolsClient in the method CaptureScreenShotAsPng is what browser.GetDevToolsClient() returns (in the line 36 of the link above). And I have also checked the implementation of the method GetDevToolsClient. It is also using DevToolsClient devToolsClient = new DevToolsClient(browser); in CefSharp.DevToolsExtensions.
private async void invokeCapture()
{
try
{
byte[] result = await winformcefdemo.CefSharp.Example.DevTools.DevToolsExtensions.CaptureScreenShotAsPng(browser);
// task.Start();
// byte[] result = task.Result;
SaveFileDialog dialog = new SaveFileDialog();
DialogResult dresult = dialog.ShowDialog();
if (dresult == DialogResult.OK)
{
string path = dialog.FileName;
try
{
File.WriteAllBytes(path, result);
MessageBox.Show(path + " saved success");
} catch (Exception e)
{
MessageBox.Show(path + "Unknown error occurred when saving to file: " + e.Message);
}
}
}
catch (Exception ee)
{
MessageBox.Show("Unknown error occurred when capturing: " + ee.Message);
}
}
Solved in Chinese community of CSDN
Use no DevToolsExtensions. Use PageClient Instead. DevToolsExtensions does have issues that are not solved.
And PageClient should be defined globally. Do not define it in the method.
# Source: https://bbs.csdn.net/topics/398544662
CefSharp.DevTools.Page.PageClient pageClien= null;
private async void invokeCapture()
{
if(pageClien==null)
{
pageClien = webBrowser.GetBrowser().GetDevToolsClient().Page;
}
var result = await pageClien.CaptureScreenshotAsync();
if (result.Data != null)
{
MemoryStream ms = new MemoryStream(result.Data);
ms.Write(result.Data, 0, result.Data.Length);
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "PNG Picture (*.PNG)|*.PNG";
DialogResult dresult = dialog.ShowDialog();
if (dresult == DialogResult.OK)
{
string path = dialog.FileName;
try
{
File.WriteAllBytes(path, result);
MessageBox.Show(path + " saved success");
} catch (Exception e)
{
MessageBox.Show(path + "Unknown error occurred when saving to file: " + e.Message);
}
}
}
}

File not downloading even though it says it did

I have a problem where a file won't download, even though it shows as completed.
The file is not showing in the location where it's supposed to be be downloaded to.
This is my code:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if(e.ColumnIndex == 2)
{
int rowIndex = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[rowIndex];
string value1 = row.Cells[2].Value.ToString();
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(AtlasCompleted);
Uri fileUrl = new Uri(value1);
Beta = fileUrl;
//Console.WriteLine(FormPopup.Variables.Location1.Length);
if (FormPopup.Variables.Location1 != null && FormPopup.Variables.Location1.Length >= 5)
{
Console.WriteLine(FormPopup.Variables.Location1);
Console.WriteLine(fileUrl);
wc.DownloadFileAsync(fileUrl, FormPopup.Variables.Location1);
//MessageBox.Show(fileUrl.ToString() + " " + FormPopup.Variables.Location1);
}
else
{
MessageBox.Show("Error: No file location specified.");
FormPopup form = new FormPopup();
form.Show(this);
}
}
}
private void AtlasCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show(Beta.ToString() + " " + FormPopup.Variables.Location1);
}
The file should download, but it's not downloading or appearing in the location specified.
If anyone can help that would be great, its really confusing me.
Thanks for the replies :D
The WebClient code is fine and it should download the file without any issues. Just ensure that your file Uri is correct (paste the uri into browser and see its correct). Path to save file on local system should be valid (folders included in path must exists) and regular user must have permissions to write.
To test it further, first use the hard-coded values:
wc.DownloadFileAsync("File Uril","File path at local system");
Example:
wc.DownloadFileAsync(new Uri("http://example.com/myfile.txt"), #"d:\myfile.txt");
Double check your variables for Uri and location because there is no magic that would prevent downloading besides invalid parameters.
Additionally, add some error logging/Exception handling so it tells you what happened.
private void AtlasCompleted(object sender, AsyncCompletedEventArgs e)
{
if(e.Error !=null)
Console.WriteLine(e.Error.Message);
else
Console.WriteLine("Completed");
MessageBox.Show(Beta.ToString() + " " + FormPopup.Variables.Location1);
}

How cancel Downloading Async?

I've got a problem. How can I cancel a download ?
client.CancelAsync();
Doesn't work for me, because if I cancel a download and start a new one the code still tries to access the old download file. You've to know in my code is a part when a download is done it should unzip the file which has been downloaded. Example.zip like this :)
So, when I cancel my download and start a new one you know my script tries to unzip my old Example.zip, but it should kick this ....
For Unzipping, I'm using Iconic.Zip.dll (http://dotnetzip.codeplex.com/)
How to get it work?
UPDATE:
This is my Downloader Form
private void button3_Click_1(object sender, EventArgs e)
{
DialogResult dialogResult = MessageBox.Show("This will cancel your current download ! Continue ?", "Warning !", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
cancelDownload = true;
URageMainWindow.isDownloading = false;
this.Close();
}
else if (dialogResult == DialogResult.No)
{
}
}
This is my Main form this happens when you start downloading something
private void checkInstall(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string input = storeBrowser.Url.ToString();
// Test these endings
string[] arr = new string[]
{"_install.html"};
// Loop through and test each string
foreach (string s in arr)
{
if (input.EndsWith(s) && isDownloading == false)
{
// MessageBox.Show("U.Rage is downloading your game");
Assembly asm = Assembly.GetCallingAssembly();
installID = storeBrowser.Document.GetElementById("installid").GetAttribute("value");
// MessageBox.Show("Name: " + installname + " ID " + installID);
installname = storeBrowser.Document.GetElementById("name").GetAttribute("value");
installurl = storeBrowser.Document.GetElementById("link").GetAttribute("value");
isDownloading = true;
string install_ID = installID;
string Install_Name = installname;
// MessageBox.Show("New Update available ! " + " - Latest version: " + updateversion + " - Your version: " + gameVersion);
string url = installurl;
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_InstallProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_InstallFileCompleted);
client.DownloadFileAsync(new Uri(url), #"C:\U.Rage\Downloads\" + installID + "Install.zip");
if (Downloader.cancelDownload == true)
{
//MessageBox.Show("Downloader has been cancelled");
client.CancelAsync();
Downloader.cancelDownload = false;
}
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(2, "Downloading !", "U.Rage is downloading " + installname, ToolTipIcon.Info);
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"c:/U.Rage/Sounds/notify.wav");
player.Play();
storeBrowser.GoBack();
igm = new Downloader();
igm.labelDWGame.Text = installname;
// this.Hide();
igm.Show();
return;
}
if (input.EndsWith(s) && isDownloading == true)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"c:/U.Rage/Sounds/notify.wav");
player.Play();
MessageBox.Show("Please wait until your download has been finished", "Warning");
storeBrowser.GoBack();
}
}
}
This happens when the download has been finished
void client_InstallFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if(Downloader.cancelDownload == false)
{
using (ZipFile zip = ZipFile.Read(#"C:\U.Rage\Downloads\" + installID + "Install.zip"))
{
//zip.Password = "iliketrains123";
zip.ExtractAll("C:/U.Rage/Games/", ExtractExistingFileAction.OverwriteSilently);
}
System.IO.File.Delete(#"C:/U.Rage/Downloads/" + installID + "Install.zip");
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(2, "Download Completed !", "Installing was succesful !", ToolTipIcon.Info);
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"c:/U.Rage/Sounds/notify.wav");
player.Play();
this.Show();
igm.Close();
isDownloading = false;
listView.Items.Clear();
var files = Directory.GetFiles(#"C:\U.Rage\Games\", "*.ugi").Select(f => new ListViewItem(f)).ToArray();
foreach (ListViewItem f in files)
{
this.LoadDataFromXml(f);
}
}
}
Here is the method for async data download that supports cancellation:
private static async Task<byte[]> downloadDataAsync(Uri uri, CancellationToken cancellationToken)
{
if (String.IsNullOrWhiteSpace(uri.ToString()))
throw new ArgumentNullException(nameof(uri), "Uri can not be null or empty.");
if (!Uri.IsWellFormedUriString(uri.ToString(), UriKind.Absolute))
return null;
byte[] dataArr = null;
try
{
using (var webClient = new WebClient())
using (var registration = cancellationToken.Register(() => webClient.CancelAsync()))
{
dataArr = await webClient.DownloadDataTaskAsync(uri);
}
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.RequestCanceled)
{
// ignore this exception
}
return dataArr;
}
When you call CancelAsync, the AsyncCompletedEventArgs object passed to the completed callback will have the Cancelled property set to true. So you could write:
void client_InstallFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if(e.Cancelled)
{
// delete the partially-downloaded file
return;
}
// unzip and do whatever...
using (ZipFile zip = ZipFile.Read(#"C:\U.Rage\Downloads\" + installID + "Install.zip"))
See the documentation for more info.
The selected answer didn't work properly for me. Here's what I did:
When they click the cancel button I call the
Client.CancelAsync();
And then in the Web.Client DownloadFileCompleted:
Client.DownloadFileCompleted += (s, e) =>
{
if (e.Cancelled)
{
//cleanup delete partial file
Client.Dispose();
return;
}
}
And then when you try to re-download just instantiate a new client:
Client = WebClient();
This way the old async parameters won't be maintained.

Download and launch default app in windows phone 8 in C#

I am using Live api to download SkyDrive files.
My code has a download click event which triggers the OnDownloadedCompleted function.
OnDownloadedCompleted function copies the file to "filename".
and calls the DefaultLaunch(), which takes in the "filename" and tries to launch it by the default program in windows phone 8.
When i execute this code (The file downloaded is a OneNote file) OneNote opens and says that the file can't be open.
Can anyone please help me validate this code?
Thanks a lot!
private void btnDownload_Click(object sender, RoutedEventArgs e)
{
if (App.Current.LiveSession == null)
{
infoTextBlock.Text = "You must sign in first.";
}
else
{
LiveConnectClient client = new LiveConnectClient(App.Current.LiveSession);
client.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(OnDownloadCompleted);
client.DownloadAsync("file_id");
}
}
The code for OnDownloadCompleted is
void OnDownloadCompleted(object sender, LiveDownloadCompletedEventArgs e)
{
if (e.Result != null)
{
var filestream = File.Create(#"filename");
e.Result.Seek(0, SeekOrigin.Begin);
e.Result.CopyTo(filestream);
filestream.Close();
DefaultLaunch();
e.Result.Close();
}
else
{
infoTextBlock.Text = "Error downloading image: " + e.Error.ToString();
}
}
The code for Default launch function is
async void DefaultLaunch()
{
try
{
string imageFile = #"File.one";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{}
else
{}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.ToString());
}
}
try this tutorial.. http://msdn.microsoft.com/en-us/live/ff519582.aspx.. it is given there how to use live sdk in windows 8 platform

Categories

Resources