我写了一个监控浏览器的小程序,目的是禁止打开标题中含特定字符串的网页,在VB IDE环境中测试正常,编译为exe以后运行也一切正常,但是如果把它作为系统服务来启动,则会出现 运行时错误"7",内存溢出 的错误而启动失败,有没有朋友知道是怎么回事?说明:
1、用ntsvc.ocx来实现系统服务,与系统服务相关的代码可以保证没有问题;
2、程序中添加了对Microsoft Internet Controls的引用;
3、主要功能通过网上找的两个类模块稍加修改来完成,两个类模块分别引用了SHDocVw.InternetExplorer和SHDocVw.ShellWindows。虽然可以改用其他自启动方式,但是既然发现了这个问题,不解决就很郁闷,请大家给帮帮忙吧!
1、用ntsvc.ocx来实现系统服务,与系统服务相关的代码可以保证没有问题;
2、程序中添加了对Microsoft Internet Controls的引用;
3、主要功能通过网上找的两个类模块稍加修改来完成,两个类模块分别引用了SHDocVw.InternetExplorer和SHDocVw.ShellWindows。虽然可以改用其他自启动方式,但是既然发现了这个问题,不解决就很郁闷,请大家给帮帮忙吧!
解决方案 »
- 动态增加控件的问题~~~求助
- 如何限制用户名必须在相对应的IP上应用???
- 记录合并的问题
- access更新问题
- 没用过VB,请教个简单问题----COM接口函数的参数没有类型,怎么回事?
- 关于如何批量插入字符串到VB资源文件里?
- 按地址传递参数,出现编译错误:ByRef argument type mismatch.为什么?在线等待
- help文件怎么做
- 怎样在程序中访问数据库的数据库目录?
- 怎样用BITBLT实现半透明的贴图,并且可以自定义透明度?这个问题有些难度,我问了很多人都没有回答上来!
- 我想问下,自己编写的OCX控件如何在窗体控制
- <TO:fvflove >关于"怎样实现数据的保存?"帖子的后续问题!
Option ExplicitPrivate WithEvents winShell As SHDocVw.ShellWindows
Private mCol As Collection
Dim bRefreshing As Boolean, bInit As BooleanPrivate Function Add(IEctl As SHDocVw.InternetExplorer) As IE_Class
Dim objNewMember As IE_Class
Set objNewMember = New IE_Class
Set objNewMember.IEctl = IEctl
mCol.Add objNewMember
Set Add = objNewMember
Set objNewMember = Nothing
End FunctionPublic Property Get IE(vntIndexKey As Variant) As IE_Class
Do While bRefreshing
DoEvents
Loop
Set IE = mCol(vntIndexKey)
End PropertyPublic Property Get Count() As Long
Count = mCol.Count
End PropertyPrivate Sub Remove(vntIndexKey As Variant)
mCol.Remove vntIndexKey
End SubPublic Property Get NewEnum() As IUnknown
Set NewEnum = mCol.[_NewEnum]
End PropertyPrivate Sub Class_Initialize()
Refresh_Col
End SubPrivate Sub Class_Terminate()
Set mCol = Nothing
Set winShell = Nothing
End SubPrivate Sub winShell_WindowRegistered(ByVal lCookie As Long)
Refresh_Col
Do While bRefreshing
DoEvents
Loop
End SubPrivate Sub winShell_WindowRevoked(ByVal lCookie As Long)
Refresh_Col
Do While bRefreshing
DoEvents
Loop
End SubPrivate Sub Refresh_Col()
bRefreshing = True
Dim SWs As New SHDocVw.ShellWindows
Dim var As SHDocVw.InternetExplorer
Set mCol = Nothing
Set mCol = New Collection
For Each var In SWs
Add var
Next
If Not bInit Then Set winShell = SWs
bInit = True
Set SWs = Nothing
Set var = Nothing
bRefreshing = False
End Sub
Option ExplicitPrivate WithEvents IE As SHDocVw.InternetExplorerPublic Property Set IEctl(IncomeIE As SHDocVw.InternetExplorer)
On Error Resume Next
Set IE = IncomeIE
End PropertyPrivate Sub Class_Terminate()
On Error Resume Next
Set IE = Nothing
End SubPrivate Sub IE_TitleChange(ByVal Text As String)
If InStr(1, Text, "禁止打开的字符串", vbTextCompare) Then
IE.Navigate "about:blank"
End If
End Sub
Option ExplicitDim StopService As BooleanDim IEWin As cIEWindowsPrivate Sub Form_Load()
App.TaskVisible = False
Set IEWin = Nothing
Set IEWin = New cIEWindows
StopService = False
NTService.ControlsAccepted = svcCtrlPauseContinue
NTService.StartService
End SubPrivate Sub Form_Unload(Cancel As Integer)
If Not StopService Then
NTService.StopService
End If
End SubPrivate Sub NTService_Continue(Success As Boolean)
On Error GoTo ServiceError
Success = True
Exit Sub
ServiceError:
End SubPrivate Sub NTService_Control(ByVal mEvent As Long)
On Error GoTo ServiceError
Exit Sub
ServiceError:
End SubPrivate Sub NTService_Pause(Success As Boolean)
On Error GoTo ServiceError
Success = True
Exit Sub
ServiceError:
End SubPrivate Sub NTService_Start(Success As Boolean)
On Error GoTo ServiceError
Success = True
Exit Sub
ServiceError:
NTService.LogEvent svcMessageError, svcEventError, "[" & Err.Number & "] " & Err.Description
End SubPrivate Sub NTService_Stop()
On Error GoTo ServiceError
StopService = True
ServiceError:
End Sub
你用不可交互的模式处理交互模式下的浏览器,肯定会出问题的了。
还有,通常处理浏览器的程序使用BHO(Browser Helper Objects)技术比较好。
这东西用服务程序作完全是多余的。服务程序是确保用户还没有登陆时都能提供服务而使用的。
而你的需求必须是用户登陆后才监视得了的浏览器,这么早启动完全没什么意义,
而且不可交互的NT服务程序也不能处理这样的事,甚至连DDE信息和很多API使用都是无效的,
建议你看看BHO方面的资料,控制和取得浏览器信息用BHO最合适。
我现在把程序分成了两部分,主程序为一部分,loader为一部分,loader作为系统服务,启动后运行主程序。
有意思的是,在loader中如果直接用shell或者shellexecute来执行主程序,还是会出现内存溢出错误,而用shell "cmd /c ..."来调用则不会,哪位朋友可以解释一下这个问题啊?
可以通过用户程序改变服务程序的配置,当然也可以服务程序发送信息让用户程序作服务程序不能做或不方便作的事。
再看看那些下载软件,都是单独用BHO来搞个接口,应用程序也是分离的。如果什么程序都要放在一起,有时候效果反而
不是很好。
2、作为系统服务来运行;
3、在系统服务中通过shell或者shellexecute或者cmd/c来运行这个exe
对于exe文件的这三种运行方式,如果说前两种有很大的不同,那么第1种和第3种方式应该区别不大吧,为什么我的exe用第1种方式可以顺利运行,而后两种方式都会出现内存溢出的错误呢?
至少我没有用NT服务直接运行成应用程序,或反过来直接拿应用
程序加成NT服务来运行我也没这么做过,即使我用,也是在程序里
做了特殊处理的,比如在运行时判断程序如果是NT服务的话怎么处
理应用程序安装自己成NT服务一类的,如果是NT服务的话又怎么去
初始化相关参数。所以就会出现这类的问题。
建议:比如网络服务用NT服务,其他的控制应用程序的就以应用程
序的方式作比较好。其实VB做NT服务Microsoft本来就不建议这样
去做的,相信你也知道,但你还想把这类程序作成万能的,呵呵。
就像SupermanKing朋友说的,微软是不建议用VB6写系统服务的,只是我用ntsvc.ocx做个多个服务,只有这一个出了问题,所以对其中的原因很想弄个究竟,并不是非得解决这个问题不可。
结贴,再次谢谢大家!