문제

웹 페이지의 스크린 샷을 찍으려면 ASP.NET 응용 프로그램에서 WinForms Webbrowser 컨트롤을 사용해야합니다.

콘솔 앱에서 많이 실행하고 ASP.NET 응용 프로그램을 통해 앱에 통신하지만 내 전화가 아니며 웹 사이트의 일부로 실행해야한다고 들었습니다.

탐색을위한 모든 호출과는 별도로 새로운 세션으로 새로 시작하는 것과는 거의 작동합니다. 쿠키가 지속되지 않는 것과 같습니다. 실험으로, 나는 IIS 응용 프로그램 풀을 Network_Service 대신 나처럼 실행하도록 변경했으며 모두 잘 작동합니다. 따라서 네트워크 서비스로 실행하는 것은 이상한 일입니다.

네트워크 서비스 계정에 ASP.NET_SESSITEID 쿠키와 인증 쿠키를 추적 할 권한이 없다고 생각합니다. 그러나 두 가지 모두 비가 유능한 쿠키이므로 왜 그런지 모르겠습니다.

다음은 단순화 된 코드가 있으므로 내가하고있는 일의 요점을 얻을 수 있습니다. 잘라낸 이미지의 로깅 및 저장이 있으므로 완전한 코드가 아닙니다. 기본적으로 개발자/테스터/관리자는 한 번이 코드를 실행할 수 있습니다 (웹 페이지를 통해 작업이 시작됨) 시스템의 모든 페이지의 비트 맵을 생성하고 웹 사이트의 새 버전을 출시 한 다음 다시 실행할 수 있습니다. 차이점 (새 페이지, 제거 된 페이지, 페이지 변경).

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();
    }
}

따라서 요약 :

  • 위 코드는 ASP.NET 페이지에서 시작하여 BackGound에서 실행됩니다.
  • 적절한 사용자로 실행되도록 IIS 애플리케이션 풀에서 실행하면 잘 작동합니다.
  • IIS 애플리케이션 풀에서 네트워크로 실행하면 모든 탐색에는 웹 브라우저의 수명을위한 세션을 지속하지 않고 새 세션이 있습니다.
  • ASP.NET 외부에서 잘 작동 할 수 있지만 현재는 옵션이 아니므 로이 ASP.NET 응용 프로그램에서 실행해야합니다.

//업데이트

내 동료의 조언에 따라 나는 웹 브라우저를 만들고 로컬 사용자로 실행하는 백그라운드 스레드에서 가장합니다. 이것은 잘 작동 하며이 솔루션에 매우 만족합니다. 그는 stackoverflow 사용자이므로 답을 게시하고 크레딧을 받도록하겠습니다 :)

도움이 되었습니까?

해결책

백그라운드 스레드에서 가장하는 데있어서 Webbrowser는 Application Pool 사용자 (Network_Service)로 실행되는 대신 IE를 실행하는 권한을 가진 사용자로 실행할 수 있습니다.

당신은에 가장을 설정할 수 있습니다 web.config 또는 프로그램 적으로 특정 스레드로 제한합니다.

다른 팁

Wininet 사용으로 인해 비교적으로 지원되지 않습니다. 보다 http://support.microsoft.com/kb/238425 서비스에서 Wininet의 한계.

웹 브라우저 컨트롤에서 오는 요청에서 세션 쿠키가 보이나요? 이 컨트롤이 쿠키를 처리하는 방법에 대해 아무것도 찾을 수 없습니다. 쿠키를 무시하면 설명하는 동작을 얻을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top