2013-03-14 9 views
6

Ich habe ein WebBrowser-Steuerelement in einem Formular, aber größtenteils bleibt es vor dem Benutzer verborgen. Es ist da, um eine Reihe von Login- und anderen Aufgaben zu bewältigen. I müssen dieses Steuerelement verwenden, da es eine Tonne Javascript gibt, die die Anmeldung behandelt. (d. h., ich kann nicht einfach zu einem WebClient-Objekt wechseln.)Laden Sie eine Datei über das WebBrowser-Steuerelement herunter

Nachdem wir ein bisschen herumgesprungen sind, möchten wir am Ende eine PDF-Datei herunterladen. Aber anstatt zu downloaden, wird die Datei innerhalb des WebBrowser-Steuerelements angezeigt, das der Benutzer nicht sehen kann.

Wie kann ich das PDF herunterladen, anstatt es in das Browser-Steuerelement zu laden?

+1

Eine späte Antwort für zukünftige Referenzen. [URLDownloadToFile] (http://msdn.microsoft.com/en-us/library/ms775123 (v = vs.85) .aspx) API [kann dafür verwendet werden] (http://stackoverflow.com/a/ 19043430/1768303). – Noseratio

Antwort

11

ein Savefiledialog-Steuerelement in das Formular hinzufügen, dann den folgenden Code auf Ihrem Web-Browser des Navigation Ereignis hinzufügen:

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    MessageBox.Show("File downloaded"); 
} 

Quelle

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) 
{ 
    if (e.Url.Segments[e.Url.Segments.Length - 1].EndsWith(".pdf")) 
    { 
     e.Cancel = true; 
     string filepath = null; 

     saveFileDialog1.FileName = e.Url.Segments[e.Url.Segments.Length - 1]; 
     if (saveFileDialog1.ShowDialog() == DialogResult.OK) 
     { 
      filepath = saveFileDialog1.FileName; 
      WebClient client = new WebClient(); 
      client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
      client.DownloadFileAsync(e.Url, filepath); 
     } 
    } 
} 

// Callback-Funktion: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/d338a2c8-96df-4cb0-b8be-c5fbdd7c9202

+2

Dies ist eine großartige Lösung. Es endete nicht genau, was ich brauchte, aber das ist wirklich nett. Danke Hanlet. – Jerry

5

Die Lösung Ich landete mit:

Ich habe alles gemacht e lse wie benötigt, um die URL zu bekommen, wohin es gehen musste. Da ich wusste, dass alle Login-Informationen, erforderlichen Einstellungen, Viewstates usw. in den Cookies gespeichert waren, konnte ich schließlich die Datei mit einem Hybrid des Web-Controls abrufen, um dann das WebClient-Objekt zu navigieren und die Datei-Bytes zu erfassen.

public byte[] GetPDF(string keyValue) 
    { 
     DoLogin(); 

     // Ask the source to generate the PDF. The PDF doesn't 
     // exist on the server until you have visited this page 
     // at least ONCE. The PDF exists for five minutes after 
     // the visit, so you have to snag it pretty quick. 
     LoadUrl(string.Format(
      "https://www.theMagicSource.com/getimage.do?&key={0}&imageoutputformat=PDF", 
      keyValue)); 

     // Now that we're logged in (not shown here), and 
     // (hopefully) at the right location, snag the cookies. 
     // We can use them to download the PDF directly. 
     string cookies = GetCookies(); 

     byte[] fileBytes = null; 
     try 
     { 
      // We are fully logged in, and by now, the PDF should 
      // be generated. GO GET IT! 
      WebClient wc = new WebClient(); 
      wc.Headers.Add("Cookie: " + cookies); 

      string tmpFile = Path.GetTempFileName(); 

      wc.DownloadFile(string.Format(
       "https://www.theMagicSource.com/document?id={0}_final.PDF", 
       keyValue), tmpFile); 

      fileBytes = File.ReadAllBytes(tmpFile); 
      File.Delete(tmpFile); 
     } 
     catch (Exception ex) 
     { 
      // If we can't get the PDF here, then just ignore the error and return null. 
      throw new WebScrapePDFException(
       "Could not find the specified file.", ex); 
     } 

     return fileBytes; 
    } 

    private void LoadUrl(string url) 
    { 
     InternalBrowser.Navigate(url); 

     // Let the browser control do what it needs to do to start 
     // processing the page. 
     Thread.Sleep(100); 

     // If EITHER we can't continue OR 
     // the web browser has not been idle for 10 consecutive seconds yet, 
     // then wait some more. 
     // ... 
     // ... Some stuff here to make sure the page is fully loaded and ready. 
     // ... Removed to reduce complexity, but you get the idea. 
     // ... 
    } 

    private string GetCookies() 
    { 
     if (InternalBrowser.InvokeRequired) 
     { 
      return (string)InternalBrowser.Invoke(new Func<string>(() => GetCookies())); 
     } 
     else 
     { 
      return InternalBrowser.Document.Cookie; 
     } 
    } 
1
bool documentCompleted = false; 
    string getInnerText(string url) 
    { 
     documentCompleted = false; 
     web.Navigate(url); 

     while (!documentCompleted)   
      Application.DoEvents(); 


     return web.Document.Body.InnerText; 
    } 
    private void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     documentCompleted = true; 
    } 
Verwandte Themen