Hey, Scripting Guy!

Hey, Scripting Guy!

TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

Hey, Scripting Guy! アーカイブも忘れずにチェックしてください。

今日の質問 : 現在ごみ箱にあるすべての項目のサイズを特定する方法はありますか


現在ごみ箱にあるすべての項目のサイズを特定する方法はありますか

Q

Scripting Guy さん、よろしくお願いします。現在ごみ箱にあるすべての項目のサイズを特定する方法はありますか。

-- T D-L

A

T D-L さん、こんにちは。ご存知ですか。Scripting Guys にその意思があれば、Recycle Bin Guys (ごみ箱ガイ) と改名していたかもしれないですよ。というのも、私たちのもとにはスクリプトとごみ箱についての質問がたくさん寄せられるからなのです。それで、なぜ改名しなかったのでしょうか。そうですね。1 つには、この余っている Scripting Guys T シャツをどう処分すればよいかわからないからです。それよりさらに重要かもしれませんが、ごみ箱についての質問にはあまり素晴らしい回答を提供することができないという事実があるためです。ファイルを完全に削除するのではなく、ごみ箱に送ることはできるでしょうか。できますが、依然として表示される "このファイルをごみ箱に移してもよろしいですか?" というプロンプトに答える必要があります。ごみ箱を空にする場合はどうでしょうか。同じことです。可能ですが、表示される "ごみ箱のファイルをすべて削除しますか?" というプロンプトには答える必要があります。とても洗練しているとはいえませんし、完全な自動化には程遠いですね。

でも、この質問にももちろん方法はあります。もう 1 度言いますが、絶対的な完全な解決策はありません。一例を挙げると、このスクリプトはローカル コンピュータ上でのみ機能します。ごみ箱に関する質問となると、この程度が限界です。

Const RECYCLE_BIN = &Ha& 
Const FILE_SIZE = 3 
 
Set objShell = CreateObject("Shell.Application") 
Set objFolder = objShell.Namespace(RECYCLE_BIN) 
 
Set colItems = objFolder.Items 
 
For Each objItem in colItems 
    strSize = objFolder.GetDetailsOf(objItem, FILE_SIZE) 
    arrSize = Split(strSize, " ") 
    intSize = intSize + CLng(arrSize(0)) 
Next 
 
Wscript.Echo intSize & " KB"

このスクリプトでは、まず 2 つの定数を定義しています。RECYCLE_BIN (16 進値 &Ha& が割り当てられる) を使用して、バインド対象の特別なフォルダをスクリプトに指示します。一方で、FILE_SIZE (値は 3) を使用して、取得するフォルダ項目のプロパティをスクリプトに指示します。この時点では納得がいかないかもしれませんが、もう少し見ていてください。後 1 〜 2 分ですべてクリアになるはずです。

これら 2 つの定数を使用して、Shell.Application オブジェクトのインスタンスを作成し、次に Namespace メソッドを使用してごみ箱にバインドします。その処理は次のコード部分で行われます。

Set objShell = CreateObject("Shell.Application") 
Set objFolder = objShell.Namespace(RECYCLE_BIN)

理想の世界では、ごみ箱に接続したら、"ねぇ、ごみ箱さん、現在のすべての項目の正確なサイズを教えてください" とたずねるだけです。残念ですが、実際は理想の世界のようにはいきません (理想の世界であれば、このコラムを書いている Scripting Guy は、ヤンキースのセンターフィールドでプレイしているでしょう)。[ごみ箱] フォルダの持つ特別な特性 (および Shell オブジェクトの持ついくつかの奇妙な点) のため、手動でサイズを計算しなければならないため、実行できるのはごみ箱の全項目を 1 つずつ加算していくことです。ただし、これを実行するには、現在ごみ箱にあるすべての項目のコレクションを取得する必要があります。これを行うのが次のコード行です。

Set colItems = objFolder.Items

コレクションを取得したら、For Each ループを設定してすべての項目 (つまり、ごみ箱の全項目) を順番に処理し、ファイル サイズを加算します。

For Each objItem in colItems

いつもなら、このあたりで "ここからは後は簡単です" というところですが、今回取り組んでいるのがごみ箱であることをどうぞお忘れなく。ごみ箱に関することで簡単なことなどまったくないのです。項目のコレクションを取得したら、GetDetailsOf メソッドを使用して、コレクションの各項目の個別のプロパティ値を取得できます。必要としているのがファイル サイズだけであるため (Shell オブジェクトに関しては、プロパティ値は 3 です)、コードの次の行によって、ごみ箱の各項目のファイル サイズを返すことができます (ちなみに、ごみ箱にはファイルだけでなくフォルダも含まれています)。

strSize = objFolder.GetDetailsOf(objItem, FILE_SIZE)

名目上は、うまく機能しているように思えます。しかし、ご推測のとおり、問題があるのです。ファイル サイズはすべて次の形式で返され、文字列の末尾に KB が付きます。

100 KB 
200 KB 
300 KB

これがなぜ問題なのでしょうか。では、100 KB + 200 KB + 300 KB を加算してみてください。問題点を理解できます (ヒント : "型の不一致" エラーが返されます。これは、文字列値をまとめて加算しようとしたためです)。

おわかり頂けましたか。これが Scripting Guy が Recycle Bin Guy にならなかったもう 1 つの理由です。ごみ箱の処理は本当にたいへんなのです。

運よく、各ファイル サイズの末尾に付けられた KB は簡単に対処できます。どうすればよいのでしょう。コードの次の行で、VBScript の Split 関数を使用して各ファイル サイズを配列に分割できます。

arrSize = Split(strSize, " ")

空白で区切ると、次の 2 つの項目で構成される配列になります。最初の項目 (インデックス番号 0) がファイル サイズで、2 番目の項目が文字列 KB です。たとえば、ファイル サイズが 100 KB の場合、配列 arrSize は以下の 2 つの項目で構成されます。

100

KB

ここからが、ようやく本題です。ファイル サイズが配列の最初の項目に安全に格納されたら、コードの次の行を使用して、ごみ箱内の全項目のサイズの集計を開始することができます。

intSize = intSize + CLng(arrSize(0))

ここでは、intSize という変数を使用して、すべての項目の合計サイズを追跡しています。コードのこの行では、現在 intSize にある値が何であれ配列の最初の項目の値 (ご存知のように、インデックス番号 0) と足して intSize に代入します。

たとえば、最初にループ処理を行うときには、intSize が 0 になります。最初のファイル サイズが 100 である場合は、intSize には次の値が代入されます。

0 + 100

2 回目にループ処理を行うときには、intSize が 100 になります。2 番目のファイル サイズが 200 である場合は、intSize には次の値が代入されます。

100 + 200

ごみ箱にこれら 2 つのファイルしかない場合、ごみ箱のサイズは 300 KB となり、For Each ループを終了した後このことがエコーされます。

ファイル サイズを処理するときになぜ CLng 関数を使用したかというのは良い質問です。そうですね、CLng 関数は変数を長整数型として "キャスト" するように作成されています。私たちは、VBScript がファイル サイズ (100 など) を文字列変数として処理するという事実を確認するためだけに、このスクリプトの最初の繰り返しから CLng を削除しました。すると、ごみ箱のサイズは次のように表示されました。

1,2407,6407,0125,20410,06423,204 KB

面白いですが、これは実際のサイズ 54364 KB とはまったく異なります。CLng 関数を使用することにより、VBScript に arrSize(0) を長整数型として処理するよう指示するだけでうまく機能したのです。

さぁ、これでバッティング センターに行けます。それに、ごみ箱を処理するスクリプトを書く方法がわかったので、Scripting Guy もヤンキースのセンターフィールドでプレイできるかもしれません。どうなったかについてはいずれお知らせします。


関連情報

Hey, Scripting Guy! - アーカイブもチェックしてください。

ページのトップへページのトップへ