VB.net webbrowser 自定义下载接口实现
使用《VB.net webbrowser 如何实现自定义下载 IDownloadManager》中的控件ExtendedWebBrowser(下载控件),并扩展了NewWindow2。
使用ExtendedWebBrowser_1过程中,遇到很多问题,花了几天时间,终于解决了所有问题。
问题1:接管了下载后,发现大文件下载,主程序会阻塞。
一开始,以为是在写文件时因为IO响应导致阻塞,改用异步写,等等...尝试,发现阻塞依然,看过《C# 用FileStream.WriteAsync 异步读文件,调用线程还是被阻塞了》等文章后,问题依然未能解决。
最后尝试主程序不写文件(就是接管下载后,在OnDataAvailable中对接收数据不操作),不做任何操作,阻塞依然存在。阻塞会导致下载中断,而且这种情况与下载文件大小无关,即使很小几M的文件也会发生。
苦思中,记起以前写一个延时函数时,为了不阻塞而加入了Application.DoEvents()语句,于是在最频繁操作的OnDataAvailable中加入Application.DoEvents()语句,问题终于得到完满解决。
问题2:写文件
一开始,是主程序写文件,遇到太多麻烦,在解决问题1中,发现接管了下载后,其实IE是有在后台进程中将文件下载到IE缓冲区的,OnProgress第一次便是返回IE缓冲区中下载的文件名,于是便改用:等下载完后从IE缓冲区复制文件。(貌似IE原有下载器也是这样干的?)
问题3:对于会弹出新窗口的下载,在进行第二次下载时,没有触发下载。
因为主程序中接管弹出窗口的Extendedwebbrowser_2一直没关闭(IE中下载窗口是立即关闭的),并且发现,在NewWindow2中将弹出下载转到Extendedwebbrowser_2触发下载时,Extendedwebbrowser_2并没有触发DocumentCompleted,估计就是这里导致第二次下载时不能触发。
解决办法:在下载完后,Extendedwebbrowser_2加载空白页"about:blank",问题解决。
下面是IWebBrowserDownloadManager接口完整代码:
Imports Remotion.Dms.Clients.Windows.WebBrowserControl
Imports System.IONamespace MyDownloadmanager '定义接口,以实现接口引用 2023.10.27Public Class MyDownloadmanagerImplements IWebBrowserDownloadManagerDim INetCacheFile As String'一些状态的判定(True、False),其中的一种状态(True或False)必须放在接口内进行设定,'不能全部都靠通过外部进程来设定,外部进程只进行其中一种状态的改变就好,否则因为轮询时间差而导致不同步引发非预期结果发生。'例如:AfterLoadBlank#Region "增加属性,将接口的数据传递出去以及传进来"#Region "可读写属性"Private _ContinueDownload As Boolean = TruePublic Property ContinueDownload() As BooleanGetReturn _ContinueDownloadEnd GetSet(ByVal value As Boolean)_ContinueDownload = valueEnd SetEnd PropertyPrivate _DownloadDir As String = ""Public Property DownloadDir() As StringGetReturn _DownloadDirEnd GetSet(ByVal value As String)_DownloadDir = valueEnd SetEnd PropertyPrivate _AttchmentFilename As String = ""Public Property AttchmentFilename() As StringGetReturn _AttchmentFilenameEnd GetSet(ByVal value As String)_AttchmentFilename = valueEnd SetEnd Property'对于会弹出新窗口的下载,因为程序中接管的webbrowser一直没关闭,’在下载完后,需要加载一次新页(在这里加载空白页"about:blank"),‘否则可能无法进行下一次下载。Private _AfterLoadBlank As Boolean = FalsePublic Property AfterLoadBlank() As Boolean GetReturn _AfterLoadBlankEnd GetSet(ByVal value As Boolean)_AfterLoadBlank = valueEnd SetEnd Property#End Region#Region "ReadOnly Property"Dim _DownloadFileName As String = ""Public ReadOnly Property DownloadFileName() As StringGetReturn _DownloadFileNameEnd GetEnd PropertyPrivate _totalSize As IntegerPublic ReadOnly Property GetTotalSize() As IntegerGetReturn _totalSizeEnd GetEnd PropertyPrivate _currentValue As IntegerPublic ReadOnly Property GetCurrentValue() As IntegerGetReturn _currentValueEnd GetEnd PropertyPrivate _success As BooleanPublic ReadOnly Property GetSuccess() As BooleanGetReturn _successEnd GetEnd PropertyPrivate _statusText As StringPublic ReadOnly Property GetStatusText() As StringGetReturn _statusTextEnd GetEnd PropertyPrivate _isAborted As BooleanPublic ReadOnly Property GetisAborted() As BooleanGetReturn _isAbortedEnd GetEnd PropertyPrivate _IsDownloadCompleted As Boolean = False'下载开始时,设置为false,下载结束或退出时,设置为TruePublic ReadOnly Property IsDownloadCompleted() As Boolean GetReturn _IsDownloadCompletedEnd GetEnd PropertyPrivate _OnStartDownloading As Boolean = False'下载开始时,设置为false,下载结束或退出时,设置为TruePublic ReadOnly Property OnStartDownloading() As Boolean GetReturn _OnStartDownloadingEnd GetEnd Property#End Region#End Region#Region "接口函数"Public Sub OnAborted() Implements Remotion.Dms.Clients.Windows.WebBrowserControl.IWebBrowserDownloadManager.OnAbortedWriteRunLog("OnAborted")_isAborted = True_IsDownloadCompleted = True_OnStartDownloading = FalseEnd SubPublic Function OnDataAvailable(ByVal buffer() As Byte, ByVal bytesAvailable As Integer) As Boolean Implements Remotion.Dms.Clients.Windows.WebBrowserControl.IWebBrowserDownloadManager.OnDataAvailable_currentValue += bytesAvailable'需要加这行,否则可能下载时发生阻塞,导致下载中断,而且这种情况与下载文件大小无关,即使很小几M的文件也会发生。Application.DoEvents() Return _ContinueDownloadEnd Function'在下载完后,需要加载一次新页(在这里加载空白页"about:blank"),否则可能无法进行下一次下载。Public Sub OnDownloadCompleted(ByVal success As Boolean, ByVal statusText As String) Implements Remotion.Dms.Clients.Windows.WebBrowserControl.IWebBrowserDownloadManager.OnDownloadCompleted_isAborted = False_IsDownloadCompleted = True_OnStartDownloading = False_AfterLoadBlank = True_success = success_statusText = statusText_AttchmentFilename = ""WriteRunLog("OnDownloadCompleted:" + success.ToString + " " + statusText)If success ThenIf String.IsNullOrEmpty(INetCacheFile) ThenWriteRunLog("没有找到IE缓冲区文件!文件 " + _DownloadFileName + " 下载失败!")ElseFile.Copy(INetCacheFile, _DownloadFileName, overwrite:=True) '从IE缓冲区复制文件WriteRunLog("找到IE缓冲区文件: " + INetCacheFile + ",复制到:" + _DownloadFileName)End IfEnd IfEnd SubPublic Function OnProgress(ByVal currentValue As Integer, ByVal totalSize As Integer, ByVal statusText As String) As Boolean Implements Remotion.Dms.Clients.Windows.WebBrowserControl.IWebBrowserDownloadManager.OnProgress_totalSize = totalSize'从第一次OnProgress中获取下载文件名If String.IsNullOrEmpty(_DownloadFileName) Then _DownloadFileName = MyGetFileName(statusText)If String.IsNullOrEmpty(_DownloadFileName) Then_DownloadFileName = "TmpFile"End IfIf Directory.Exists(_DownloadDir) Then_DownloadFileName = _DownloadDir + "\" + _DownloadFileNameEnd IfEnd IfIf String.IsNullOrEmpty(INetCacheFile) ThenIf InStr(statusText, "Windows\INetCache") > 0 Then '查找IE缓冲区文件 保存路径、文件名INetCacheFile = statusText'WriteRunLog("OnProgress找到IE缓冲区文件: " + INetCacheFile)End IfEnd IfSystem.Windows.Forms.Application.DoEvents()Return _ContinueDownloadEnd FunctionPublic Function OnStartDownload(ByVal uri As System.Uri) As Boolean Implements Remotion.Dms.Clients.Windows.WebBrowserControl.IWebBrowserDownloadManager.OnStartDownload_currentValue = 0_OnStartDownloading = True_ContinueDownload = True_IsDownloadCompleted = FalseINetCacheFile = ""_DownloadFileName = ""WriteRunLog("OnStartDownload :" + uri.ToString)Return TrueEnd Function'OnStartDownload:http://115.1.115.15:9080/FrntMonitor/servlet/com.icbc.cte.cs.servlet.CSReqServlet'1、第一次获得文件名 OnProgress:0 totalSize:0 statusText: C:\Users\gdzs-liyh\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\0F2VEW6C\statatmdev[2].xls'2、第二次获得下载链接 OnProgress:3483 totalSize:0 statusText:(OnStartDownload中的网址:http://115.1.115.15:9080/FrntMonitor/servlet/com.icbc.cte.cs.servlet.CSReqServlet)'3483就是在这时候读取的数据大小。'OnProgress:3483 totalSize:0 statusText: C:\Users\gdzs-liyh\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\0F2VEW6C\statatmdev[2].xls'OnDataAvailable:38281 (这个就是文件的实际大小)(可能文件小,此时文件已经下载到缓存:C:\Users\gdzs-liyh\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\0F2VEW6C\statatmdev[2].xls)'OnProgress:38281 totalSize:0 statusText:(OnStartDownload中的网址)'OnDownloadCompleted'================================='OnStartDownload :http://115.96.14.11/kjbbs/UpLoadFile/2010-7/20107214401523292.doc'1、第一次获得文件名 OnProgress:0 totalSize:0 statusText :http://115.96.14.11/kjbbs/UpLoadFile/2010-7/20107214401523292.doc'2、第二次获得下载链接 OnProgress:119296 totalSize:119296 statusText :http://115.96.14.11/kjbbs/UpLoadFile/2010-7/20107214401523292.doc'OnProgress:119296 totalSize:119296 statusText :C:\Users\gdzs-liyh\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\5Q44G40U\20107214401523292.doc'OnProgress:119296 totalSize:119296 statusText :http://115.96.14.11/kjbbs/UpLoadFile/2010-7/20107214401523292.doc'OnDataAvailable:119296 (可能文件小,此时文件已经下载到缓存:C:\Users\gdzs-liyh\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\0F2VEW6C\statatmdev[2].xls)'OnDownloadCompleted#End RegionShared Sub WriteRunLog(ByVal MyMsg As String)'Using w As StreamWriter = File.AppendText("RunLog.txt")Dim w As StreamWriterIf File.Exists("RunLog.txt") ThenIf My.Computer.FileSystem.GetFileInfo("RunLog.txt").Length > 10485760 Then '2017.5.4 文件大于10M,清0w = File.CreateText("RunLog.txt")w.Write("文件大于10M,置0从头开始!")w.Write(Chr(9))Elsew = File.AppendText("RunLog.txt")End IfElsew = File.CreateText("RunLog.txt")End Ifw.Write(Now)w.Write(Chr(9)) '插入Tab键w.WriteLine(MyMsg)w.Flush()w.Close()'End UsingEnd SubPublic Function MyGetFileName(ByVal inStr As String) As String'获取文件名, '文件夹名、文件名不能包含下列字符\/:*?"<>|Dim ss As Stringss = System.IO.Path.GetFileName(inStr)Dim n = InStrRev(ss, "=")If n < ss.Length Thenss = ss.Substring(n)End IfMyGetFileName = ss.Replace("\", "").Replace("/", "").Replace(":", "").Replace("*", "").Replace("?", "").Replace(Chr(34), "").Replace("<", "").Replace(">", "").Replace("|", "")If InStrRev(MyGetFileName, "[") > 1 And InStrRev(MyGetFileName, "[") < InStrRev(MyGetFileName, "]") Then '将 21018102002617385797[1] 中的 [1] 去掉MyGetFileName = Left(MyGetFileName, InStrRev(MyGetFileName, "[") - 1) + Mid(MyGetFileName, InStrRev(MyGetFileName, "]") + 1)End IfMyGetFileName = _AttchmentFilename + MyGetFileNameEnd FunctionEnd ClassEnd Namespace
相关文章:
VB.net webbrowser 自定义下载接口实现
使用《VB.net webbrowser 如何实现自定义下载 IDownloadManager》中的控件ExtendedWebBrowser(下载控件),并扩展了NewWindow2。 使用ExtendedWebBrowser_1过程中,遇到很多问题,花了几天时间,终于解决了所有…...
Android 启动优化案例-WebView非预期初始化排查
作者:邹阿涛涛涛涛涛涛 去年年底做启动优化时,有个比较好玩的 case 给大家分享下,希望大家能从我的分享里 get 到我在做一些问题排查修复时是怎么看上去又low又土又高效的。 1. 现象 在我们使用 Perfetto 进行app 启动过程性能观测时&#…...
【MATLAB源码-第80期】基于蚯蚓优化算法(EOA)的无人机三维路径规划,输出做短路径图和适应度曲线
操作环境: MATLAB 2022a 1、算法描述 蚯蚓优化算法(Earthworm Optimisation Algorithm, EOA)是一种启发式算法,灵感来源于蚯蚓在自然界中的行为模式。蚯蚓优化算法主要模仿了蚯蚓在寻找食物和逃避天敌时的行为策略。以下是蚯蚓…...
树状图怎么画?推荐这个好用的在线树状图软件!
在日常工作和学习中,我们需要用到各种各样的图表,树状图是其中之一。 树状图是什么? 树状图是一种层次式的图形结构,可以用来展示数据之间的关系,并且可以在一定程度上提高工作和学习的效率。 树状图通常用来表示…...
C#学习相关系列之Linq用法---where和select用法(二)
一、select用法 Linq中的select可以便捷使我们的对List中的每一项进行操作,生成新的列表。 var ttlist.select(p>p10); //select括号内为List中的每一项,p10即为对每一项的操作,即对每项都加10生成新的List 用法实例: 1、la…...
后端返回 date 时间日期格式为 UTC 格式字符串,形如 2022-08-11T10:50:31.050+00:00前端如何修改为yyyy-mm-dd
在不指定任何特殊配置的情况下,返回的 date 类型的字段会自动转成 UTC 格式字符串,形如 2022-08-11T10:50:31.05000:00。 前端如何处理? vue举例 utils 下新建 mixins.js文件 // minins.js文件 import Vue from "vue"; import {…...
【万字长文】前端性能优化实践 | 京东云技术团队
一、引言 从一个假死页面引发的思考: 作为前端开发,除了要攻克页面难点,也要有更深的自我目标,性能优化是自我提升中很重要的一环; 在前端开发中,会偶遇到页面假死的现象, 是因为当js有大量计算…...
WPF位图效果
Windows Presentation Foundation (WPF) 提供了许多位图效果,可以让你创建复杂的图形和动画。这些效果包括,但不限于以下几种: 模糊效果 (BlurEffect):这一效果可以使图像模糊,你可以设置模糊半径来控制模糊程度。投影…...
CFI(Common Flash Interface)简介
CFI定义了符合CFI规则设备的基本Query接口,包括已知或待拟定的flash Read/Write/Program/Erase控制接口。Query接口以结构体形式定义与flash设备相关的关键参数,但是CFI不会对单个flash设备厂家指定详细的指令集、状态轮询模式以及软件算法。 1.操作概要…...
linux、windows 查看java等进程占用资源情况
linux查看进程占用资源情况: top -o %MEM -b -n 1 | grep java | awk {print "PID: "$1" \t 虚拟内存: "$5" \t 物理内存: "$6" \t 共享内存: "$7" \t CPU使用率: "$9"% \t 内存使用率: "$10"%&…...
听GPT 讲Rust源代码--library/core/src(7)
题图来自 Hello, crustaceans.[1] File: rust/library/core/src/ptr/metadata.rs 在Rust的源代码中,rust/library/core/src/ptr/metadata.rs 文件的作用是定义了与指针(ptr)和元数据(metadata)相关的结构体和 trait&am…...
html:lang属性设置为中文zh-CN
默认的lang属性 <html lang"en"> </html>声明网页语言格式: 语言-国家/地区示例 <html lang"zh-CN"> </html>ISO 639-1 语言代码 语言ISO 代码Chinese (简体)zh ISO 639-1 国家/地区代码 国家/地区ISO 代码CHINA…...
滴滴 Redis 异地多活的演进历程
为了更好的做好容灾保障,使业务能够应对机房级别的故障,滴滴的存储服务都在多机房进行部署。本文简要分析了 Redis 实现异地多活的几种思路,以及滴滴 Redis 异地多活架构演进过程中遇到的主要问题和解决方法,抛砖引玉,…...
前端实现页面内容的截图与下载(html2canvas)
今天是一个发文的好日子😀~ 👇👇👇 一个需求,要截取页面中的内容并截图保存,来看一看我是怎么实现的吧: 这里需要使用到插件--html2canvas 1.安装并引入html2canvas npm install html2canv…...
VS2017 IDE 编译时的 X86、x64位 是干什么的
指定编译出的程序是x86架构下的32位程序还是64位程序 VS2017项目配置X86改配置x64位_winform:把项目由x86改为x64-CSDN博客 vs平台选项:Any CPU,x86,x64_vs anycpu-CSDN博客...
微信小程序 解决tab页切换过快 数据出错问题
具体问题:切换tab页切换过快时,上一个列表接口未响应完和当前列表数据冲突 出现数据错误 具体效果如下: 解决方式:原理 通过判断是否存在request 存在中断 并发送新请求 不存在新请求 let shouldAbort false; // 添加一个中断标志 let re…...
Taro编译警告解决方案:Error: chunk common [mini-css-extract-plugin]
文章目录 1. 背景2. 问题分析3. 解决方案3.1 更新 Taro 版本3.2 更新相关依赖3.3 调整 webpack 配置3.4 检查依赖版本 4. 拓展与分析4.1 拓展4.2 避免不必要的依赖4.3 查阅 Taro GitHub 仓库 5. 总结 🎉欢迎来到Java学习路线专栏~Taro编译警告解决方案:E…...
基于JavaWeb+SpringBoot+Vue电子商城微信小程序系统的设计和实现
基于JavaWebSpringBootVue电子商城微信小程序系统的设计和实现 源码获取入口前言系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 身处互联网时代,互联网无形中影响着人们的吃穿住行,人们享受着不…...
JS进阶——作用域、解构、箭头函数
1、作用域 作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问。 1.1 局部作用域 局部作用域可分为函数作用域和块作用域。 1.1.1 函数作用域 在函数内部声明的变量只能在函数内部被访问,外部无…...
centos下安装mysql8版本
1、如果服务器没有wget,先下载wget工具 sudo yum install wget 2、下载指定mysql版本的tar包 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.21-1.el7.x86_64.rpm-bundle.tar 3、解压tar包 sudo tar -xvf mysql-8.0.21-1.el7.x86_64.rpm…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
