Frage

Ich brauche das WinForms-WebBrowser-Steuerelement in einer ASP.NET-Anwendung verwenden, um Screenshots von Webseiten zu übernehmen.

Ich würde viel lieber laufen sie in einer Konsolenanwendung, und an die App über die ASP.NET-Anwendung kommunizieren, aber es ist nicht mein Anruf, ich habe gesagt, es als Teil des Internetangebotes laufen hat.

Es alle ziemlich Werke abgesehen von jedem Gespräch beginnt mit einer neuen Sitzung frisch zu navigieren, es ist wie die Cookies nicht beibehalten werden. Als Experiment änderte ich meinen IIS-Anwendungspool als ich zu laufen, anstatt NETWORK_SERVICE, und alles funktioniert einwandfrei. So ist es etwas seltsam es als Netzwerkdienst ausgeführt wird.

Ich vermute, dass das Netzwerk-Dienstkonto nicht die Berechtigungen verfügt Spur des ASP.NET_SessionId Cookie zu halten und die Auth-Cookie, aber diese beiden sind nicht-persistente Cookies, damit ich weiß nicht, warum das wäre sein.

Hier ist etwas vereinfachte Code, so dass Sie den Kern von dem, was bekommen kann ich tue. Es gibt eine Reihe von Protokoll- und Speichern von Bildern, die ich ausgeschnitten, so dass es nicht vollständiger Code. Im Grunde ein Entwickler / Tester / admin kann diesen Code ausführen einmal (Task trat über die Homepage aus), wird es Bitmaps jeder Seite im System erzeugen, sie eine neue Version der Website freigeben können und es dann wieder laufen, es wird Ihnen sagen, die Unterschiede (neue Seiten, Seiten entfernt, Seiten geändert).

public void Run()
{
    var t = new Thread(RunThread);
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

private void RunThread()
{
    try
    {
        using (var browser = new WebBrowser())
        {
            browser.DocumentCompleted += BrowserDocumentCompleted;

            if (!VisitPage(browser, "special page that sets some session flags for testing - makes content predictable")))
                throw new TestRunException("Unable to disable randomness");

            foreach (var page in pages)
            {
                VisitPage(browser, page);
            }
        }
    }
    // An unhandled exception in a background thread in ASP.NET causes the app to be recycled, so catch everything here
    catch (Exception)
    {
        Status = TestStatus.Aborted;
    }
}

private bool VisitPage(WebBrowser browser, string page)
{
    finishedEvent.Reset();

    var timeout = false;
    stopwatch = new Stopwatch();

    browser.Navigate(page);

    stopwatch.Start();

    while (!timeout && !finishedEvent.WaitOne(0))
    {
        Application.DoEvents();
        if (stopwatch.ElapsedMilliseconds > 10000)
            timeout = true;
    }
    Application.DoEvents();

    if (timeout)
    {
        if (resource != null)
            ShopData.Shop.LogPageCrawlTestLine(testRunID, resource, sequence++, (int)stopwatch.ElapsedMilliseconds, null);
    }

    browser.Stop();

    return !timeout;
}

private void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    try
    {
        var browser = (WebBrowser)sender;

        var width = browser.Document.Body.ScrollRectangle.Width;
        var height = browser.Document.Body.ScrollRectangle.Height;
        var timeTaken = (int)stopwatch.ElapsedMilliseconds;

        if ((width == 0) || (height == 0))
        {
            return;
        }

        browser.Width = width;
        browser.Height = height;

        byte[] buffer;

        using (var bitmap = new Bitmap(width, height))
        using (var memoryStream = new MemoryStream())
        {
            browser.DrawToBitmap(bitmap, new Rectangle(0, 0, width, height));
            bitmap.Save(memoryStream, ImageFormat.Bmp);
            buffer = memoryStream.ToArray();
        }
        // stores image

    }
    finally
    {
        finishedEvent.Set();
    }
}

Also zusammenfassend:

  • Der obige Code wird von einer ASP.NET-Seite und es läuft in der backgound
  • gestartet
  • Es funktioniert gut, wenn ich es in einer IIS-Anwendungspool ausgeführt als ein richtigen Benutzer ausführen
  • Wenn ich es in einem IIS-Anwendungspool ausgeführt als NETWORK_SERVICE dann jeder navigate eine neue Sitzung hat, anstatt eine Sitzung für die gesamte Lebensdauer des WebBrowser persistierenden.
  • Ich kann es gut außerhalb von ASP.NET erhalten arbeiten, aber das ist keine Option für mich zur Zeit, hat es in dieser ASP.NET-Anwendung ausgeführt werden.

// aktualisieren

Auf Anraten meines Kollegen I Identitätswechsel in dem Hintergrund-Thread bin mit dem ich den WebBrowser bin zu schaffen, als lokaler Benutzer ausgeführt wird. Das funktioniert gut, und ich bin ziemlich glücklich mit dieser Lösung. Er ist ein Stackoverflow Benutzer so lasse ich ihn die Antwort posten und den Kredit bekommen:)

War es hilfreich?

Lösung

Identitätswechsel in dem Hintergrund-Thread würde der WebBrowser erlaubt als Benutzer mit Berechtigungen zu laufen IE und damit speichern Cookies zu laufen, anstatt es als Anwendungspool Benutzer ausgeführt wird (NETWORK_SERVICE).

Sie können Setup die Identitätswechsel in der web.config oder programmatisch es auf einen spezifischen Thread zu beschränken.

Andere Tipps

nicht offziell aufgrund seiner Verwendung von WinInet unterstützt. finden Sie unter http://support.microsoft.com/kb/238425 für Einschränkungen von WinInet in einem Bedienung.

Sehen Sie den Session-Cookie in den Anfragen von dem WebBrowser-Steuerelement kommen? Ich kann nichts finden, wie diese Kontrolle soll Cookies zu handhaben - wenn es sie ignoriert das Verhalten bekommen würden Sie beschreiben,

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top