2009-07-13 28 views
1

私はwinformのコードをここに見つけました:http://www.wincustomize.com/articles.aspx?aid=136426&c=1WebアプリケーションでSystem.Windows.Forms.WebBrowserを使用するには?

そしてwinformとしてうまくいきます。しかし、私はWebアプリケーションでコードを実行したい。

  1. 私はC言語でのSystem.Windows.Formsの参照とMicrosoft.mshtml.dllを追加します:\プログラムファイル\ Microsoft.NET \プライマリ相互運用機能アセンブリ\私のWebアプリに。

  2. WebアプリケーションにWebPageBitmap.csをコピーします。

  3. Program.csのMain()をButton_Click()としてWebアプリケーションにコピーします。

  4. ウェブアプリケーションのボタンをクリックすると、これは、エラーが発生します。現在のスレッドがシングルスレッドアパートメントにないため

のActiveXコントロールの8856f961-340a-11D0-A96B-00c04fd705a2 'をインスタンス化することはできません。

WebアプリケーションでSystem.Windows.Forms.WebBrowserを使用してWebサイトのサムネイルを取得するにはどうすればよいですか?

public partial class Capture01 : System.Web.UI.Page 
{ 
    public delegate void WebBrowserDocumentCompletedEventHandler(object sender, WebBrowserDocumentCompletedEventArgs e); 

    [STAThread] 
    protected void Button1_Click(object sender, EventArgs e) 
    {   
     int width = 1024; 
     int height = 900; 

     int thumbwidth = width; 
     int thumbheight = height;   

     string fileName = "image01.jpg"; 
     string url = "http://www.iweixtest.cn/WE/Site/1647/index.aspx";   
     thumbwidth = 150; 
     thumbheight = 100; 

     //WebPageBitmap webBitmap = new WebPageBitmap(args[0], width, height, false, 10000); 
     WebPageBitmap webBitmap = new WebPageBitmap(url, width, height, false, 10000); 
     if (webBitmap.IsOk) 
     { 
      webBitmap.Fetch(); 
      Bitmap thumbnail = webBitmap.GetBitmap(thumbwidth, thumbheight); 
      //thumbnail.Save(args[1], ImageFormat.Jpeg); 
      thumbnail.Save(fileName, ImageFormat.Jpeg); 
      thumbnail.Dispose(); 
     } 
     else 
     { 
      MessageBox.Show(webBitmap.ErrorMessage); 
     }  
    } 
} 

WebPageBitmap.cs

namespace GetSiteThumbnail 
{ 
    /// <summary> 
    /// Thanks for the solution to the "sometimes not painting sites to Piers Lawson 
    /// Who performed some extensive research regarding the origianl implementation. 
    /// You can find his codeproject profile here: 
    /// http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=39324 
    /// </summary> 
    [InterfaceType(1)] 
    [Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")] 
    public interface IHTMLElementRender2 
    { 
     void DrawToDC(IntPtr hdc); 
     void SetDocumentPrinter(string bstrPrinterName, ref _RemotableHandle hdc); 
    } 

    /// <summary> 
    /// Code by Adam Najmanowicz 
    /// http://www.codeproject.com/script/Membership/Profiles.aspx?mid=923432 
    /// http://blog.najmanowicz.com/ 
    /// Some improvements suggested by Frank Herget 
    /// http://www.artviper.net/ 
    /// </summary> 
    class WebPageBitmap 
    { 
     private WebBrowser webBrowser; 
     private string url; 
     private int width; 
     private int height; 
     private bool isOk; 
     private string errorMessage; 

     public string ErrorMessage 
     { 
      get { return errorMessage; } 
     } 

     public bool IsOk 
     { 
      get { return isOk; } 
      set { isOk = value; } 
     } 

     public WebPageBitmap(string url, int width, int height, bool scrollBarsEnabled, int wait) 
     { 
      this.width = width; 
      this.height = height; 

      this.url = 
       url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) ? 
       url : this.url = "http://" + url; 

      try 
      // needed as the script throws an exeception if the host is not found 
      { 
       HttpWebRequest req = (HttpWebRequest)WebRequest.Create(this.url); 
       req.AllowAutoRedirect = true; 
       //req.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"; //成功 
       req.UserAgent = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 
       //req.Referer = "http://www.cognifide.com"; 
       req.ContentType = "text/html"; 
       req.Accept = "*/*"; 
       req.KeepAlive = false; 

       using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) 
       { 
        string x = resp.StatusDescription; 
       }  
      } 
      catch (Exception ex) 
      { 
       errorMessage = ex.Message; 
       isOk = false; 
       return; 
      } 
      isOk = true;              // public, to check in program.cs if the domain is found, so the image can be saved 

      webBrowser = new WebBrowser(); 
      webBrowser.DocumentCompleted += 
      new WebBrowserDocumentCompletedEventHandler(documentCompletedEventHandler); 
      webBrowser.Size = new Size(width, height); 
      webBrowser.ScrollBarsEnabled = false; 
     } 

     /// <summary> 
     /// Fetches the image 
     /// </summary> 
     /// <returns>true is the operation ended with a success</returns> 
     public bool Fetch() 
     { 
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); 
      req.AllowAutoRedirect = true; 
      //req.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"; 
      req.UserAgent = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 
      //req.Referer = "http://www.cognifide.com"; 
      req.ContentType = "text/html"; 
      req.AllowWriteStreamBuffering = true; 
      req.AutomaticDecompression = DecompressionMethods.GZip; 
      req.Method = "GET"; 
      req.Proxy = null; 
      req.ReadWriteTimeout = 20; 

      HttpStatusCode status; 
      using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) 
      { 
       status = resp.StatusCode; 
      } 

      if (status == HttpStatusCode.OK || status == HttpStatusCode.Moved) 
      { 
       webBrowser.Navigate(url); 
       while (webBrowser.ReadyState != WebBrowserReadyState.Complete) 
       { 
        Application.DoEvents(); 

       } 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 

     private void documentCompletedEventHandler(object sender, WebBrowserDocumentCompletedEventArgs e) 
     { 
      ((WebBrowser)sender).Document.Window.Error += 
       new HtmlElementErrorEventHandler(SuppressScriptErrorsHandler); 
     } 

     public void SuppressScriptErrorsHandler(object sender, HtmlElementErrorEventArgs e) 
     { 
      e.Handled = true; 
      MessageBox.Show("Error!"); 
     } 

     internal Bitmap GetBitmap(int thumbwidth, int thumbheight) 
     { 
      IHTMLDocument2 rawDoc = (IHTMLDocument2)webBrowser.Document.DomDocument; 
      IHTMLElement rawBody = rawDoc.body; 
      IHTMLElementRender2 render = (IHTMLElementRender2)rawBody; 

      Bitmap bitmap = new Bitmap(width, height); 
      Rectangle bitmapRect = new Rectangle(0, 0, width, height); 

      // Interesting thing that despite using the renderer later 
      // this following line is still necessary or 
      // the background may not be painted on some websites. 
      webBrowser.DrawToBitmap(bitmap, bitmapRect); 

      using (Graphics graphics = Graphics.FromImage(bitmap)) 
      { 
       IntPtr graphicshdc = graphics.GetHdc(); 
       render.DrawToDC(graphicshdc); 

       graphics.ReleaseHdc(graphicshdc); 
       graphics.Dispose(); 

       if (thumbheight == height && thumbwidth == width) 
       { 
        return bitmap; 
       } 
       else 
       { 
        Bitmap thumbnail = new Bitmap(thumbwidth, thumbheight); 
        using (Graphics gfx = Graphics.FromImage(thumbnail)) 
        { 
         // high quality image sizing 
         gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;        
         gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;                  // make it look pretty 
         gfx.DrawImage(bitmap, new Rectangle(0, 0, thumbwidth, thumbheight), bitmapRect, GraphicsUnit.Pixel); 
        } 
        bitmap.Dispose(); 
        return thumbnail; 
       } 
      } 
     } 
    } 
} 

答えて

3

WebアプリケーションでSystem.Windows.Forms.WebBrowserの使用に成功しました。

ちょうど上記の手順に従い、WebフォームページにASPCOMPAT =「true」を追加します。

がすべての答えをいただき、ありがとうございます。

0

短い答えは、System.Windowsで何もWebアプリケーションで使用されることが意図されていないことです。

System.Windows.Formsはクライアントコントロールです。ただし、Webアプリケーションはサーバー側で実行され、System.Web.UIには独自のUI要素があります。

mshtmlが別の障害ブロックである可能性があります。正直なところ、IISからアクセスできるかどうかは言えませんでした。

それを行う別の方法があるかもしれませんが、私はそれ以上のことを知っている人に私がその部分に答えさせるようにします。

3

独自のワーカースレッドを作成し、SetApartmentStateを呼び出してSTAスレッドに変更できます。このスレッドはWebページをレンダリングする作業を行うことができます。しかし、多くのスレッド間通信が必要とされ、R. Bemroseが述べたように、System.Windowsクラスは実際にWebアプリケーション内で使用するようには設計されていません。

もう1つのアプローチは、(1)ダウンロードするURLと(2)スクリーンショットイメージの出力場所の2つのパラメータを取るようにサンプルアプリケーションを.EXEとして書き直すことです。あなたのWebアプリケーションは一時パス(出力ファイル用)を作成し、このプログラム(Process.Start)を起動し、完了するのを待って、作成した出力ファイルをロードしてから、クライアントに送信されたもはや必要なくなった。 (何か問題が発生した場合は、メッセージボックスを表示するのとは異なるエラー処理が必要です。)

関連する問題