我有一个列表Uri,我想要"点击"为了达到这个目的,我试图为每个Uri创建一个新的Web浏览器控件.我为每个Uri创建一个新线程.我遇到的问题是文档在文档之前结束是完全加载的,所以我永远不会使用DocumentComplete事件.我怎么能克服这个?
var item = new ParameterizedThreadStart(ClicIt.Click);
var thread = new Thread(item) {Name = "ClickThread"};
thread.Start(uriItem);
public static void Click(object o)
{
var url = ((UriItem)o);
Console.WriteLine(@"Clicking: " + url.Link);
var clicker = new WebBrowser { ScriptErrorsSuppressed = true };
clicker.DocumentCompleted += BrowseComplete;
if (String.IsNullOrEmpty(url.Link)) return;
if (url.Link.Equals("about:blank")) return;
if (!url.Link.StartsWith("http://") && !url.Link.StartsWith("https://"))
url.Link = "http://" + url.Link;
clicker.Navigate(url.Link);
}
Run Code Online (Sandbox Code Playgroud) 我正在使用嵌入在C#WPF .NET4应用程序中的webbrowser控件.每当我手动按下表单中的按钮时,浏览器就会挂起"正在处理您的请求"消息并且没有任何反应.如果我在完整的IE浏览器中执行相同操作,则会正常处理页面以生成结果.我错过了什么?谢谢按钮背后的代码如下
<a onclick="startSearch();" href="javascript:void(-1);" name="btnNext" class="btn floatLe noClear btnSubmit btnRight">
<span>Continue</span>
</a>
Run Code Online (Sandbox Code Playgroud) 当一个COM对象在STA线程上实例化时,该线程通常必须实现一个消息泵,以便为来回调用其他线程(见这里).
可以手动泵送消息,或者依赖于某些(但不是全部)线程阻塞操作在等待时自动泵送COM相关消息的事实.文档通常无助于决定哪个是哪个(参见相关问题).
如何确定线程阻塞操作是否会在STA上泵送COM消息?
到目前为止的部分清单:
阻断其业务做泵*:
Thread.JoinWaitHandle.WaitOne/ WaitAny/WaitAll(WaitAll不能从一个STA线程虽然称为)GC.WaitForPendingFinalizersMonitor.Enter(因此lock) - 在某些条件下ReaderWriterLock阻止不泵送的操作:
Thread.SleepConsole.ReadKey (在某处读)*注意Noseratio的答案说,即使是操作泵,也是为非常有限的未公开的COM特定消息集.
我正在建立一个冲浪到几个网站并做一些事情的程序.
在成功冲浪到5个网址之后,该程序在Application.Run()行之后挂起.该程序甚至没有进入处理程序功能,只是卡住了.此时CPU使用率为0.
我尝试以任何可能的方式关闭线程.我做错了什么?
我这样做:
[STAThread]
private static void Main(string[] args)
{
for (int i = 0; i < urls.Count; i++)
{
var th = new Thread(() = >
{
var weBrowser = new WebBrowser();
weBrowser.AllowNavigation = true;
weBrowser.DocumentCompleted += Handler;
weBrowser.Navigate(urls[i]);
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join();
}
}
Run Code Online (Sandbox Code Playgroud)
而我的Handle功能是:
private static void Handler(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser weBrowser = sender as WebBrowser;
var htmlDocument = weBrowser.Document;
/*do something*/
Application.Exit();
Application.ExitThread();
weBrowser.Dispose();
weBrowser.Stop();
Thread.CurrentThread.Abort();
}
Run Code Online (Sandbox Code Playgroud)
我的问题非常类似于: Application.Run()导致应用程序挂起
这个问题也没有答案.
谢谢!
我读过的关于这个主题的大多数答案都指向System.Windows.Forms.WebBrowser类或来自Microsoft HTML Object Library程序集的COM接口mshtml.HTMLDocument.
WebBrowser类没有引导我到任何地方.以下代码无法检索由我的Web浏览器呈现的HTML代码:
[STAThread]
public static void Main()
{
WebBrowser wb = new WebBrowser();
wb.Navigate("https://www.google.com/#q=where+am+i");
wb.DocumentCompleted += delegate(object sender, WebBrowserDocumentCompletedEventArgs e)
{
mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)wb.Document.DomDocument;
foreach (IHTMLElement element in doc.all)
{
System.Diagnostics.Debug.WriteLine(element.outerHTML);
}
};
Form f = new Form();
f.Controls.Add(wb);
Application.Run(f);
}
Run Code Online (Sandbox Code Playgroud)
以上只是一个例子.我真的不想找到一个解决方法来找出我所在城镇的名称.我只需要了解如何以编程方式检索那种动态生成的数据.
(调用新的System.Net.WebClient.DownloadString(" https://www.google.com/#q=where+am+i "),将生成的文本保存到某处,搜索您当前所在城镇的名称找到了,如果你能找到它,请告诉我.)
但是,当我从我的网络浏览器(即或Firefox)访问" https://www.google.com/#q=where+am+i "时,我会在网页上看到我的城镇名称.在Firefox中,如果我右键单击城镇名称并选择"Inspect Element(Q)",我会清楚地看到用HTML代码编写的城镇名称,这看起来与WebClient返回的原始HTML完全不同.
在我厌倦了玩System.Net.WebBrowser后,我决定给mshtml.HTMLDocument一个镜头,最后得到同样无用的原始HTML:
public static void Main()
{
mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)new mshtml.HTMLDocument();
doc.write(new System.Net.WebClient().DownloadString("https://www.google.com/#q=where+am+i"));
foreach (IHTMLElement e in doc.all)
{
System.Diagnostics.Debug.WriteLine(e.outerHTML);
}
}
Run Code Online (Sandbox Code Playgroud)
我想必须有一种优雅的方式来获取这种信息.现在,我能想到的是将一个WebBrowser控件添加到表单中,让它导航到相关的URL,发送键"CLRL,A",并将页面上显示的任何内容复制到剪贴板并尝试解析它.不过,这是一个可怕的解决方案.
根据以下链接和我的控制台应用程序,该方法DrawToBitmap不尊重不透明度.
证明链接:http: //social.msdn.microsoft.com/Forums/vstudio/en-US/e9704309-0c52-442d-80e0-2f8393dcd313/webbrowser-opacity-problem-
我的HTML代码:http://fiddle.jshell.net/L37TC/
<div id="fader" style="background-color: #ff0000">ffff</div>
<div style="background-color: blue; opacity:0;filter:alpha(opacity=0);">HIDDEN TEXT!</div>
SomeText
Run Code Online (Sandbox Code Playgroud)
我的C#控制台代码:
var bmp = new Bitmap(640,480, PixelFormat::Format32bppArgb)
var web = (System.Windows.Forms.Control)sender;
web.DrawToBitmap(bmp, Rectangle(0, 0, 640,480));
Run Code Online (Sandbox Code Playgroud)
所以我正在寻找替代的.NET内置解决方案(没有CEF,Awesomium,或任何扩展请)只是.NET的内置功能来修复错误或替代解决方案,以在我的控制台中截取Web URL的屏幕截图应用.
如果我让WebBrowser窗口对我的客户端可见并且使用CopyFromScreen不透明度并且HIDDEN TEXT没有显示,那么我怎么不想让WebBrowser窗口对桌面屏幕可见.
我正在寻找一个内置的解决方案,可以在没有问题的情况下从发布的URL中截取屏幕截图HIDDEN TEXT.换句话说,是尊重opacity的解决方案.
EDIT1:我的所有像素Bitmap class(.NET类不是BMP格式)的alpha值为255.所以问题不在于文件格式.我尝试过PNG和任何其他.NET支持的格式.
完整的源代码(控制台模板,需要添加引用System.Drawing和System.Windows.Forms
class Program
{
static System.Windows.Forms.WebBrowser w = new System.Windows.Forms.WebBrowser();
[STAThread]
static void Main(string[] args) …Run Code Online (Sandbox Code Playgroud) 我在WinForms中有一个WebBrowser控件,其URL属性设置为外部网页.我还有一个DocumentCompleted事件的事件处理程序.在这个处理程序中,我正在尝试获取特定元素,但wb.Document.Body似乎在执行onload之前捕获HTML.
{System.Windows.Forms.HtmlElement}
All: {System.Windows.Forms.HtmlElementCollection}
CanHaveChildren: true
Children: {System.Windows.Forms.HtmlElementCollection}
ClientRectangle: {X = 0 Y = 0 Width = 1200 Height = 0}
Document: {System.Windows.Forms.HtmlDocument}
DomElement: {mshtml.HTMLBodyClass}
ElementShim: {System.Windows.Forms.HtmlElement.HtmlElementShim}
Enabled: true
FirstChild: null
htmlElement: {mshtml.HTMLBodyClass}
Id: null
InnerHtml: "\n"
InnerText: null
Name: ""
NativeHtmlElement: {mshtml.HTMLBodyClass}
NextSibling: null
OffsetParent: null
OffsetRectangle: {X = 0 Y = 0 Width = 1200 Height = 0}
OuterHtml: "<body onload=\"evt_Login_onload(event);\" uitheme=\"Web\">\n</body>"
OuterText: null
Parent: {System.Windows.Forms.HtmlElement}
ScrollLeft: 0
ScrollRectangle: {X = 0 Y = 0 Width = 1200 …Run Code Online (Sandbox Code Playgroud) 该任务的Parallels额外扩展发表于2010年,从那时起没有更新已被释放.
我在3年前在Nuget上将此代码作为DLL发布,并且已经有超过16,000次下载,这是对代码感兴趣的指标.
TPL Extras是否已被任何新技术取代?如果是这样,我想适当地注释Nuget描述.
c# parallel-processing concurrency multithreading task-parallel-library
我有一个#.Net应用程序打开一个自定义的打印预览表单(一个WebBrowser表单控件的泄露,它显示一个HTML文件和一个打印Web浏览器控件内容的按钮:
webBrowser.Print();
Run Code Online (Sandbox Code Playgroud)
但是,我现在想在不打开此表单的情况下打印HTML文件.
我试图将html加载到webbrowser表单而不显示表单并调用webBrowser.Print()但没有任何内容可以打印.如果我显示表单并将HTML加载到控件中,似乎我只能打印.
我正在使用自动测试脚本,并使用WebBrowser控件.我试图在用户接受服务条款时提交以下HTML并进行测试:
<form action="http://post.dev.dealerconnextion/k/6hRbDTwn4xGVl2MHITQsBw/hrshq" method="post">
<input name="StepCheck" value="U2FsdGVkX18zMTk5MzE5OUgFyFgD3V5yf5Rwbtfhf3gjdH4KSx4hqj4vkrw7K6e-" type="hidden">
<button type="submit" name="continue" value="y">ACCEPT the terms of use</button>
<button type="submit" name="continue" value="n">DECLINE the terms of use</button>
</form>
// Terms of Use Information
<form action="http://post.dev.dealerconnextion/k/6hRbDTwn4xGVl2MHITQsBw/hrshq" method="post">
<input name="StepCheck" value="U2FsdGVkX18zMTk5MzE5OUgFyFgD3V5yf5Rwbtfhf3gjdH4KSx4hqj4vkrw7K6e-" type="hidden">
<button type="submit" name="continue" value="y">ACCEPT the terms of use</button>
<button type="submit" name="continue" value="n">DECLINE the terms of use</button>
</form>
Run Code Online (Sandbox Code Playgroud)
这是C#中的代码,但不提交表单.
HtmlElementCollection el = webBrowser.Document.GetElementsByTagName("button");
foreach (HtmlElement btn in el)
{
if (btn.InnerText == "ACCEPT the terms of use")
{
btn.InvokeMember("Click");
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激.谢谢.
我对用 MessageLoopWorker 包装的 WebBrowser 控件进行了一些测试,如下所述:WebBrowser Control in a new thread
但是当另一个测试创建用户控件或表单时,测试会冻结并且永远不会完成:
[Test]
public async Task WorksFine()
{
await MessageLoopWorker.Run(async () => new {});
}
[Test]
public async Task NeverCompletes()
{
using (new Form()) ;
await MessageLoopWorker.Run(async () => new {});
}
// a helper class to start the message loop and execute an asynchronous task
public static class MessageLoopWorker
{
public static async Task<object> Run(Func<object[], Task<object>> worker, params object[] args)
{
var tcs = new TaskCompletionSource<object>();
var thread = …Run Code Online (Sandbox Code Playgroud) c# ×11
.net ×3
html ×2
winforms ×2
async-await ×1
automation ×1
browser ×1
com ×1
concurrency ×1
dynamic-html ×1
for-loop ×1
forms ×1
interop ×1
javascript ×1
message-pump ×1
nunit ×1
onload ×1
printing ×1
submit ×1
vb.net ×1
wpf ×1