1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windowsでドキュメント(PDFや電子書籍も!)を対象にとにかく爆速で全文検索する方法

1
Last updated at Posted at 2026-02-23

目的・背景

PCで調べ物をしているとき、「今見ているこのキーワード、昔読んだPDFや電子書籍、あるいは過去のメモのどこかに書いてあったはず……」と思うことはありませんか?
Windows標準の検索機能では時間がかかったり、ファイルの中身までうまくヒットしなかったりしてストレスを感じることがあります。

そこで今回は、超高速検索ソフト「Everything」のテスト版(1.5 Alpha)の強力なコンテンツ検索機能と、AutoHotkeyを組み合わせて、「選択したテキストをショートカットキー一発でローカルのPDFやドキュメントから爆速で全文検索する」 環境を構築する方法をご紹介します。

なお、この記事はAIの支援で書いています。

使い方

設定が完了すると、以下のようなシームレスな検索が可能になります。

  1. 全文検索したい文字列を選択し、Alt + 右クリック すると、専用のメニューが表示されます。
    メニューの表示

    • 「Everythingでファイル名検索」: 選択した文字列をファイル名に含むファイルを検索します。
    • 「Everythingでファイル内容検索」: 選択した文字列をファイルの内容(中身)に含むファイルを検索します。(今回はこちらを選択)
  2. Everythingが即座に起動し、該当するファイルがリストアップされます。
    Everythingの検索結果

  3. 検索結果からファイルを開いてみると、キーワードがバッチリ含まれています!
    PDFリーダーで開いた結果

準備

この環境を作るためには、以下の3つのステップが必要です。

1. IFilterの導入

Everything自体はテキスト検索が非常に高速ですが、PDFやEPUBといった特殊なファイルの中身を解読するためには、Windows Searchの「IFilter(アイフィルター)」という翻訳機のような仕組みが必要です。

今回は、各種電子書籍フォーマット(PDF, EPUB, MOBIなど)にまとめて対応できる無料のIFilterパッケージを導入します。

以下のページから「e-book handler pack」をダウンロードし、インストールしてください。特別な設定は不要です。導入後、念のためPCを再起動しておくと確実です。
(※自炊した画像PDFの場合は、事前にAcrobat等でOCR処理を行い、透明テキストを付与しておく必要があります)

2. Everything 1.5 Alphaの導入・設定

ファイルの中身を事前にインデックス化して爆速検索できる機能は、現在テスト中の「1.5 Alpha版」に搭載されています。普段使いでも十分に安定して動作します。

以下のフォーラムからインストーラーをダウンロードして実行します。

  • Everything 1.5 Alpha - voidtools
    (※ 1.4系のLanguage Packを同じフォルダに導入すると、1.4系に存在するメニュー項目は日本語化されます)

インストール時の必須オプション

インストーラーを進める際、以下の項目には必ずチェックを入れてください。

  • Start Everything on system startup: PC起動時に裏側でスタンバイさせます。
  • es: URL protocol: 後述するAutoHotkeyからの呼び出しを確実にするための設定です。
  • Automatically index NTFS volumes: ドライブの自動インデックスを有効にします。
  • Install the Everything Service (recommended): UACの警告画面を毎回出さずに済むようになります。

コンテンツ検索のインデックス設定

インストール後、Everythingを起動してインデックスの設定を行います。

  1. メニューの「ツール」>「オプション」を開きます。

  2. 左側メニューの「検索データ」ツリー内にある「Content」を開きます。
    設定画面

    ここで以下の通りに設定します。

    • Index file content: チェックを入れます。
    • Include only folders: 検索対象にしたいファイルが入っているフォルダを指定します(複数指定可)。空欄だとPC全体を読み込もうとして重くなるため、ドキュメントや電子書籍のフォルダに限定するのがおすすめです。
    • Include only files: インデックスに加えたいファイルの拡張子を指定します。
    • 設定例:*.pdf; *.epub; *.txt; *.md; *.csv (Markdown形式なども入れておくとメモの串刺し検索ができて便利です!)
    • Exclude recall on data access: 必ずチェックを入れます。 これにより、OneDriveやDropboxなどのクラウド上にあり、ローカルに同期(ダウンロード)されていないファイルは無視されます。無駄なダウンロードが発生せず、動作が軽快になります。

設定を適用すると、バックグラウンドで指定フォルダのファイル内容のインデックス化が始まります。

3. AutoHotkeyのスクリプト作成

最後に、選択したテキストをワンアクションでEverythingに渡すためのAutoHotkeyスクリプト(v2用)を作成します。

クリップボードの既存データを壊さずにテキストを取得し、Everythingがうまく見つからなかった場合は es: プロトコルで強引に呼び出すフェイルセーフも備えています。

以下のコードを .ahk ファイルとして保存し、実行してください。

#Requires AutoHotkey v2.0
#SingleInstance Force

; ============================================================
; 設定(必要ならここだけ調整)
; ============================================================

; Everything検索だけなら通常は不要。必要な場合のみ true。
ForceAdmin := false

; Everything.exe の探索候補(1.5aのパスを最優先に追加)
ProgramFiles    := A_ProgramFiles
ProgramFilesX86 := EnvGet("ProgramFiles(x86)")  ; 32-bit OS では空になる

EverythingCandidates := [
    ProgramFiles "\Everything 1.5a\Everything64.exe",      ; 1.5a (64-bit) デフォルト
    ProgramFiles "\Everything 1.5a\Everything.exe",        ; 1.5a (32-bit等)
    A_ScriptDir "\Everything\Everything.exe",              ; ポータブル運用例
    ProgramFiles "\Everything\Everything.exe"              ; 旧1.4版
]

if (ProgramFilesX86 != "") {
    EverythingCandidates.Push(ProgramFilesX86 "\Everything 1.5a\Everything.exe")
    EverythingCandidates.Push(ProgramFilesX86 "\Everything\Everything.exe")
}

; ============================================================
; 管理者権限(任意)
; ============================================================
if ForceAdmin && !A_IsAdmin {
    try Run('*RunAs "' A_AhkPath '" "' A_ScriptFullPath '"')
    ExitApp
}

; ============================================================
; メニュー
; ============================================================
global MyMenu := Menu()
MyMenu.Add("Everythingでファイル名検索 (&E)", RunEverythingSearch)
MyMenu.Add("Everythingでファイル内容検索 (&C)", RunEverythingContentSearch)
MyMenu.Add()
MyMenu.Add("終了 (&X)", (*) => ExitApp())

; ============================================================
; ホットキー:Alt + 右クリック
; ============================================================
!RButton::ShowMyMenu()

ShowMyMenu() {
    global MyMenu
    ; 右ボタン押下状態のままだと不安定なことがあるので、離すのを待つ
    KeyWait "RButton"
    ; Altを離すのを待って Alt 系ショートカット暴発を抑止(固まり防止でタイムアウト)
    KeyWait "Alt", "T1"
    MyMenu.Show()
}

; ============================================================
; Everything検索 実行処理
; ============================================================
RunEverythingSearch(*) {
    ExecuteSearch("")
}

RunEverythingContentSearch(*) {
    ExecuteSearch("content:")
}

ExecuteSearch(prefix := "") {
    global EverythingCandidates

    term := GetSelectedText(0.9)
    term := NormalizeSearchTerm(term)
    if (term = "")
        return

    ; 内容検索の場合はキーワードに content: を付与
    fullQuery := prefix . QuoteArg(term)
    exePath := FindExistingPath(EverythingCandidates)

    ; ----------------------------------------------------
    ; ① Everything.exe が見つかった場合(通常ルート)
    ; ----------------------------------------------------
    if exePath {
        ; 判別用ツールチップを表示(2秒後に消す)
        ToolTip("Everything.exe で起動しました`n(" exePath ")")
        SetTimer () => ToolTip(), -2000

        cmd := QuoteArg(exePath) . " -search " . fullQuery
        Run(cmd)
        return
    }

    ; ----------------------------------------------------
    ; ② es: プロトコルを使う場合(最終手段ルート)
    ; ----------------------------------------------------
    try {
        ; 判別用ツールチップを表示(2秒後に消す)
        ToolTip("es: プロトコル(URL) で起動しました")
        SetTimer () => ToolTip(), -2000

        Run("es:" . UriEncode(fullQuery))
    } catch {
        MsgBox "Everything(1.5a/1.4) が見つからず、es: プロトコル起動にも失敗しました。`n"
            . "インストール/パス設定を確認してください。"
    }
}

; ============================================================
; 選択テキスト取得(クリップボード破壊防止:必ず復元)
; ============================================================
GetSelectedText(timeout := 0.8) {
    saved := ClipboardAll()     ; 画像なども含む全形式で退避
    try {
        A_Clipboard := ""
        Send("^c")
        if !ClipWait(timeout)
            return ""
        return A_Clipboard
    } finally {
        A_Clipboard := saved    ; 必ず復元
        saved := ""             ; 大きなデータの解放促進
    }
}

; ============================================================
; 検索語の正規化(改行→スペース、余分な空白の圧縮、前後Trim)
; ============================================================
NormalizeSearchTerm(s) {
    s := Trim(s)
    if (s = "")
        return ""
    s := RegExReplace(s, "\R+", " ")      ; 改行 → スペース
    s := RegExReplace(s, "\s{2,}", " ")   ; 連続空白 → 1つ
    return s
}

; ============================================================
; Everything.exe の探索
; ============================================================
FindExistingPath(paths) {
    for _, p in paths {
        if (p != "" && FileExist(p))
            return p
    }
    return ""
}

; ============================================================
; URLエンコード(es: フォールバック用)
; ============================================================
UriEncode(str, encoding := "UTF-8") {
    byteLen := StrPut(str, encoding)  ; NUL終端込み
    buf := Buffer(byteLen)
    StrPut(str, buf, encoding)

    out := ""
    Loop byteLen - 1 {                ; NUL終端は除外
        b := NumGet(buf, A_Index - 1, "UChar")
        ch := Chr(b)
        if ((b>=0x30 && b<=0x39) || (b>=0x41 && b<=0x5A) || (b>=0x61 && b<=0x7A)
            || ch="-" || ch="." || ch="_" || ch="~") {
            out .= ch
        } else {
            out .= "%" . Format("{:02X}", b)
        }
    }
    return out
}

; ============================================================
; CreateProcess向けの引数クォート
; ============================================================
QuoteArg(arg) {
    if (arg = "")
        return '""'
    if !RegExMatch(arg, '[\s"]')
        return arg

    out := '"'
    bs := 0
    for _, ch in StrSplit(arg) {
        if (ch = "\") {
            bs++
            continue
        }
        if (ch = '"') {
            out .= StrRepeat("\", bs * 2 + 1) . '"'
            bs := 0
            continue
        }
        if (bs) {
            out .= StrRepeat("\", bs)
            bs := 0
        }
        out .= ch
    }
    if (bs)
        out .= StrRepeat("\", bs * 2)
    out .= '"'
    return out
}

StrRepeat(s, n) {
    out := ""
    Loop n
        out .= s
    return out
}

おわりに

Everything 1.5 Alphaのコンテンツ検索機能とAutoHotkeyの連携により、ファイルの中身を問わず、どこからでも一瞬でアクセスできる快適な検索環境が手に入ります。ぜひ試してみてください!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?