0

インターンシップの宿題をしなければならないのですが、条件付きが機能しない理由がわかりません。VBscript を使用して一部を除くすべての Windows サービスを取得し、テキスト ファイルに書き込もうとしています。私はプログラミングの経験がなく、ここで途方に暮れていますが。このコードのどこが間違っているのか理解できますか:

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
4

3 に答える 3

2

さて、あなたが見逃したことを説明する2つの非常に詳細な回答があります。@Ekkehard.Horner が提案するように使用Dictionaryすることは、比較する値のリストが大きいため、この場合最も最適化された方法である必要があります。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
于 2013-02-25T16:43:16.183 に答える
2

より構造化された方法でこのような問題に対処するには:

(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) 「自然な」方法で選択/スキップの問題に取り組みます (If ... Else ... End If):

  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"

挿入ポイントに挿入すると、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」というランタイム エラーが発生します。.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
...
于 2013-02-24T15:10:56.667 に答える
1

まず、文字列自体は条件ではありません。文字列を繰り返す代わりに、条件を繰り返します。条件は、=両側に変数を持つ演算子で構成されます。条件の例はanswer = 42.

次に、オブジェクトを文字列と比較しています。Ekkehard Horner がコメントしているように、おそらくオブジェクトのDisplayNameプロパティを比較する必要がありobjServiceます。

第 3 に、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 _
于 2013-02-24T14:10:48.253 に答える