您的位置:首页 > 移动开发 > Objective-C

终极解决:变量类型必须为对象类型("Object") 推荐

2010-04-09 08:38 519 查看
[align=center]终极解决:变量类型必须为对象类型("Object")[/align]
[align=left] 关于AUTOIT,相信任何一个技术网管,尤其是网吧的IT技术管理员都不会陌生。如此强大的一个基于windows下的类BASIC的脚本语言。极大地方便了我们工作中的方方面面......上周,抽空去西单图书大厦4层购书,也看到了她的身影(半年前去找过,是没有的),甚感欣慰。仔细翻阅之,大多讲解一些基本的自动安装的东西。。。。并没有真正地讲到AUTOIT对GUI的控制,还有不断扩展的UDF,及在COM接口上的编程实现方法例子,调用API等等,希望在今后有更多的autoit高手出来讲解......[/align]
[align=left] [/align]
[align=left] 言归正题说我遇到的问题:近期在寻找一个可靠的办法来实现对系统服务的智能检测,[/align]
[align=left] [/align]
[align=left] 比如:我要实现对系统服务:seclogon的智能检测,若其是禁用,就设为自动,若其停止运行,就开启这个服务,实现代码如下:[/align]

#include <ServiceControl.au3>
_SetService("seclogon",1) ;若要禁用服务请使用:_SetService("seclogon",2)
Select
Case @error=5
MsgBox(64,"by boyhong.blog.51cto.com","成功将此服务设为自动并启动")
Case @error=6
MsgBox(16,"by boyhong.blog.51cto.com","成功禁用此服务!")
Case @error=7
MsgBox(16,"boyhong.blog.51cto.com","没有此服务名,请确认!")
EndSelect

Func _SetService($ServiceName,$testservice=1)
If $testservice = '' Then $testservice = 1
$Servicecheck = _ServGetDetails($ServiceName) ;查这个服务的详情
If @error <> -1 Then
If $testservice=1 Then
If $Servicecheck[16]<>"Auto" Then _SerSetState($ServiceName,1)
If $Servicecheck[4]<>"Running" Then _ServStart($ServiceName)
Return SetError(5)
EndIf

If $testservice=2 Then
If $Servicecheck[4]="Running" Then _ServStop($ServiceName)
If $Servicecheck[16]="Auto" Then _SerSetState($ServiceName,3)
Return SetError(6)
EndIf
Else
Return SetError(7)
EndIf
EndFunc

以上代码很简单,若要停止这个服务并禁用这个禁用,只需更改:_SetService("seclogon",1)为_SetService("seclogon",2)

但在实际生产中不断发现,以上示例代码在的一小部分电脑上执行,报错如下:



Error: 变量类型必须为对象类型("Object") ,针对此问题,刚开始很困惑,仔细询问这些个用户,才得知,他们安装的系统为精简版系统或者经过一些专业优化软件优化过电脑。
=============
于是开始我在GOOGLE及BAIDU上漫游这个故障,发现有很多的用户遇到这个问题,他们的解决方法只有一个:就是重做系统!!别无它法~~~
=============
重做系统来解决肯定是下下策。我试着打开AUTOIT自己的udf:
ServiceControl.au3
位于:D:\autoit3\UserInclude\ServiceControl.au3

打开522行: Local $Service = ObjGet("winmgmts:\\" & $Computer & "\root\cimv2")
原来是依赖系统服务:WMI,回到故障系统里看看他的:winmgmt服务状态:





原用是禁用,我晕,敢紧启用。再回去运行程序,电脑一切OK!至此故障解决
在此,希望那些优化程序,精简版系统,别精简过度了,winmgmt服务是微软默认开启的哦,呵呵。。

当然,到此,不能说这样一台台手工去解决这个问题,咱们要通过程序的方式来解决那肯定最妙!!彻底解放我们的双手。

其实解决方法可以这样写:

#include <ServiceControl.au3>
#include <Process.au3>
_RunDos("sc config winmgmt start= AUTO")
_SetService("seclogon",1) ;若要禁用服务请使用:_SetService("seclogon",2)
Select
Case @error=5
MsgBox(64,"","成功将此服务设为自动并启动")
Case @error=6
MsgBox(16,"","成功禁用此服务!")
Case @error=7
MsgBox(16,"","没有此服务名,请确认!")
EndSelect

Func _SetService($ServiceName,$testservice=1)
If $testservice = '' Then $testservice = 1
$Servicecheck = _ServGetDetails($ServiceName) ;查这个服务的详情
If @error <> -1 Then
If $testservice=1 Then
If $Servicecheck[16]<>"Auto" Then _SerSetState($ServiceName,1)
If $Servicecheck[4]<>"Running" Then _ServStart($ServiceName)
Return SetError(5)
EndIf

If $testservice=2 Then
If $Servicecheck[4]="Running" Then _ServStop($ServiceName)
If $Servicecheck[16]="Auto" Then _SerSetState($ServiceName,3)
Return SetError(6)
EndIf
Else
Return SetError(7)
EndIf
EndFunc

当然,你若只是不要弹这个错误窗口出来,那也可以在ServiceControl.au3的522行下边加一句:

if @error then exit
即可。
最后的最后。还是希望autoit的开发者们,汉化工作者们,再辛苦完善一下就更好了。
当然喜欢研究及喜爱AUTOIT的朋友,通过这些经历完全可以增长我们驾驭AUTOIT的能力。

本文试验环境基于的autoit版本是:
3.3.5.6 第一汉化版(2010-03-04)
http://autoit-cn.googlecode.com/files/AUTOIT_3.3.5.6.exe
我的操作系统:WINXP SP3
谢谢大家。欢迎大家多多指教。
BY http://boyhong.blog.51cto.com/
2010.4.13 11:00更新:
如上改进后,很有效果,但仍还有那么零散几个用户执行以上改进后的脚本还是报上边的那个错误.狂汗!!!!!!!
仔细查看了这几个零散用户电脑,发现:
问题1:
winmgmt服务可以正常地手工开启与关闭,看不出问题所在。但是:



点击依存关系选项卡,报错:“WMI: 找不到”

问题2:
我发现这几个用户电脑的本地连接的高级选项卡有个共性:



“Windows 不能显示此连接的属性。Windows Management Instrumentation (WMI) 信息可能损坏。要更正此问题,请使用系统还原来将 Windows 还原到一个较早的时间点(称为还原点)。系统还原在“附件”中的“系统工具”文件夹中。”

经过一翻在网络上的查找,可以用本文附件中的批处理来解决之,经测试很有效。

以上脚本例子再次改进修复之,就OK了:

#include <ServiceControl.au3>
#include <Process.au3>
_RunDos("sc config winmgmt start= AUTO")
Local $Servicetestxf = ObjGet("winmgmts:\\.\root\cimv2")
if @error then
Msgbox (16,"WMI组件错误","检测到您的系统关键WMI组件错误,错误代码: " & hex(@error,8),5)
FileInstall("wmi.bat",@ScriptDir&"\wmi.bat",1)
ShellExecuteWait(@ScriptDir&"\wmi.bat") ;核心修复
_RunDos("sc config winmgmt start= AUTO")
EndIf

_SetService("seclogon",1) ;若要禁用服务请使用:_SetService("seclogon",2)
Select
Case @error=5
MsgBox(64,"by boyhong.blog.51cto.com","成功将此服务设为自动并启动")
Case @error=6
MsgBox(16,"by boyhong.blog.51cto.com","成功禁用此服务!")
Case @error=7
MsgBox(16,"boyhong.blog.51cto.com","没有此服务名,请确认!")
EndSelect

Func _SetService($ServiceName,$testservice=1)
If $testservice = '' Then $testservice = 1
$Servicecheck = _ServGetDetails($ServiceName) ;查这个服务的详情
If @error <> -1 Then
If $testservice=1 Then
If $Servicecheck[16]<>"Auto" Then _SerSetState($ServiceName,1)
If $Servicecheck[4]<>"Running" Then _ServStart($ServiceName)
Return SetError(5)
EndIf

If $testservice=2 Then
If $Servicecheck[4]="Running" Then _ServStop($ServiceName)
If $Servicecheck[16]="Auto" Then _SerSetState($ServiceName,3)
Return SetError(6)
EndIf
Else
Return SetError(7)
EndIf
EndFunc

以上脚本部分提到的: wmi.bat 请从本文附件中下载得到.
若您有更好的方法,望得到您的指点.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐