DELPHI中的webbrowser如何有效防止内存疏漏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DELPHI中的webbrowser如何有效防止内存疏漏相关的知识,希望对你有一定的参考价值。

根据网上给出的修改文件重新编译的办法可以有效减少,但仍然未能杜绝。我做的程序仍然是过一段时间就大量占用内存,烦死了。

有没有办法彻底解决这个问题?若是要控件解决,麻烦给个控件地址,谢谢。
我没怎么写代码,一般就是打开一个链接,然后用try
wb1.OleObject.document.all.item('DDDDD').innerText:=*******;excpet end;
这类的

或者自动刷新的页面。一刷新就占用多几k到几十K的内存,晕死哦

WEBBROWSER控件是安全的,代码写的好就可以了。。
但占用内存多,那是没办法的。。除非你用底层的WINSOCK自己写个GET HTTP
参考技术A 没听说webbrowser会造成内存泄露啊,是不是你调用了它的接口又没释放呢?检查一下你的代码吧

例如:
finally
Element._Release
end;

如何检测 WebBrowser 控件中的 Javascript 执行

【中文标题】如何检测 WebBrowser 控件中的 Javascript 执行【英文标题】:How to detect Javascript execution in WebBrowser control 【发布时间】:2012-03-22 23:42:34 【问题描述】:

我的 C# 应用程序中有一个 WebBrowser 控件。网络浏览器在用户的控制之下,即他可以在网络上加载他的电脑可以访问的任何网页(当然受限于代理、hosts文件等)。

当网页浏览器组件中加载的页面内有 Javascript 调用时,我需要知道并得到通知。

第一个例子:给定这样的链接

<a href="javascript:void(0)" onclick="jsFunct();">test</a>

当用户点击链接时,我需要知道函数“jsFunct”已被调用。

第二个例子:给定一个电话

<script type="text/javascript">
    window.setTimeout("jsFunct()", 1000);
</script>

我需要知道,脚本执行后1秒,函数jsFunct已经被调用。

最好的办法是在函数被调用时触发一个事件。如果事件可以执行 Javascript 代码,或者至少是参数中的函数名,那也很棒。

编辑:

即使问题与 webbrowser 组件有关,任何允许用户检测 javascript 激活(甚至通过 js)的东西都可以,能够注入处理 javascript 事件并将其传递给 wb 控件的 js触发一些它可以处理的事件。

【问题讨论】:

【参考方案1】:

当在 JavaScript 中触发全局函数时,您可以使用 window.external 调用 C# 方法。有关 window.external 的详细信息,请参阅WebBrowser Control Overview。

您需要设置 ObjectForScripting: Webbrowser control's window.external is ALWAYS null. 才能使其工作。

采用@Krishna 的回答来添加 JavaScript(但删除 jQuery,因为它不需要):

private void addScript(HtmlElement head, string scriptSource) 
 
HtmlElement lhe_script = head.Document.CreateElement("script"); 
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
script.src = scriptSource;
head.AppendChild(lhe_script);            
 

addScript(WebBrowser.Head, @"InjectMonitor.js");

下面的 JavaScript (InjectMonitor.js) 将查找所有全局函数并附加您指定的处理程序:

function augment(withFn) 
    var name, fn;
    for (name in window) 
        fn = window[name];
        if (typeof fn === 'function') 
            window[name] = (function(name, fn) 
                var args = arguments;
                return function() 
                    withFn.apply(this, args);
                    fn.apply(this, arguments);

                ;
            )(name, fn);
        
    


augment(function(name, fn) 
    console.log("calling " + name, fn);

    // window.external.yourC#method
);

在这个例子中,取自Adding Console Log to Every Function,它只是记录对控制台的调用;但是使用 window.external 您可以将一些消息发送回您的 C# 应用程序,其中包含从客户端调用的函数的详细信息。

最后,这是一个 JS Bin 示例(运行它,不要忘记控制台):JS Bin Example

【讨论】:

目前我没有太多时间来测试这个,你能解释一下我如何用window.external 检测到网页中对特定js函数的调用吗?一个小的代码示例也将不胜感激 已更新,我添加了相关的 JS 并希望完整的解决方案。 正是我所需要的,真的很高兴奖励赏金并解决这个问题,谢谢! 没问题,仅供参考,我曾经玩过 Function.prototype.call 认为可以做到这一点,但除非调用 call(),否则永远无法让它工作。 什么是WebBrowser.Head?这是一个例子,你的意思是WebBrowser.Document.GetElementsByTagName("head")[0]?【参考方案2】:

在浏览器加载事件上,

    注入 Jquery 注入监控脚本

private void addScript(HtmlElement head, string scriptSource) 
 
HtmlElement lhe_script = head.Document.CreateElement("script"); 
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
script.src = scriptSource;
head.AppendChild(lhe_script);            
 

addScript(Webbrowser.Head, @"<Change File Path here>jquery.min.js");
addScript(WebBrowser.Head, @"InjectMonitor.js");

您的文件 InjectMonitor.js 应该是这样的

 $(document).ready(function ()  
        //Add click event for every anchor on the page loaded- note this merely alerts text on click. you can however add your own function
        $("a").click(function (e)  alert($(this).text()); return false;) 
    ); 

【讨论】:

+1 为我指明了正确的方向,让我们做更多的工作来得到答案 请告诉我你们相处得如何。如果你被困在某个地方,我也会尝试在我的最后设置这个项目。这是一个很好的,相信很有可能 您能更好地解释一下“监控脚本”是什么意思吗?谢谢 jQuery 支持同一事件的多个处理程序,因此如果您想知道某人何时单击了某个锚点(例如),您可以将代码添加到 MonitorScript(请参阅上面我编辑的答案) 我相信这就是帖子所说的,包装对 webbrowser 代码中加载的现有 javascript 代码(不在您的控制范围内)的额外调用。即,对于页面中的每个 javascript 函数,向您的侦听器注入一个调用(这是/将在 MonitorScript.js 中定义)。让我看看我是否可以为您获取此代码。我这周不在,但这将是一项值得思考的好任务【参考方案3】:

克里希纳回答的是纯 javascript 附加到事件,但是我看到您可能需要将它附加到所有标签(a、p、div、输入)等以及附加到每个标签的所有事件.

我相信另一种方法是使用 .net 中可用的 BHO(浏览器帮助对象),如果没有,并且您擅长 VC++ 和 MFC,您也可以使用 Windows Hooks。

【讨论】:

将javascript附加到事件的问题是它没有检测到使用setTimeout之类的函数执行的javascript的执行。此外,如果点击没有触发 javascript 调用怎么办?不好。无论何时发生,我都需要检测 JavaScript 函数的执行,它应该在事件处理程序中调用,由超时触发还是以其他方式触发。

以上是关于DELPHI中的webbrowser如何有效防止内存疏漏的主要内容,如果未能解决你的问题,请参考以下文章

DELPHI如何实现打开某一个网页没webbrowser组件

DELPHI 如何获得 Webbrowser 浏览文件夹 选中的文件路径

delphi中 WebBrowser如何控制Frame下面的元素

delphi中WebBrowser控件怎么模拟点击网页框架中的按钮button?

Delphi用WebBrowser控件定制浏览器,如何控制不让下载网页中的图像或Flash或背景音乐之类的东西?

delphi webbrowser,如何调整webbrowser里面打开网页的大小,或者使打开的内容适应webbrowser控件的大小。