2012-01-31 15 views
3

コンピュータ上の特定のファイルを探して削除しようとしています。VBSスクリプトファイルの検索と削除

これは私のコードです:

Const DeleteReadOnly = True 

Set oFSO = CreateObject("Scripting.FileSystemObject") 
Set oWshShell = CreateObject("WScript.Shell") 
sDir = oWshShell.ExpandEnvironmentStrings("%temp%\dir.txt") 
sFileName = "\date.vbs" 

If oFSO.FileExists(sDir) Then oFSO.DeleteFile(sDir) 

For Each oDrive In oFSO.Drives 
if oDrive.DriveType = 2 Then Search oDrive.DriveLetter 
Next 

Set oFile = oFSO.OpenTextFile(sDir, 1) 
aNames = Split(oFile.ReadAll, VbCrLf) 
oFile.Close 
For Each sName In aNames 
If InStr(1, sName, sFileName, 1) > 0 Then WScript.Echo sName 
Next 

dim filesys 
Set filesys = CreateObject("Scripting.FileSystemObject") 
filesys.CreateTextFile "\date.vbs", True 
If filesys.FileExists("\date.vbs") Then 
filesys.DeleteFile "\date.vbs" 
Wscript.Echo("File deleted") 
End If 


Sub Search(sDrive) 
WScript.Echo "Scanning drive " & sDrive & ":" 
oWshShell.Run "cmd /c dir /s /b " & sDrive & ":\" & sName & " >>" & sDir, 0, True 
End Sub 

コードは部分的にしか働いています。ファイル "date.vbs"がルートフォルダ(C:\ date.vbs)にある場合は削除されますが、フォルダ(C:\ backup \ date.vbs)にある場合は削除されません。ルートにはないがコンピュータのどこにいてもファイルを削除できるようにするコードの変更を知っていますか?

ありがとうございました! V.

更新:

コードは現在かなり機能しています。私はちょうどファイルを削除する最終的な問題があります。私は属性をRead-onlyからNormalに変更できますが、依然としてアクセス拒否のエラーが出ます。

これは私のコードです:

Const DeleteReadOnly = True 
Dim oFSO, oDrive, sFileName, ws, WshS, fso, usrProfile, oFolder, skypefolder 

Set oFSO = CreateObject("Scripting.FileSystemObject") 
sFileName = "Skype.exe" 

Set WshS = WScript.CreateObject("WScript.Shell") 
usrProfile = WshS.ExpandEnvironmentStrings("%UserProfile%") 
skypefolder = "C:\Program Files (x86)\Skype\" 

For Each oDrive In oFSO.Drives 
    If oDrive.DriveType = 2 Then Recurse oFSO.GetFolder(skypefolder) 
Next 

Sub Recurse(oFolder) 
    Set oFile = CreateObject("Scripting.FileSystemObject") 
    Dim oSubFolder, oFile 

    If IsAccessible(oFolder) Then 
    For Each oSubFolder In oFolder.SubFolders 
    Recurse oSubFolder 
    Next 
    WScript.Echo oFolder.Path 

    For Each oFile In oFolder.Files 
     If oFile.Name = sFileName And oFile.Attributes And 1 Then 
     oFile.Attributes = 0 
     oFile.Delete True 

     End If 
     Next 
    End If 
End Sub 

Function IsAccessible(oFolder) 
    On Error Resume Next 
    IsAccessible = oFolder.SubFolders.Count >= 0 
End Function 

は助けてくれてありがとう!

コードスクリプトをADMINとして実行するために使用します。その後、MessageBoxが表示され始めました。それがコンソールで実行される前に。

If WScript.Arguments.Named.Exists("elevated") = False Then 

    CreateObject("Shell.Application").ShellExecute "wscript.exe", """" &  WScript.ScriptFullName & """ /elevated", "", "runas", 1 
    WScript.Quit 
Else 

    Set oShell = CreateObject("WScript.Shell") 
    oShell.CurrentDirectory =  CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) 
    'WScript.Echo("Now running with elevated permissions") 

End If 

このコードには何か問題があると思います。

+1

一般的な注意点:コードを正しくインデントしてください。 – Tomalak

答えて

4

あなたのアプローチは非常に複雑です。簡単な再帰関数を使用します。

Option Explicit 

Const DeleteReadOnly = True 
Dim oFSO, oDrive, sFileName 

Set oFSO = CreateObject("Scripting.FileSystemObject") 
sFileName = "date.vbs" 

For Each oDrive In oFSO.Drives 
    If oDrive.DriveType = 2 Then Recurse oDrive.RootFolder 
Next 

Sub Recurse(oFolder) 
    Dim oSubFolder, oFile 

    If IsAccessible(oFolder) Then 
    For Each oSubFolder In oFolder.SubFolders 
    Recurse oSubFolder 
    Next 

    For Each oFile In oFolder.Files 
     If oFile.Name = sFileName Then 
     'oFile.Delete ' or whatever 
     End If 
    Next 
    End If 
End Sub 

Function IsAccessible(oFolder) 
    On Error Resume Next 
    IsAccessible = oFolder.SubFolders.Count >= 0 
End Function 

は、大文字と小文字を区別しないファイル名の比較を実現するには、練習として

If StrComp(oFile.Name, sFileName, vbTextCompare) = 0 Then 
+0

ありがとう、私は何かが起こっていることを知っていたので、スキャンの部分が好きだった。どうすれば削除を実装できますか?どの構文を試してもうまくいきません。私はoFile.Delete(sFileName)を試しました。ファイル名としてファイルの名前を使用しましたが、それでもエラーを返します。 – Vojtech

+0

@Vojtech 'oFile.Delete'はうまくいくはずです。何が起こっているのか見たい場合は、 'IsAccessible()'チェックの直前に 'WScript.Echo oFolder.Path'を追加してください。コマンドラインで 'cscript.exe yourscript.vbs'を使ってスクリプトを実行する必要があります。そうでない場合(つまり、ダブルクリックで起動する場合)、各フォルダごとに1つのMessageBoxが生成されます。 – Tomalak

3

を使用することができます:あなたはまた、特定のファイルを見つけるために、WMIサービスを使用することができます。あなたは、あなただけの任意のフォルダに、任意のドライブ上のファイルを照会し、すべてのフォルダを通過する必要はありません。

Function find_file(filename) 

    Dim objWMIService, colItems, objItem, strComputer 
    strComputer = "." 

    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
    Set colItems = objWMIService.ExecQuery("SELECT * FROM CIM_DataFile WHERE FileName='" & filename & "'",,48) 

    For Each objItem in colItems 
     msgbox "Found " & objItem.Name & " in " objItem.Path 
    Next 

End Function 

注:関数はその結果を返した前にそれは長い時間がかかることができます。

+0

+1、非常に良い。パフォーマンスのための2つのソリューションを比較するために気をつけますか? :) – Tomalak

+0

WMIソリューションの所要時間は0.4秒、再帰的な検索には12秒かかりました。パフォーマンスはC:ドライブでのみ測定されました。 – AutomatedChaos

+0

興味深い。私はWMIの方が速いと考えましたが、その差は驚くべきものです。 Windowsファイルシステムのキャッシュ効果を補うために複数回実行しましたか? – Tomalak

関連する問題