我需要在ASP.NET應用程序中使用WinForms WebBrowser控件才能截取網頁截圖。將WinForms WebBrowser控件作爲NETWORK_SERVICE運行
我寧願在控制檯應用程序中運行它,並通過ASP.NET應用程序與應用程序通信,但它不是我的電話,我被告知它必須作爲網站的一部分運行。
除了每次調用導航都會從新會話開始新鮮開始,它就像餅乾沒有被持久保存一樣。作爲一個實驗,我將我的IIS應用程序池更改爲以我的身份運行而不是NETWORK_SERVICE,並且一切正常。所以它作爲網絡服務運行是很奇怪的。
我猜測網絡服務帳戶沒有權限跟蹤ASP.NET_SessionId cookie和auth cookie,但這兩個都是非持久性cookie,所以我不知道爲什麼將會。
下面是一些簡化的代碼,以便您可以獲得我正在做的事情的要點。有很多記錄和存儲我剪下來的圖像,所以它不是完整的代碼。基本上,開發人員/測試人員/管理員可以運行一次代碼(任務通過網頁啓動),它會生成系統中每個頁面的位圖,他們可以發佈新版本的網站,然後再運行它,它會告訴你差異(新頁面,頁面被刪除,頁面改變)。
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應用程序池集運行它,它工作正常以適當的用戶身份運行
- 如果我將其作爲NETWORK_SERVICE在IIS應用程序池中運行,則每個導航都會有一個新的會話,而不是在WebBrowser的生命週期中保留一個會話。
- 我可以在ASP.NET以外的地方正常工作,但目前這不是我的選擇,它必須在此ASP.NET應用程序中運行。
//更新
在我的同事,我使用模擬在後臺線程在那裏我創建的web瀏覽器,運行的本地用戶的意見。這工作正常,我很滿意這個解決方案。他是一個計算器用戶,所以我會讓他發佈答案並獲得信用:)
你能準確地分享你開始和停止冒充的地方嗎?我有它的工作(環境。UserName會返回所期望的),但瀏覽器仍然不會保留cookie。相反,如果我將App Pool設置爲以相同用戶身份運行,那麼它工作正常...... – Roman 2014-05-21 05:37:24