WebBrowser Madness

Editar: La pregunta original era larga con muchas conjeturas salvajes. Lo he recortado a los misterios restantes ...

He estado luchando y desconcertando todo el día y creo que debería presentar mi problema a la comunidad.

Se originó en la publicación llamadaEl método de captura de pantalla genera imágenes en negro.. El póster original quiere tomar continuamente capturas de pantalla de su programa, que incluye un navegador web, cada n segundosincluso cuando el usuario está desconectado.

Cuando el usuario cierra sesión, ya no tiene pantalla. Por lo tanto, cualquier intento de leer la pantalla fallará. Si se utiliza un identificador de ventana, el resultado es un cuadro negro, cuando se utiliza CopyFromScreen, una excepción de error GDI.

Pero la ventana del programa sigue ahí y usaDrawToBitmap funciona bien incluso cuando el usuario está desconectado.

Aquí están las condiciones y los problemas restantes:

El usuario no debe tocar / hacer clic en elWebBrowser de cualquier manera. Si lo hace, por ejemplo, desplazándose, haciendo clic, navegando por el subsectorDrawToBitmap las llamadas dan como resultado un cuadro vacío.

Mientras que laWebBrowser permanece intacto, es suficiente para hacer unRefresh antes de la próxima llamada DrawToBitmap.

Después de tocarlo, es necesario cargar la URL nuevamente haciendo unwebBrowser1.Url = new Uri(URLpath);

Al navegar, la nueva URL debe almacenarse para hacer esto. Lo hago en el evento Navegado.

No importa qué,DrawToBitmap falla (con el cuadro vacío) si la página web contiene un<input type="text" ..> field.

Al destrozar elDocumentText con unReplace("<input", "<in_put"); esto podría curarse, pero sin más trucos, perderá las hojas CSS.

Para probarlo tira dosButtons, a Label, a Timer, a Combobox and a WebBrowser on a Form y copie el código; cambie la ruta del archivo a una carpeta que se ajuste a su configuración y mire ..:

public Form1()
{
    InitializeComponent();
    this.button1.Click += new System.EventHandler(this.button1_Click);
    this.button2.Click += new System.EventHandler(this.button2_Click);
    this.button1.Text = "Start";
    this.button2.Text = "Stop";
    this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
    this.comboBox1.Items.AddRange(new object[] {
        "https://stackoverflow.com/questions",
        "http://webcam.zirndorf.de/marktplatz/gross.jpg"});
    scapeRect = this.ClientRectangle;
    webBrowser1.Url = new Uri("https://stackoverflow.com/questions");
    this.comboBox1.SelectedIndexChanged += 
                   new System.EventHandler(this.comboBox1_SelectedIndexChanged);

}

Rectangle scapeRect = Rectangle.Empty;
int imgIndex = 0;
int urlIndex = 0;

private void button1_Click(object sender, EventArgs e)
{
    timer1.Interval = 10 * 1000;  // every 10 seconds
    timer1.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    timer1.Stop();
}


private void timer1_Tick(object sender, EventArgs e)
{
    imgIndex ++;
    label1.Text = imgIndex .ToString();
    webBrowser1.Url = new Uri(comboBox1.Text); // this works almost always
    //webBrowser1.Refresh();                   // this works only if the WB is 'untouched'   
    string filename = "d:\\scrape\\AB_sos_Screen" + imgIndex .ToString("000") + ".png";
    Bitmap bmp = new Bitmap(scapeRect.Width, scapeRect.Height);
    this.DrawToBitmap(bmp, scapeRect);
    bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
    bmp.Dispose();
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    if (comboBox1.Text != "") webBrowser1.Url = new Uri(comboBox1.Text);
}




private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (!comboBox1.Items.Contains(e.Url.ToString()))
        urlIndex = comboBox1.Items.Add(e.Url.ToString());
    else
        urlIndex = comboBox1.Items.IndexOf(e.Url.ToString());
    if (urlIndex >= 0) comboBox1.SelectedIndex = urlIndex;
    button1.Focus();
}

Ahora puedo navegar casi libremente y el raspado de la pantalla sigue funcionando, excepto en las páginas con campos de entrada de texto como p. Ej. elLos usuarios o laEtiquetas páginas

Me pregunto si anybdoy puede reproducir ...

O explicar ??

¿O simplemente he estado 'cazando fantasmas' después de todo y la cosa simplemente no es confiable?

Edición final:

Si bien hubiera sido bueno obtener una explicación, obtener una solución que funcione probablemente tenga que ser lo suficientemente bueno. El OP ha encontrado un código que utiliza unPrintWindow llamar auser32.dll y resuelve todos los problemas. Funciona mientras está desconectado, funciona conRefreshing incluso después de hacer clic en elWebBrowser y raspa todas las páginas, incluidas las que tienen campos de entrada de texto. Aquí está mi versión de ella:

using System.Runtime.InteropServices;
//...
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);

public Bitmap CaptureControl(Control ctl)
{
    //Bitmap bmp = new Bitmap(ctl.Width, ctl.Height);  // includes borders
    Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height);  // content only
    using (Graphics graphics = Graphics.FromImage(bmp))
    {
        IntPtr hDC = graphics.GetHdc();
        try      { PrintWindow(ctl.Handle, hDC, (uint)0);   }
        finally  { graphics.ReleaseHdc(hDC);                }
    }
    return bmp;
}

Esto puede capturar un formulario o un control con o sin bordes.

Respuestas a la pregunta(1)

Su respuesta a la pregunta