VBscript有条件的每个
我必须为我的实习做一个任务,我无法弄清楚为什么条件将无法正常工作。 我试图让所有的windowsservices除了一些VBscript,并将其写入到文本文件。虽然我没有编程经验,但我在这里不知所措。你们能找出这段代码有什么问题:VBscript有条件的每个
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
("D:\Beheer\Scripts\Services\Services_For_this_server.txt", ForAppending, True)
Set colServices = GetObject("winmgmts:").ExecQuery _
("Select * from Win32_Service")
For Each objService in colServices
If objService = "Human Interface Device Access" OR
"Health Key and Certificate Management" OR
"IKE and AuthIP IPsec Keying Modules" OR
"PnP-X IP Bus Enumerator" OR
"IP Helper" OR
"CNG Key Isolation" OR
"KtmRm for Distributed Transaction Coordinator" OR
"Server" OR
"Workstation" OR
"Link-Layer Topology Discovery Mapper" OR
"TCP/IP NetBIOS Helper" OR
"Multimedia Class Scheduler" OR
"Windows Firewall" OR
"Distributed Transaction Coordinator" OR
"Microsoft iSCSI Initiator Service" OR
"Windows Installer" OR
"Network Access Protection Agent" OR
"Netlogon" OR
"Network Connections" OR
"Network List Service" OR
"Network Location Awareness" OR
"Network Store Interface Service" OR
"Performance Counter DLL Host" OR
"Performance Logs & Alerts" OR
"Plug and Play" OR
"IPsec Policy Agent" OR
"Power" OR
"User Profile Service" OR
"Protected Storage" OR
"Remote Access Auto Connection Manager" OR
"Remote Access Connection Manager" OR
"Routing and Remote Access" OR
"Remote Registry" OR
"RPC Endpoint Mapper" OR
"Remote Procedure Call (RPC) Locator" OR
"Remote Procedure Call (RPC)" OR
"Resultant Set of Policy Provider" OR
"Special Administration Console Helper" OR
"Security Accounts Manager" OR
"Smart Card" OR
"Task Scheduler" OR
"Smart Card Removal Policy" OR
"Secondary Logon" OR
"System Event Notification Service" OR
"Remote Desktop Configuration" OR
"Internet Connection Sharing (ICS)" OR
"Shell Hardware Detection" OR
"SNMP Trap" OR
"Print Spooler" OR
"Software Protection" OR
"SPP Notification Service" OR
"SSDP Discovery" OR
"Secure Socket Tunneling Protocol Service" OR
"Microsoft Software Shadow Copy Provider" OR
"Telephony"
THEN ""
ELSE
objTextFile.WriteLine(objService.DisplayName)
Next
objTextFile.Close
首先,一个字符串本身并不是一个条件。重复字符串,而不是重复条件。该条件由一个带有变量的=
运算符组成。示例条件是answer = 42
。
其次,你正在比较一个对象与一个字符串。正如Ekkehard Horner所评论的,您应该比较objService
对象的DisplayName
属性。
第三,在VBScript中,跨越多行的语句(如if
)需要在除最后一行之外的所有行末尾加下划线(_
)。
因此改变:
If objService = "Human Interface Device Access" OR
"Health Key and Certificate Management" OR
要:
If objService.DisplayName = "Human Interface Device Access" OR _
objService.DisplayName = "Health Key and Certificate Management" OR _
-0.49您无法将objServerice与字符串进行比较,必须使用objServerice.DisplayName。 – 2013-02-24 14:21:02
抱歉是一个有害生物,但现在'_'(请继续行标记)在'OR's后出现。 (+1;感谢您的改进)。 – 2013-02-24 14:31:46
@ Ekkehard.Horner:你说得对。当你试图运行它时,解析器必须提示这一点。 – Andomar 2013-02-24 14:56:13
为了应对这样的问题,以更加结构化的方式:
(1)先从最简单的脚本(列表中的所有服务):
Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
Dim n : n = 0
Dim objService
For Each objService in colServices
WScript.Echo n, objService.DisplayName
n = n + 1
Next
输出:
0 Adobe Flash Player Update Service
1 Alerter
2 Application Layer Gateway Service
3 Application Management
4 ASP.NET State Service
5 Windows Audio
6 Background Intelligent Transfer Service
...
105 Automatic Updates
106 Wireless Zero Configuration
107 Network Provisioning Service
(2)将输出重定向到临时文件中(以供进一步参考;见步骤(5)所示)
(3)应对选择/ '自然' 的方式跳到问题(如果...否则...结束如果):
Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
Dim n : n = 0
Dim objService
For Each objService in colServices
Dim sSkipped : sSkipped = Space(7)
[insertion point]
WScript.Echo n, sSkipped, objService.DisplayName
n = n + 1
Next
如果你把
If objService = "Alerter" Then sSkipped = "skipped"
进入插入点,您会收到一个'Object does not support this property or method'runtime error。使用.DisplayName在
If objService.DisplayName = "Alerter" Then sSkipped = "skipped"
'作品':
0 Adobe Flash Player Update Service
1 skipped Alerter
2 Application Layer Gateway Service
3 Application Management
然后尝试:
If objService.DisplayName = "Alerter" Or
objService.DisplayName = "Application Management" Then sSkipped = "skipped"
挑起语法错误,并
If objService.DisplayName = "Alerter" Or _
objService.DisplayName = "Application Management" Then sSkipped = "skipped"
输出:
0 Adobe Flash Player Update Service
1 skipped Alerter
2 Application Layer Gateway Service
3 skipped Application Management
4 ASP.NET State Service
...
使其“工作”。
(4)原则上解决了这个问题,您可以考虑解决方案的缺陷和可能的增强/改进。以长连接顺序编辑Or
条款是非常麻烦的;一个标准的出路/周围正在使用的字典:
Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
Dim dicSkip : Set dicSkip = CreateObject("Scripting.Dictionary")
dicSkip("Alerter" ) = Empty
dicSkip("Application Management") = Empty
WScript.Echo "planning to skip:", Join(dicSkip.Keys(), ", ")
Dim n : n = 0
Dim objService
For Each objService in colServices
Dim sSkipped : sSkipped = Space(7)
If dicSkip.Exists(objService.DisplayName) Then sSkipped = "skipped"
WScript.Echo n, sSkipped, objService.DisplayName
n = n + 1
Next
现在,一个易于维护的数据结构
dicSkip("Alerter" ) = Empty
dicSkip("Application Management") = Empty
取代了更复杂的控制结构。 (5)甚至可以使用完整列表(步骤2)的转储和一些编辑器宏创建dicSkip(..) = Empty
行的完整序列,并通过注释输入/输出来禁用当前选择。这样可以避免因拼写错误导致的意外。
更新:
type servicedump.vbs
Option Explicit
Const sOutFSpec = ".\servicedump.txt"
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
Dim oOutFile : Set oOutFile = goFS.CreateTextFile(sOutFSpec, True)
Dim colServices : Set colServices = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service")
Dim dicSkip : Set dicSkip = CreateObject("Scripting.Dictionary")
dicSkip("Alerter" ) = Empty
dicSkip("Application Management") = Empty
Dim objService
For Each objService in colServices
If Not dicSkip.Exists(objService.DisplayName) Then oOutFile.WriteLine objService.DisplayName
Next
oOutFile.Close
cscript servicedump.vbs
type servicedump.txt
Adobe Flash Player Update Service
Application Layer Gateway Service
ASP.NET State Service
Windows Audio
...
这可能是一个好主意,使字典中的键不区分大小写:'dicSkip.CompareMode = vbTextCompare' – 2013-02-24 17:30:06
感谢您的详细解释。这种方法唯一的问题是,它不会将生成的输出结果放到一个.txt文件中,我需要这样做。 – user2104534 2013-02-25 10:28:18
@ user2104534 - 你在拉我的腿吗? (a)写入文件是在您发布的代码中实现的。 (b)步骤(2)显示免费获得文件输出。 – 2013-02-25 11:37:32
好了,你这里有2好,非常详细的解答,说明你错过了什么。使用Dictionary
作为@ Ekkehard.Horner建议在这种情况下应该是最优化的方式,因为您有大量要比较的值。但也可以尝试Select Case
,就像其他类似任务的替代方案一样。在Select Case
你可以使用值的逗号分隔的列表,例如:
'instead of...
For obj In Collection
If obj.property = "X" Or _
obj.property = "Y" Or _
obj.property = "Z" Then
'...
Else
'...
Next
'you can...
For obj In Collection
Select Case obj.property
Case "X", "Y", "Z"
'skip (or whatever)
Case Else
'write (or whatever)
End Select
Next
+1 - 当'IF'导致问题时,查看'选择案例'。 – 2013-02-25 16:49:43
你要什么发生,以及以何种方式它“不工作”? – 2013-02-24 14:23:09