【テクニカル・上級編】【ファイル属性制御】FileSystemObject の Attributes プロパティによる隠しファイル・読み取り専用属性の動的変更 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【ファイル属性制御】FileSystemObject の Attributes プロパティによる隠しファイル・読み取り専用属性の動的変更

レガシーシステムの裏側、あるいは企業の基幹を支えるバッチ処理の現場において、VBScript(Visual Basic Scripting Edition)とWSH(Windows Script Host)のコンビネーションは、いまだに不可欠なインフラストラクチャとして稼働し続けている。コンパイル不要、OS標準搭載、そして極限まで無駄を削ぎ落としたランタイム。この枯れた技術を真に掌握することは、シニアエンジニアやインフラ管理者にとっての必須教養である。

本稿では、`FileSystemObject`(以下、FSO)の `Attributes` プロパティに焦点を当て、ファイル属性(読み取り専用、隠しファイル等)の動的制御について、そのビット演算のメカニズムからオブジェクトのライフサイクル管理、さらには実務で直面するセキュリティと競合制御の極限の知見を解説する。

1. FSO `Attributes` プロパティの深層:ビットマスク演算の真実

FSOの `File.Attributes` プロパティが返す値は、単なる数値ではない。これは Windows API のファイル属性(`FILE_ATTRIBUTE_READONLY`, `FILE_ATTRIBUTE_HIDDEN` など)を内包したビットフィールド(BitField)そのものである。

VBScriptには C言語のようなシフト演算子(`<<`, `>>`)が存在しないため、属性の付与・剥奪には論理演算(Bitwise Operations)を駆使する必要がある。ここを理解していないエンジニアは、しばしば「既存の属性を上書きして消してしまう」という致命的なバグを引き起こす。

主要な属性定数とビット値

  • 読み取り専用 (Read-Only): `1` (&H1)
  • 隠しファイル (Hidden): `2` (&H2)
  • システムファイル (System): `4` (&H4)
  • アーカイブ (Archive): `32` (&H20)

属性付与の鉄則:論理和 (OR)

特定の属性を追加する場合、既存の属性値を破壊してはならない。必ず `OR` 演算を使用する。

属性解除の鉄則:否定と論理積 (AND NOT)

特定の属性だけを選択的に剥奪する場合、「対象ビット以外を全て1にし、対象ビットを0にする(Bitwise AND with NOT mask)」という操作が必要となる。

2. 実践:誤上書き防止と一時ファイルの不可視化を実装する

以下のコードは、重要設定ファイルの保護(読み取り専用の付与)と、処理中の一時ファイルの隠蔽(隠しファイル属性の付与・解除)を安全かつ堅牢に実装した実用スクリプトである。

Option Explicit

‘ ==============================================================================
‘ Script Name: FileAttributeController.vbs
‘ Description: FSOを用いたファイル属性の動的制御(読み取り専用・隠し属性)
‘ Author: Chief Architect
‘ ==============================================================================

Call Main()

Sub Main()
Dim fso, targetFile, tempFile
Dim targetPath, tempPath

targetPath = “C:\Config\app_settings.ini”
tempPath = “C:\Config\processing.tmp”

‘ 1. FileSystemObjectのインスタンス生成
Set fso = CreateObject(“Scripting.FileSystemObject”)

On Error Resume Next

‘ — 【シナリオA】重要設定ファイルに「読み取り専用」を付与する —
If fso.FileExists(targetPath) Then
Set targetFile = fso.GetFile(targetPath)

‘ 既存の属性に ReadOnly(&H1) を安全に追加(ビットOR演算)
‘ ※ 既存のHiddenやArchive属性を消去しないための配慮
If (targetFile.Attributes And 1) = 0 Then
targetFile.Attributes = targetFile.Attributes Or 1
WScript.Echo “[INFO] 誤上書き防止のため、ファイルを読み取り専用に設定しました: ” & targetPath
Else
WScript.Echo “[INFO] 対象ファイルは既に読み取り専用です: ” & targetPath
End If

Set targetFile = Nothing
Else
WScript.Echo “[WARNING] 対象ファイルが存在しません: ” & targetPath
End If

‘ — 【シナリオB】処理中の一時ファイルを「隠しファイル」として作成・制御 —
‘ ダミーの一時ファイルを作成
If fso.FileExists(tempPath) Then fso.DeleteFile tempPath, True
Set tempFile = fso.CreateTextFile(tempPath, True)
tempFile.WriteLine “Processing data…”
tempFile.Close
Set tempFile = Nothing

‘ 作成直後の一時ファイルに Hidden(&H2) 属性を付与してユーザーから不可視にする
Set tempFile = fso.GetFile(tempPath)
tempFile.Attributes = tempFile.Attributes Or 2
WScript.Echo “[INFO] 一時ファイルを隠し属性に変更しました: ” & tempPath

‘ — ここで重いバッチ処理や外部プロセス連携を実行する(模擬) —
WScript.Sleep 2000

‘ 処理完了後、クリーンアップのために隠し属性を解除して削除を許可する
‘ 解除のロジック: Attributes AND (NOT 2)
‘ VBScriptにはビット否定演算子がなため、XOR または数学的な引き算(対象が含まれている場合のみ引く)で処理する
If (tempFile.Attributes And 2) <> 0 Then
tempFile.Attributes = tempFile.Attributes Xor 2 ‘ ビット反転(XOR)による安全なトグル解除
WScript.Echo “[INFO] 一時ファイルの隠し属性を解除しました。”
End If

Set tempFile = Nothing

‘ 安全に削除
fso.DeleteFile tempPath, True
WScript.Echo “[INFO] 一時ファイルを正常に破棄しました。”

If Err.Number <> 0 Then
WScript.Echo “[ERROR] 予期せぬエラーが発生しました: ” & Err.Description
End If

On Error GoTo 0

‘ 2. オブジェクトの明示的解放(メモリ管理の極意)
Set fso = Nothing
End Sub

3. シニアエンジニアが知るべき「罠」とアーキテクチャの知見

オブジェクトのライフサイクルとメモリリークの防止

VBScriptのCOMコンポーネント(`Scripting.FileSystemObject` や生成される `File` オブジェクト)は、スクリプト終了時に自動解放されるが、長期間稼働する常駐型WSHや、ループ内で幾度もインスタンスを生成するバッチ処理においては、ガベージコレクションを待つのではなく、明示的に `Set xxx = Nothing` を記述すべきである。
特に `GetFile()` メソッドは内部でファイルハンドルの参照を保持する場合があるため、処理が終わったオブジェクトは速やかにスコープから切り捨てること。

ロック競合とWin32エラーへの対策

ファイル属性を変更するということは、OSのファイルシステムメタデータを更新する行為である。もし、他のプロセス(アンチウイルスソフト、ログ監視エージェント、別スレッドのバッチ)がそのファイルを開いている最中に `Attributes` 書き換えを行うと、「権限がありません (Permission denied)」「ファイルは別のプロセスで使用されています」 といったランタイムエラー(エラー番号 70 など)が容赦なく発生する。

本番環境に耐えうるコードを書くためには、以下のフェーズを必ず組み込むべきだ。
1. `On Error Resume Next` によるトラップの敷設
2. エラー発生時のリトライ機構(Exponential Backoff 等のリトライロジック)
3. 処理終了後の確実にファイルハンドルを解放するフロー

レガシー環境におけるセキュリティガバナンス

「重要な設定ファイルを読み取り専用にする」アプローチは、オペレーターのうっかりミス(誤削除・誤上書き)を防ぐための第一歩としては有効である。しかし、セキュリティの観点から言えば、NTFSアクセス権(ACL)の制御に勝るものはない。VBScriptからACLを直接細かく制御するのは煩雑であるため、cacls.exe や icacls.exe を `WshShell.Run` で叩くアプローチと、今回のFSOによる属性変更を、要件の機密性に応じて使い分けるのがプロフェッショナルな判断と言える。

総括

VBScriptは過去の遺物と揶揄されることもあるが、OSの根幹にダイレクトに触れ、数行のコードでシステムを意のままに動かすことができる類まれなツールである。
`Attributes` プロパティのビット演算という「泥臭いレイヤー」を完全に掌握したエンジニアこそが、堅牢で障害に強い真の自動化アーキテクチャを構築できる。本稿の知見が、あなたの現場のシステム信頼性を一段引き上げる一助となれば幸いである。

タイトルとURLをコピーしました