表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

2/2

[VBS]ショートカットファイルの検索

ショートカットファイルを検索し、

参照先を記録する。

リンクが切れていないか調査のために使用してみては?

Option Explicit


'**************************************************************************************************

' 定数宣言

'**************************************************************************************************

Const LOG_FILE_PREFIX = "SearchShortCutFile_vbs_"

Const SHORTCUT_EXT = "lnk"


' ショートカットリンク先判定ステータス

Const SHORTCUT_STATUS_FILE = "ファイル"

Const SHORTCUT_STATUS_FOLDER = "フォルダ"

Const SHORTCUT_STATUS_WORKINGDIR_ONLY = "作業ディレクトリのみ" ' TargetPathがなくWorkingDirectoryのみが有効な場合

Const SHORTCUT_STATUS_BROKEN = "リンク切れ"


' 取得時のエラータイプ

Const SHORTCUT_ERROR_CREATE_OBJECT = "オブジェクト作成エラー" ' WshShortcutオブジェクトの作成失敗

Const SHORTCUT_ERROR_GET_TARGETPATH = "ターゲットパス取得エラー" ' TargetPath取得失敗

Const SHORTCUT_ERROR_GET_WORKINGDIR = "作業ディレクトリ取得エラー" ' WorkingDirectory取得失敗

Const SHORTCUT_ERROR_UNKNOWN = "不明なエラー" ' その他の取得失敗


' ログファイルヘッダー

Const LOG_HEADER = "No." & vbTab & _

"リンク先判定" & vbTab & _

"最終更新日時" & vbTab & _

"ファイルサイズ(バイト)" & vbTab & _

"ファイル名" & vbTab & _

"フォルダパス" & vbTab & _

"ショートカットリンク先パス" & vbTab & _

"エラー詳細"


' FileSystemObjectのOpenFileメソッド用モード定数

Const FSO_APPENDING = 8 ' テキストファイルへの追記モード


' FileSystemObjectのOpenFileメソッド用フォーマット定数 (TRISTATE_UNICODEを推奨)

Const TRISTATE_UNICODE = -1 ' Unicode (日本語環境での文字化け防止のため推奨)


'**************************************************************************************************

' メイン処理のエントリーポイント

'**************************************************************************************************

Call Main


'**************************************************************************************************

' Mainサブルーチン

' 機能: スクリプトの主要な処理フローを制御します。

' ショートカットファイルの検索、ログへの出力、処理時間の表示を行います。

' 引数: なし

' 戻り値: なし

' 備考: このスクリプトが置かれたフォルダ配下を対象とします。

' ログファイルも、このスクリプトと同じフォルダに作成されます。

'**************************************************************************************************

Sub Main()

' ローカル変数としてオブジェクトを宣言

Dim fso As Object

Dim wsh As Object

Dim intRecordCount As Long ' 処理されたショートカットファイルのカウント

Dim dteStartTime As Date ' 処理開始時刻

Dim dteEndTime As Date ' 処理終了時刻

Dim strLogFilePath As String ' ログファイルのフルパス

Dim objRootFolder As Object


' オブジェクトの初期化

Set fso = CreateObject("Scripting.FileSystemObject")

Set wsh = CreateObject("WScript.Shell")


' 処理開始時刻の記録

dteStartTime = Now()

' ショートカットファイル数の初期化

intRecordCount = 0


' ログファイルパスを生成

strLogFilePath = fso.BuildPath(fso.GetParentFolderName(WScript.ScriptFullName), _

LOG_FILE_PREFIX & wsh.ComputerName & "_" & _

FormatDateForLog(Now()) & ".log")


' ログファイルのヘッダーを書き込みます。

Call F_LogWrite(fso, strLogFilePath, "処理開始: " & FormatDateTime(dteStartTime, vbGeneralDate) & vbCrLf & LOG_HEADER)


' 現在のスクリプトがあるフォルダの取得

On Error Resume Next ' GetFolderでエラーが発生する可能性に備える

Set objRootFolder = fso.GetFolder(fso.GetParentFolderName(WScript.ScriptFullName))

If Err.Number <> 0 Then

' エラー発生時はログに記録し、ユーザーに通知して終了

Call F_LogWrite(fso, strLogFilePath, "エラー: スクリプト実行フォルダの取得に失敗しました。パス: '" & fso.GetParentFolderName(WScript.ScriptFullName) & _

"', エラーコード: " & Err.Number & ", エラー詳細: " & Err.Description)

WScript.Echo "重大なエラー: スクリプト実行フォルダの取得に失敗しました。スクリプトを終了します。"

WScript.Quit 1

End If

On Error GoTo 0 ' エラーハンドリングを元に戻す


' ショートカットファイルの検索と処理を開始

Call F_FindShortcutsInFolder(objRootFolder, fso, wsh, intRecordCount, strLogFilePath)


' 処理終了時刻の記録

dteEndTime = Now()


' 処理時間の計算と整形

Dim strDuration As String

strDuration = F_FormatDuration(dteStartTime, dteEndTime)


' ログファイルに処理終了情報と処理時間を書き込みます。

Call F_LogWrite(fso, strLogFilePath, "処理終了: " & FormatDateTime(dteEndTime, vbGeneralDate) & vbTab & _

"処理時間: " & strDuration & vbCrLf & _

"処理件数: " & intRecordCount)


' オブジェクトの解放

Set fso = Nothing

Set wsh = Nothing


' 処理結果をユーザーに通知

WScript.Echo "処理が完了しました!" & vbCrLf & _

"開始時刻: " & FormatDateTime(dteStartTime, vbGeneralDate) & vbCrLf & _

"終了時刻: " & FormatDateTime(dteEndTime, vbGeneralDate) & vbCrLf & _

"処理時間: " & strDuration & vbCrLf & _

"処理件数: " & intRecordCount & vbCrLf & _

"ログファイル: " & strLogFilePath


End Sub


'**************************************************************************************************

' F_FindShortcutsInFolderサブルーチン

' 機能: 指定されたフォルダとそのサブフォルダ内のショートカットファイルを再帰的に検索し、

' その情報をログに出力します。

' 引数: objCurrentFolder (Object) - 検索対象のフォルダオブジェクト

' fso (Object) - FileSystemObjectのインスタンス

' wsh (Object) - WshShellオブジェクトのインスタンス

' intRecordCount (Long) - 処理されたショートカットファイルのカウント (ByRefで更新)

' strLogFilePath (String) - ログファイルのパス

' 戻り値: なし

'**************************************************************************************************

Function F_FindShortcutsInFolder(ByVal objCurrentFolder As Object, _

ByVal fso As Object, _

ByVal wsh As Object, _

ByRef intRecordCount As Long, _

ByVal strLogFilePath As String)


Dim objFile As Object ' ファイルを格納する変数

Dim objSubFolder As Object ' サブフォルダを格納する変数


' 現在のフォルダ内のファイルを処理します。

For Each objFile In objCurrentFolder.Files

If LCase(fso.GetExtensionName(objFile.Name)) = SHORTCUT_EXT Then

intRecordCount = intRecordCount + 1

' ショートカットファイルの処理を別関数に委譲 (必要なオブジェクトとカウンタを渡す)

Call F_ProcessShortcutFile(objFile, fso, wsh, intRecordCount, strLogFilePath)

End If

Next


' 現在のフォルダ内のサブフォルダを再帰的に処理します。

For Each objSubFolder In objCurrentFolder.SubFolders

On Error Resume Next ' サブフォルダアクセス中にエラーが発生する可能性に備える

' 再帰呼び出し (必要なオブジェクトとカウンタを渡す)

Call F_FindShortcutsInFolder(objSubFolder, fso, wsh, intRecordCount, strLogFilePath)

If Err.Number <> 0 Then

' エラー発生時はログに記録し、エラーをクリアして続行

Call F_LogWrite(fso, strLogFilePath, FormatDateTime(Now(), vbGeneralDate) & vbTab & _

"エラー: サブフォルダアクセス中にエラー発生。パス: '" & objSubFolder.Path & _

"', エラーコード: " & Err.Number & ", エラー詳細: " & Err.Description)

Err.Clear ' エラーをクリアして次のサブフォルダの処理を続行

End If

On Error GoTo 0 ' エラーハンドリングを元に戻す

Next

End Function


'**************************************************************************************************

' F_ProcessShortcutFileサブルーチン

' 機能: 個々のショートカットファイルの詳細情報を取得し、ログに出力します。

' 引数: objShortcutFile (Object) - ショートカットファイルのファイルオブジェクト

' fso (Object) - FileSystemObjectのインスタンス

' wsh (Object) - WshShellオブジェクトのインスタンス

' intRecordCount (Long) - 処理されたショートカットファイルのカウント (ログ出力用)

' strLogFilePath (String) - ログファイルのパス

' 戻り値: なし

'**************************************************************************************************

Function F_ProcessShortcutFile(ByVal objShortcutFile As Object, _

ByVal fso As Object, _

ByVal wsh As Object, _

ByVal intRecordCount As Long, _

ByVal strLogFilePath As String)


Dim objShortcut As Object ' WshShortcutオブジェクト

Dim strShortcutTargetPath As String ' ショートカットのリンク先パス

Dim strLinkStatus As String ' リンク先の状態(ファイル、フォルダ、リンク切れ、エラーなど)

Dim strErrorDetail As String ' エラー詳細メッセージ


strShortcutTargetPath = ""

strLinkStatus = ""

strErrorDetail = ""


On Error Resume Next ' ショートカットオブジェクト作成中のエラーを捕捉

Set objShortcut = wsh.CreateShortcut(objShortcutFile.Path)


If Err.Number <> 0 Then

strLinkStatus = SHORTCUT_ERROR_CREATE_OBJECT

strErrorDetail = "WshShortcutオブジェクトの作成に失敗しました: " & Err.Description

Err.Clear

Else

' TargetPathの取得を試みる

Dim tempTargetPath As String

On Error Resume Next ' TargetPath取得中のエラーを捕捉

tempTargetPath = objShortcut.TargetPath

If Err.Number <> 0 Then

strLinkStatus = SHORTCUT_ERROR_GET_TARGETPATH

strErrorDetail = "TargetPathの取得に失敗しました: " & Err.Description

Err.Clear

Else

strShortcutTargetPath = tempTargetPath

End If

On Error GoTo 0 ' エラーハンドリングを元に戻す


' TargetPathが空の場合、WorkingDirectoryを試す

If strShortcutTargetPath = "" Then

Dim tempWorkingDir As String

On Error Resume Next ' WorkingDirectory取得中のエラーを捕捉

tempWorkingDir = objShortcut.WorkingDirectory

If Err.Number <> 0 Then

If strLinkStatus = "" Then ' TargetPath取得エラーでなければ

strLinkStatus = SHORTCUT_ERROR_GET_WORKINGDIR

End If

strErrorDetail = strErrorDetail & IIf(strErrorDetail = "", "", " / ") & "WorkingDirectoryの取得に失敗しました: " & Err.Description

Err.Clear

Else

If tempWorkingDir <> "" Then

strShortcutTargetPath = tempWorkingDir ' 作業ディレクトリをリンク先として記録

If strLinkStatus = "" Then ' エラーがまだ記録されていなければ

strLinkStatus = SHORTCUT_STATUS_WORKINGDIR_ONLY

End If

End If

End If

On Error GoTo 0 ' エラーハンドリングを元に戻す

End If


' 取得したパスに基づいてリンク先を判定 (エラーが発生していない場合のみ)

If strLinkStatus = "" Then

If fso.FileExists(strShortcutTargetPath) Then

strLinkStatus = SHORTCUT_STATUS_FILE

ElseIf fso.FolderExists(strShortcutTargetPath) Then

strLinkStatus = SHORTCUT_STATUS_FOLDER

ElseIf strShortcutTargetPath = "" Then ' TargetPathもWorkingDirectoryも空の場合

strLinkStatus = SHORTCUT_ERROR_UNKNOWN

strErrorDetail = "TargetPathもWorkingDirectoryも取得できませんでした。"

Else

strLinkStatus = SHORTCUT_STATUS_BROKEN

End If

End If

End If


' オブジェクトの解放

Set objShortcut = Nothing


' ログに出力する情報を整形します。

Dim strLogLine As String

strLogLine = Right("0000" & intRecordCount, 4) & vbTab & _

strLinkStatus & vbTab & _

FormatDateTime(objShortcutFile.DateLastModified, vbGeneralDate) & vbTab & _

objShortcutFile.Size & vbTab & _

objShortcutFile.Name & vbTab & _

objShortcutFile.ParentFolder & vbTab & _

strShortcutTargetPath & vbTab & _

strErrorDetail ' エラー詳細もログに出力


Call F_LogWrite(fso, strLogFilePath, strLogLine)

End Function


'**************************************************************************************************

' F_LogWriteサブルーチン

' 機能: 指定されたデータをログファイルに書き込みます。

' 引数: fso (Object) - FileSystemObjectのインスタンス

' strLogFilePath (String) - ログファイルのフルパス

' strData (String) - ログに書き込む文字列

' 戻り値: なし

' 備考: ログファイルが存在しない場合は新規作成し、存在する場合は追記します。

'**************************************************************************************************

Function F_LogWrite(ByVal fso As Object, ByVal strLogFilePath As String, ByVal strData As String)

Dim objFile As Object ' TextStreamオブジェクト


On Error Resume Next ' ファイルオープン中のエラーを捕捉


' ログファイルを開きます。新規作成 (True) および Unicode (TRISTATE_UNICODE) を指定

Set objFile = fso.OpenTextFile(strLogFilePath, FSO_APPENDING, True, TRISTATE_UNICODE)


If Err.Number <> 0 Then

' ログファイルへの書き込み自体に失敗した場合の最終手段

WScript.Echo "重大なエラー: ログファイルのオープンまたは書き込み中に問題が発生しました。" & vbCrLf & _

"エラーコード: " & Err.Number & ", エラー詳細: " & Err.Description & vbCrLf & _

"ログファイルパス: " & strLogFilePath & vbCrLf & _

"書き込みを試みたデータ: " & strData

WScript.Quit 1 ' スクリプトをエラー終了

Else

objFile.WriteLine (strData)

End If


objFile.Close

Set objFile = Nothing


On Error GoTo 0 ' エラーハンドリングを元に戻す

End Function


'**************************************************************************************************

' F_FormatDuration関数

' 機能: 開始時刻と終了時刻から処理時間を整形して返します。

' 引数: dteStart (Date) - 処理開始時刻

' dteEnd (Date) - 処理終了時刻

' 戻り値: String - 整形された処理時間文字列

'**************************************************************************************************

Function F_FormatDuration(ByVal dteStart As Date, ByVal dteEnd As Date) As String

Dim lngTotalSeconds As Long

lngTotalSeconds = DateDiff("s", dteStart, dteEnd)


Dim strDuration As String

If lngTotalSeconds < 60 Then

strDuration = lngTotalSeconds & "秒"

ElseIf lngTotalSeconds < 3600 Then

strDuration = Int(lngTotalSeconds / 60) & "分" & (lngTotalSeconds Mod 60) & "秒"

Else

strDuration = Int(lngTotalSeconds / 3600) & "時間" & _

Int((lngTotalSeconds Mod 3600) / 60) & "分" & _

(lngTotalSeconds Mod 60) & "秒"

End If

F_FormatDuration = strDuration

End Function


'**************************************************************************************************

' FormatDateForLog関数

' 機能: 日付をYYYYMMDD形式の文字列に整形して返します。

' 引数: dteDate (Date) - 整形する日付

' 戻り値: String - YYYYMMDD形式の文字列

'**************************************************************************************************

Function FormatDateForLog(ByVal dteDate As Date) As String

FormatDateForLog = Year(dteDate) & Right("0" & Month(dteDate), 2) & Right("0" & Day(dteDate), 2)

End Function

スクリプトの実行方法

このスクリプトは、元のスクリプトと同様にVBScriptとして実行できます。

* 上記のコードを SearchShortcut.vbs のような名前でファイルに保存します。

* このファイルをダブルクリックするか、コマンドプロンプトで cscript SearchShortcut.vbs を実行します。

スクリプトが実行されたフォルダに、SearchShortCutFile_vbs_コンピュータ名_YYYYMMDD.log という形式のログファイルが作成されます。


評価をするにはログインしてください。
この作品をシェア
Twitter LINEで送る
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ