/// <summary> /// Downloads the contents at the URL and save them to a temporary file. /// </summary> /// <param name="url">The URL that specifies what to download.</param> /// <returns>The file name it was saved to.</returns> public string DownloadZipFile(DownloadInfo downloadInfo, BackgroundWorker workerThread) { CookieContainer cookieContainer = null; HttpWebRequest webRequest = null; HttpWebResponse webResponse = null; Stream responseStream = null; FileStream fileStream = null; string fileName = ""; // we can't get the size of the download because it's not included in the response header // so we will estimate that it's 500k long estimatedSize = 500000; try { // create the cookie container cookieContainer = new CookieContainer(); cookieContainer.Add(new Uri("http://www.codeproject.com/"), downloadInfo.Cookies); // Create the web request webRequest = (HttpWebRequest)HttpWebRequest.Create(downloadInfo.ProjectUrl); // Set default authentication for retrieving the file webRequest.Credentials = CredentialCache.DefaultCredentials; // identifies itself webRequest.UserAgent = "CPBrowser"; // apply the session cookies webRequest.CookieContainer = cookieContainer; // Get the response webResponse = (HttpWebResponse)webRequest.GetResponse(); // Get the response stream responseStream = webResponse.GetResponseStream(); // get the name from the url fileName = ExtractNameFromUrl(downloadInfo.ProjectUrl.ToString()) + ".zip"; fileName = Path.Combine(Path.GetTempPath(), fileName); // write it to a temporary file in 1000 byte chunks fileStream = new FileStream(fileName, FileMode.Create); int bytesRead = 0; int totalBytesRead = 0; int progress = 15; byte[] data = new byte[1000]; // keep looping until we read nothing do { // read the next 1000 bytes of data bytesRead = responseStream.Read(data, 0, 1000); // write the data to the file fileStream.Write(data, 0, bytesRead); // report the progress totalBytesRead += bytesRead; // because this is an estimation, if the downloaded amount goes over the // estimated amount, just loop back to 0 if (totalBytesRead >= estimatedSize) totalBytesRead = 0; progress = (int)(((float)totalBytesRead / (float)estimatedSize) * 99.0f); workerThread.ReportProgress(progress); } while (bytesRead > 0); // report that we're done workerThread.ReportProgress(100); } catch (Exception ex) { string errMsg = "Error downloading file: "; // check if the user is logged in bool isLoggedIn = IsUserLoggedIn(downloadInfo.Cookies); if (isLoggedIn == false) errMsg += "Make sure you are logged in to the web site."; else errMsg += ex.Message; throw new Exception(errMsg); } finally { // free any resources if (fileStream != null) { fileStream.Close(); fileStream.Dispose(); } if (responseStream != null) { responseStream.Close(); responseStream.Dispose(); } if (webResponse != null) webResponse.Close(); } // return the file name return fileName; }
/// <summary> /// This is the event handler which is called when the web browser control /// begins navigating to an URL. We want to intercept this navigation when the /// URL ends in .zip, which indicates that a sample project may be being /// downloaded. If the URL ends with a .zip extension, ask if the user wants to /// open the sample directly in Visual Studio. If so, then cancel IE's handling /// of this message, otherwise do nothing. /// </summary> private void WebBrowserCtl_Navigating(object sender, WebBrowserNavigatingEventArgs e) { try { string originalUrl = e.Url.ToString(); // check the extension of the link string extension = Path.GetExtension(originalUrl); if (String.Compare(extension, ".zip", true) == 0) { // if our worker thread os busy, just pass if (m_downloadWorkerThread.IsBusy == true) { e.Cancel = true; return; } // ask the user if they want to open the project directly DialogResult dr = MessageBox.Show("Would you like to open this with the Code Project Browser?", "Code Project Browser", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (dr == DialogResult.Yes) { try { ShowBusy(); // set the status bar m_dte.StatusBar.Text = "Downloading Code Project file..."; // create the download info string cookieString = ""; if (WebBrowserCtl.Document != null) cookieString = WebBrowserCtl.Document.Cookie; DownloadInfo downloadInfo = new DownloadInfo(e.Url, WebBrowserCtl.Url, WebBrowserCtl.Document); // download the zip file asynchronously m_downloadWorkerThread.RunWorkerAsync(downloadInfo); } catch (Exception ex) { ShowNotBusy(); string errMsg = "Error: " + ex.Message; MessageBox.Show(errMsg, "Code Project Browser", MessageBoxButtons.OK, MessageBoxIcon.Error); } // tell IE not to go any further with this request e.Cancel = true; } else if (dr == DialogResult.Cancel) { // tell IE not to go any further with this request e.Cancel = true; } } else if (IsArticleURL(e.Url) == true) { ShowBusy(); // add the url to the combo box ComboURL.Text = originalUrl; m_navigating = true; } } catch (Exception ex) { ShowNotBusy(); // show the error message MessageBox.Show("Unable to navigate: " + ex.Message, "Code Project Browser", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }