C# Launcher based on WebClient - c#

I'm creating simple launcher for my other application and I need advise on logical part of the program. Launcher needs to check for connection, then check for file versions (from site), compare it with currently downloaded versions (if any) and if everything is alright, start the program, if not, update (download) files that differs from newest version. The files are:
program.exe, config.cfg and mapFolder. The program.exe and mapFolder must be updated, and config.cfg is only downloaded when there is no such file. Additionaly mapFolder is an folder which contains lots of random files (every new version can have totally different files in mapFolder).
For the file version I thought I would use simple DownloadString from my main site, which may contain something like program:6.0,map:2.3, so newest program ver is 6.0 and mapFolder is 2.3. Then I can use FileVersionInfo.GetVersionInfo to get the version of current program (if any) and include a file "version" into mapFolder to read current version.
The problem is I dont know how to download whole folder using WebClient and what's the best way to do what I want to do. I've tried to download the mapFolder as zip and then automatically unpack it, but the launcher need to be coded in .net 3.0.
Here is my current code, that's just a prototype to get familiar with whole situation, dont base on it.
`
WebClient wc = new WebClient();
string verifySite = "google.com/downloads/version";
string downloadSite = "google.com/downloads/program.exe";
Uri verifyUri, downloadUri = null;
string userVer, currVer = "";
string downloadPath = Directory.GetCurrentDirectory();
string clientName = "program.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(FileDownloaded);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileDownloadProgress);
chckAutorun.Checked = Properties.Settings.Default.autorun;
checkConnection();
if(!checkVersion())
downloadClient();
else
{
pbDownload.Value = 100;
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
}
private bool checkConnection()
{
verifyUri = new Uri("http://" + verifySite);
downloadUri = new Uri("http://" + downloadSite);
WebRequest req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
verifyUri = new Uri("https://" + verifySite);
downloadUri = new Uri("https://" + downloadUri);
req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
return false;
}
private void downloadClient()
{
try
{
wc.DownloadFileAsync(downloadUri, Path.Combine(downloadPath, clientName));
}
catch { }
}
private bool checkVersion()
{
lblProgress.Text = "checking for updates";
try
{
currVer = FileVersionInfo.GetVersionInfo(Path.Combine(downloadPath, clientName)).FileVersion;
}
catch {
currVer = "";
}
try
{
userVer = wc.DownloadString(verifyUri);
}
catch {
userVer = "";
}
return currVer == userVer && currVer != "";
}
private void FileDownloaded(object sender, AsyncCompletedEventArgs e)
{
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
private void FileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
long received = e.BytesReceived / 1000;
long toReceive = e.TotalBytesToReceive / 1000;
lblProgress.Text = string.Format("{0}KB {1}/ {2}KB", received, Repeat(" ", Math.Abs(-5 + Math.Min(5, received.ToString().Length))*2), toReceive);
pbDownload.Value = e.ProgressPercentage;
}
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
if(checkVersion())
{
lblProgress.Text = "Starting...";
Process.Start(Path.Combine(downloadPath, clientName));
this.Close();
}
else
{
downloadClient();
}
}
public static string Repeat(string instr, int n)
{
if (string.IsNullOrEmpty(instr))
return instr;
var result = new StringBuilder(instr.Length * n);
return result.Insert(0, instr, n).ToString();
}
private void chckAutorun_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.autorun = chckAutorun.Checked;
Properties.Settings.Default.Save();
}`

I've managed to achieve what I need by enabling autoindex on web server and download string of files in folder ending with .map .
string mapSite = wc.DownloadString(new Uri("http://" + mapsSite));
maps = Regex.Matches(mapSite, "<a href=\"(.*).map\">");
foreach (Match m in maps)
{
string mapName = m.Value.Remove(0, 9).Remove(m.Length - 11);
downloaded = false;
wc.DownloadFileAsync(new Uri("http://" + mapsSite + mapName), Path.Combine(downloadPath, #"mapFolder/" + mapName));
while (!downloaded) { }
}

Related

Listbox Item holds data

Server 1 Server2 Server Config Screen
I am trying to make a video game server manager and I have run into an issue. I want the user to be able to have as many servers as they would like. However I cannot figure out through google searching and just regular messing around how to store the information that the user selects to become associated with the Server they create in the list. Basically when you make Server1 it takes the info you selected from the boxes on the config screen and uses them on the server selection page. But, when you make Server2, the configuration overwrites Server1's configuration. I know my code isn't even setup to be able to do this but I would appreciate a push in the right direction as to which type of code I should use.
Tl:dr I want config options to be associated with ServerX in the server list and each server should have unique settings.
public partial class Form1 : Form
{
//Variables
string srvName;
string mapSelect;
string difSelect;
public Form1()
{
InitializeComponent();
this.srvList.SelectedIndexChanged += new System.EventHandler(this.srvList_SelectedIndexChanged);
}
private void srvList_SelectedIndexChanged(object sender, EventArgs e)
{
if(srvList.SelectedIndex == -1)
{
dltButton.Visible = false;
}
else
{
dltButton.Visible = true;
}
//Text being displayed to the left of the server listbox
mapLabel1.Text = mapSelect;
difLabel1.Text = difSelect;
}
private void crtButton_Click(object sender, EventArgs e)
{
//Add srvName to srvList
srvName = namBox1.Text;
srvList.Items.Add(srvName);
//Selections
mapSelect = mapBox1.Text;
difSelect = difBox1.Text;
//Write to config file
string[] lines = { mapSelect, difSelect };
System.IO.File.WriteAllLines(#"C:\Users\mlynch\Desktop\Test\Test.txt", lines);
//Clear newPanel form
namBox1.Text = String.Empty;
mapBox1.SelectedIndex = -1;
difBox1.SelectedIndex = -1;
//Return to srvList
newPanel.Visible = false;
}
}
You mentioned in a recent comment that you had tried saving to a .txt file but it overwrote it anytime you tried to make an additional one. If you wanted to continue with your .txt approach, you could simply set a global integer variable and append it to each file you save.
//Variables
string srvName;
string mapSelect;
string difSelect;
int serverNumber = 0;
...
serverNumber++;
string filepath = Path.Combine(#"C:\Users\mlynch\Desktop\Test\Test", serverNumber.ToString(), ".txt");
System.IO.File.WriteAllLines(filepath, lines);
I think below source code will give you some idea about the direction. Let us start with some initializations:
public Form1()
{
InitializeComponent();
this.srvList.SelectedIndexChanged += new System.EventHandler(this.srvList_SelectedIndexChanged);
mapBox1.Items.Add("Germany");
mapBox1.Items.Add("Russia");
difBox1.Items.Add("Easy");
difBox1.Items.Add("Difficult");
}
This is the event handler of the "Create Server" button. It takes server parameters from the screen and writes to a file named as the server.
private void crtButton_Click(object sender, EventArgs e)
{
//Add srvName to srvList
srvName = namBox1.Text;
srvList.Items.Add(srvName);
//Selections
mapSelect = mapBox1.Text;
difSelect = difBox1.Text;
//Write to config file
string path = #"C:\Test\" + srvName + ".txt";
StreamWriter sw = new StreamWriter(path);
sw.WriteLine(mapSelect);
sw.WriteLine(difSelect);
sw.Flush();
sw.Close();
//Clear newPanel form
namBox1.Text = String.Empty;
mapBox1.SelectedIndex = -1;
difBox1.SelectedIndex = -1;
//Return to srvList
//newPanel.Visible = false;
}
And finally list box event handler is below. Method reads the server parameters from file and displays on the screen.
private void srvList_SelectedIndexChanged(object sender, EventArgs e)
{
if (srvList.SelectedIndex == -1)
{
dltButton.Visible = false;
}
else
{
dltButton.Visible = true;
}
string path = #"C:\Test\" + srvList.SelectedItem + ".txt";
StreamReader sr = new StreamReader(path);
//Text being displayed to the left of the server listbox
mapLabel1.Text = sr.ReadLine(); // mapSelect;
difLabel1.Text = sr.ReadLine(); // difSelect;
}
Please feel free to ask any questions you have.
I ended up figuring out the issue. Basically I ended up deciding on a write to a txt file and then read from it to display the contents of the file in the server select menu. I also added a delete button so you can delete the servers that you created. it does not have full functionality yet but it is there. So here it what I ended up with and it works perfectly. Thank you all for trying to help.
public partial class Form1 : Form
{
//Variables
string srvName;
string mapSelect;
string mapFile;
string difSelect;
string difFile;
int maxPlayers;
string plrSelect;
string plrFile;
string finalFile;
string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string fileName = "config.txt";
public Form1()
{
InitializeComponent();
this.srvList.SelectedIndexChanged += new System.EventHandler(this.srvList_SelectedIndexChanged);
}
private void srvList_SelectedIndexChanged(object sender, EventArgs e)
{
//Read Server Selection
string srvSelect = srvList.GetItemText(srvList.SelectedItem);
string srvOut = System.IO.Path.Combine(basepath, srvSelect, fileName);
mapFile = File.ReadLines(srvOut).Skip(1).Take(1).First();
difFile = File.ReadLines(srvOut).Skip(2).Take(1).First();
plrFile = File.ReadLines(srvOut).Skip(3).Take(1).First();
//Display Server Selection
if (srvList.SelectedIndex == -1)
{
dltButton.Visible = false;
}
else
{
dltButton.Visible = true;
mapLabel1.Text = mapFile;
difLabel1.Text = difFile;
plrLabel1.Text = plrFile;
}
private void crtButton_Click(object sender, EventArgs e)
{
//Set Server Name
srvName = namBox1.Text;
string finalpath = System.IO.Path.Combine(basepath, srvName);
//Check if server name is taken
if (System.IO.Directory.Exists(finalpath))
{
MessageBox.Show("A Server by this name already exists");
}
else
{
//Add Server to the Server List
srvList.Items.Add(srvName);
//Server Configuration
mapSelect = mapBox1.Text;
difSelect = difBox1.Text;
maxPlayers = maxBar1.Value * 2;
plrSelect = "" + maxPlayers;
//Clear New Server Form
namBox1.Text = String.Empty;
mapBox1.SelectedIndex = -1;
difBox1.SelectedIndex = -1;
//Create the Server File
Directory.CreateDirectory(finalpath);
finalFile = System.IO.Path.Combine(finalpath, fileName);
File.Create(finalFile).Close();
//Write to config file
string[] lines = { srvName, mapSelect, difSelect, plrSelect };
System.IO.File.WriteAllLines(#finalFile, lines);
//Return to srvList
newPanel.Visible = false;
}
}
}

Wait for download to complete

I'm trying to create a simple program to download few files. I've tried some ready-made solutions I found on the web but I can't manage to make it work the way I want it to. I'm using this:
private void startDownload(string toDownload, string saveLocation)
{
Thread thread = new Thread(() =>
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(toDownload), saveLocation);
});
thread.Start();
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
labelPercentage.Text = "Downloading " + Convert.ToInt32(percentage) + "% - " + Convert.ToInt32(bytesIn / 1024) + " / " + Convert.ToInt32(totalBytes / 1024) + " kB";
progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
});
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
textBoxLog.AppendText("OK");
});
}
I'd like to make the program continue (download next file / show the "OK" message / do whatever is in the next line of code) AFTER the download has finished.
In the current form, if I'd put eg.
private void button1_Click(object sender, EventArgs e)
{
startDownload(url, localpath + #"\file.zip");
textBoxLog.AppendText("the cake is a lie");
}
it's showing me this text first and "OK" later.
I'm beginning with c#/.net and I've never learned object-oriented programming before so it's kind of double challenge for me and I can't figure it out by myself. I would be really grateful for relatively easy explanation.
You can have startDownload wait for the asynchronous file download through Application.DoEvents() like this:
private bool downloadComplete = false;
private void startDownload(Uri toDownload, string saveLocation)
{
string outputFile = Path.Combine(saveLocation, Path.GetFileName(toDownload.AbsolutePath));
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(toDownload, outputFile);
while (!downloadComplete)
{
Application.DoEvents();
}
downloadComplete = false;
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// No changes in this method...
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
textBoxLog.AppendText("OK");
downloadComplete = true;
});
}
And the download queue...
private void button1_Click(object sender, EventArgs e)
{
FireDownloadQueue(urls, localpath);
textBoxLog.AppendText("the cake is a lie");
}
private async void FireDownloadQueue(Uri[] toDownload, string saveLocation)
{
foreach (var url in urls)
{
await Task.Run(() => startDownload(url, localpath));
}
}
However, I think you're better off reading about HttpWebRequest and writing your own downloader class with proper checks and events...
Here's a pretty good example by Hemanshu Bhojak (Source) that you can expand upon:
public class Downloader
{
public async Task Download(string url, string saveAs)
{
var httpClient = new HttpClient();
var response = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
var parallelDownloadSuported = response.Headers.AcceptRanges.Contains("bytes");
var contentLength = response.Content.Headers.ContentLength ?? 0;
if (parallelDownloadSuported)
{
const double numberOfParts = 5.0;
var tasks = new List<Task>();
var partSize = (long)Math.Ceiling(contentLength / numberOfParts);
File.Create(saveAs).Dispose();
for (var i = 0; i < numberOfParts; i++)
{
var start = i*partSize + Math.Min(1, i);
var end = Math.Min((i + 1)*partSize, contentLength);
tasks.Add(
Task.Run(() => DownloadPart(url, saveAs, start, end))
);
}
await Task.WhenAll(tasks);
}
}
private async void DownloadPart(string url, string saveAs, long start, long end)
{
using (var httpClient = new HttpClient())
using (var fileStream = new FileStream(saveAs, FileMode.Open, FileAccess.Write, FileShare.Write))
{
var message = new HttpRequestMessage(HttpMethod.Get, url);
message.Headers.Add("Range", string.Format("bytes={0}-{1}", start, end));
fileStream.Position = start;
await httpClient.SendAsync(message).Result.Content.CopyToAsync(fileStream);
}
}
}
Example usage:
Task.Run(() => new Downloader().Download(downloadString, saveToString)).Wait();
With something along the lines of:
public class Downloader
{
public event EventHandler DownloadProgress;
DownloaderEventArgs downloaderEventArgs;
public void DownloadStarted(DownloaderEventArgs e)
{
EventHandler downloadProgress = DownloadProgress;
if (downloadProgress != null)
downloadProgress(this, e);
}
// ...
}
class DownloaderEventArgs : EventArgs
{
public string Filename { get; private set; }
public int Progress { get; private set; }
public DownloaderEventArgs(int progress, string filename)
{
Progress = progress;
Filename = filename;
}
public DownloaderEventArgs(int progress) : this(progress, String.Empty)
{
Progress = progress;
}
}
startDownload initiates the download on a new thread, so when you invoke startDownload it starts the thread and the rest of the code after that continues immediately because it is on a separate thread. That is why you are seeing "the cake is a lie" before the "OK".

c# windows phone -- text box doesn't understand foreign characters?

I'm building an app to access Google Translate for Windows Phone. I've noticed that for languages where the translated words will have foreign characters, the text box gets all screwed up and instead displays random symbols and such. Not sure why. Do I need to enable something on the text box?
Code:
private void btnTranslate_Click(object sender, RoutedEventArgs e)
{
string text = txtboxOriginal.Text;
string fromLanguage;
string toLanguage;
//Use Bing.
if ((bool)settings["translateIsBing"] == true)
{
if (string.IsNullOrWhiteSpace(text))
{
MessageBox.Show("Can't translate with nothing to translate. Please try again.");
}
else
{
}
}
//Use Google.
else if ((bool)settings["translateIsGoogle"] == true)
{
if (string.IsNullOrWhiteSpace(text))
{
MessageBox.Show("Can't translate with nothing to translate. Please try again.");
}
else
{
fromLanguage = this.getLanguageCodeGoogle(lstOriginalLanguages.SelectedIndex.ToString());
toLanguage = this.getLanguageCodeGoogle(lstTranslateToLanguages.SelectedIndex.ToString());
string url = "http://translate.google.com/translate_t?text=" + text + "&sl=" + fromLanguage + "&tl=" + toLanguage;
WebClient webclient = new WebClient();
webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webclient_DownloadStringCompleted);
webclient.DownloadStringAsync(new Uri(url, UriKind.RelativeOrAbsolute));
}
}
}
void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
Debug.WriteLine(e.Result);
string result = e.Result;
int startPosition = result.IndexOf("TRANSLATED_TEXT='");
int length = result.IndexOf(#"';INPUT") - startPosition;
string partial = result.Substring(startPosition, length);
Debug.WriteLine("Step 1: {0}", partial);
startPosition = partial.IndexOf("'") + 1;
length = partial.Length - startPosition;
string secondPartial = partial.Substring(startPosition, length);
Debug.WriteLine("Step 2: {0}", secondPartial);
translatedText = secondPartial;
txtboxOriginal.Text = secondPartial;
btnTranslate.Content = "Translated";
btnTranslate.IsEnabled = false;
btnCopy.Visibility = Visibility.Visible;
btnCopy.IsEnabled = true;
btnReset.Visibility = Visibility.Visible;
btnReset.IsEnabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The issues is could by the encoding type of the response from Google.
When you look at the Content-type of the response it isn't UTF8 always which what WebClient.DownloadStringAsync decodes it to so you have to change the decoding type
You will have to change the Webclient.Encoding to match the request type
The solution to the problem can be found here

Facebook logout Windows Phone Application without opening WebBrowser

I am trying to develop a Windows Phone 7 application using Facebook login and logout operations. I found Facebook SDK and used it in order to carry out login, by opening WebBrowser. The user enters credentials to this browser and logs in successfully. Moreover, I managed to login the user without using any SDK, just using http requests, like the SDK actually does. However, I want to logout users without using any WebBrowser, but just clicking a button for example. There are so many solutions in the web suggesting that I should open web browser and navigate it to a certain URL in order to logout. However, this is not what I want. I think there should be a way to logout by clearing cookies, which I dont exactly know how to do, or any other that you suggest. Some part of my code below:
private static String appID = "";
private static String appSecret = "";
public static void login(String[] permissions)
{
try
{
permissionArray = permissions;
popup = new Popup();
popup.Height = 480;
popup.Width = 480;
popup.VerticalOffset = 100;
FacebookLoginUserControl control = new FacebookLoginUserControl();
control.facebookWebBrowser.Loaded += new RoutedEventHandler(webBrowser_Loaded);
control.facebookWebBrowser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(webBrowser_Navigated);
popup.Child = control;
popup.IsOpen = true;
}
catch (Exception e)
{
//handle
}
}
private static void webBrowser_Loaded(Object sender, RoutedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
String loginUrl = GetFacebookLoginUrl();
wb.Navigate(new Uri(loginUrl));
}
private static String GetFacebookLoginUrl()
{
String permissionString = String.Empty;
if (permissionArray.Length > 0)
permissionString = String.Join(",", permissionArray);
var uriParams = new Dictionary<string, string>() {
{"client_id", appID},
{"response_type", "token"},
{"scope", permissionString},
{"redirect_uri", "http://www.facebook.com/connect/login_success.html"},
{"display", "touch"}
};
StringBuilder urlBuilder = new StringBuilder();
foreach (var current in uriParams)
{
if (urlBuilder.Length > 0)
{
urlBuilder.Append("&");
}
var encoded = HttpUtility.UrlEncode(current.Value);
urlBuilder.AppendFormat("{0}={1}", current.Key, encoded);
}
var loginUrl = "http://www.facebook.com/dialog/oauth?" + urlBuilder.ToString();
return loginUrl;
}
private static void webBrowser_Navigated(Object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (string.IsNullOrEmpty(e.Uri.Fragment)) return;
if (e.Uri.AbsoluteUri.Replace(e.Uri.Fragment, "") == "http://www.facebook.com/connect/login_success.html")
{
string text = HttpUtility.HtmlDecode(e.Uri.Fragment).TrimStart('#');
var pairs = text.Split('&');
foreach (var pair in pairs)
{
var kvp = pair.Split('=');
if (kvp.Length == 2)
{
if (kvp[0] == "access_token")
{
accessToken = kvp[1];
MessageBox.Show("Access granted");
RequestUserProfile();
}
}
}
if (string.IsNullOrEmpty(accessToken))
{
MessageBox.Show("Unable to authenticate");
}
popup.IsOpen = false;
}
}
private static void RequestUserProfile()
{
var profileUrl = string.Format("https://graph.facebook.com/me?access_token={0}", HttpUtility.UrlEncode(accessToken));
request = (HttpWebRequest)HttpWebRequest.Create(new Uri(profileUrl));
request.Method = "GET";
request.BeginGetResponse(result =>
{
try
{
var resp = (result.AsyncState as HttpWebRequest).EndGetResponse(result);
using (var strm = resp.GetResponseStream())
{
StreamReader sr = new StreamReader(strm);
var responseString = sr.ReadToEnd();
}
}
catch (Exception ex)
{
//
}
}, request);
}
Any Ideas to solve the problem.
Thanks in advance
What's actually so spooky in using webBrowser? If you programmatically create a WebBrowser object, it won't be visible, unless you'd add it somewhere on form/page. If you want to clear cookies for Facebook, the solution will be something like that:
// Can be invoked from your button_click event
public void TryLogout()
{
webBrowser = new WebBrowser();
Uri uri = new Uri("http://m.facebook.com/home.php?r", UriKind.Absolute);
webBrowser.LoadCompleted += new LoadCompletedEventHandler(webBrowser_TryLogoutLoadCompleted);
webBrowser.Navigate(uri);
}
And then:
private void webBrowser_TryLogoutLoadCompleted(object sender, EventArgs e)
{
try
{
var cookies = webBrowser.GetCookies();
foreach (Cookie cookie in cookies)
{
if (cookie.Domain.Contains("m.facebook.com"))
{
cookie.Discard = true;
cookie.Expired = true;
}
}
// we've just cleaned up cookies
}
finally
{
webBrowser.LoadCompleted -= webBrowser_TryLogoutLoadCompleted;
}
}
Hope this helps.
GetCookies method

ProgressBar problems while program downloading file

I have a problem with a simple updater program. It should to download archive and extract it. Well, this works fine. But i cannot overcome progressbar.
It shows at setProgressBar(progressBar1.Maximum/20) fine.
But all other changes of it's value doesn't shows at all. I can't define reason for this behavior. Could anyone help me?
UPD: It seems that e.ProgressPercentage returns always 0, and only once 100, right before download is complete.
Here is my code:
static EventWaitHandle _waitHandle = new AutoResetEvent(false);
void UpdaterForm_Shown(object sender, System.EventArgs e)
{
setProgressBar(progressBar1.Maximum/20);
UpdateProgram(address, login, password);
setProgressBar(progressBar1.Maximum);
ExecuteProgram(Path + "../" + programName + ".exe");
Application.Exit();
}
private void UpdateProgram(string pathToUpdateArchive, string login, string pass)
{
string downloadedArchive = null;
Thread downloadAsync = new Thread(() => DownloadFileFromFtp(pathToUpdateArchive, login, pass, out downloadedArchive));
downloadAsync.Name = "downloadAsync";
downloadAsync.Start();
_waitHandle.WaitOne();
ExtractFile(downloadedArchive, Path + "/../");
}
private void DownloadFileFromFtp(string address, string login, string password, out string archivePath)
{
fileName = address.Substring(address.LastIndexOf('/') + 1);
try
{
WebClient wc = new WebClient();
wc.Credentials = new NetworkCredential(login, password);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
archivePath =Path + fileName;
wc.DownloadFileAsync(new Uri(address), archivePath);
}
catch
{
}
}
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
setProgressBar(e.ProgressPercentage*7/10 + 10);
}
void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
_waitHandle.Set();
}
private void setProgressBar(int value)
{
if (progressBar1.InvokeRequired)
this.BeginInvoke((MethodInvoker)delegate { progressBar1.Value = value; });
else
progressBar1.Value = value;
}

Categories