コンテンツにスキップ

画面の共通の決まり

扱うこと: キーボード操作・表示とアクセシビリティの決まり、配布と実行ポリシー(Mark-of-the-Web)、確認ダイアログの形式、複数のタブで共通のフォルダ選択ダイアログ。扱わないこと: 画面に出すメッセージそのものの一覧(画面に出すメッセージの一覧)。先に読むページ: 画面。

キーボード操作

キー 動作
Enter(検索ワード欄) 検索する
Esc 検索中なら中止する(ウィンドウは閉じない)
Ctrl+F 検索ワード欄にフォーカスを移し、全選択する([検索]タブに切り替える)
Ctrl+Shift+F 絞り込み欄にフォーカスを移す
Enter(結果の表) 元のファイルの該当箇所を開く(ファイルの見出しの行では、そのファイルの行を開く・閉じる。ファイルごとにまとめた表示)
Ctrl+C(結果の表) 選択行をコピーする(元のファイルを開く。見出しの行を選んでいれば、そのファイルの行をすべて)
Ctrl+C(選択行のプレビュー) 選んだセルの値をコピーする(選択行のプレビュー)
F5 インデックスの状態と検索対象のツリーを読み直す
Ctrl+Tab / Ctrl+Shift+Tab 左の欄の画面を順に切り替える(端から先は反対の端に回る)
Delete インデックス一覧で、選択中のインデックスを削除する(確認あり。[インデックス管理]タブの[削除])
スペース 検索対象のツリーで、選択中の項目のチェックを切り替える(検索対象のツリー)

インデックス作成と強制終了は影響が大きいため、ショートカットキーを設けない。フォルダ選択ダイアログ(フォルダ選択ダイアログ([参照…]))は Windows 標準のため、キー操作もエクスプローラーと同じになる。

表示・アクセシビリティ

  • フォントは Windows 標準の Segoe UI を先に使い、日本語など足りない文字は Yu Gothic UI(無ければ Meiryo UI)で表す。13 px とする(scripts/shared/ui/app_host.ps1 の newAppFontFamily が作り、loadXaml が各画面の Font.Body に入れる。フォントは同梱しないので、展開した版も単一 .ps1 版も同じ見た目になる)。結果の表は 12 px とする。
  • WPF は高 DPI に自動で対応するため、表示倍率 125 %・150 % でもぼやけない。
  • 状態は色だけで表さない。Lucide のアイコン(check・x・triangle-alert など)と文言を併記する。scripts/ に CP932 に無い文字(記号の文字)を書かない(単一 .ps1 を Shift_JIS で保存し直しても、字が落ちたり化けたりしないため。tests/meta/encoding.Tests.ps1 が確かめる)。一致箇所の強調は背景色に加えて太字にする。
  • 対象を言う文言は、「Office ファイル」や「Excel」だけにせず、「Excel・PowerPoint・Word・PDF・テキスト」を並べる(Office ファイルは Excel・PowerPoint・Word)。画面・進み具合・ログ・例外の文言に「Office ファイル」と書くと tests/meta/wording.Tests.ps1 が落ちる。
  • ツールチップは、画面の文字だけでは分からない補足と、省略(…)で切れた文字の全文にだけ使う。切れた文字の全文は addTrimmedToolTip(shared/ui/trimmed_tooltip.ps1)で付け、切れていないときは開かない(切れているかの判定は testTextTrimmed)。キー操作の案内(Ctrl+C・Enter など)と、ステータスバーの文のツールチップは置かない。
  • 入力の誤りや注意は入力欄の下やステータスに表示する。ダイアログは確認が必要な操作([インデックス管理]タブの[削除]、インデックス作成の確認ダイアログ のインデックス作成の確認、中止・終了・ログ のインデックス作成の中止、元のファイルが見つからないとき(元のフォルダを設定する)、前回残った Office の確認)に限り、その形式は 確認ダイアログ のとおりとする(インデックス作成の確認ダイアログ だけは、インデックスごとの件数を一覧で見せるため専用のダイアログにする)。なお、インデックスの名前とフォルダパスはダイアログにせず、詳細の欄で直接直し、入力の誤りは欄の下に表示する(名前とフォルダパスの編集)。確認も入力も要らない「バージョン情報」(左の欄の下の[バージョン情報])だけは例外で、版・コミット・ライセンスを見せるだけの小さなダイアログにする(メンテナの選択。画面構成)。
  • 確認ダイアログの中で消す操作を選ぶボタン([削除する]など)は、赤で塗りつぶして区別する(確認ダイアログ)。
  • 説明を読まないと何が起きるか分からない画面にしない。確認は「実行するとこうなります」を並べて見せ(確認ダイアログ)、ボタンの文言は「はい/いいえ」ではなく操作そのもの([削除する][中止する])にする。画面の注意書きには、内部の言葉(TSV・work\store\content・取り込み一覧)や、その場で必要のない手順の説明を書かない。
  • アイコンはベクターの絵(scripts/tebunko/xaml/app_icon.xaml。DrawingImage)とし、タイトルバー・タスクバー・Alt+Tab・スプラッシュ・バージョン情報に表示する。拡大・縮小や画面の倍率(DPI)が変わっても、ぼやけない。
  • 元データは docs/images/logo.svg の 1 つだけ。tools/new_icon.ps1 が app_icon.xaml と tebunko.ico を同時に作る(手で写さない)。SVG だけ直して作り直し忘れると、テスト(tests/tools/icon_xaml.Tests.ps1)が落ちる。
  • 読み込みは shared/ui/app_host.ps1 の loadAppIcon(凍結して全部の画面で 1 つを共有する)。窓は loadWindow が Window.Icon に渡す(Window.Icon は DrawingImage を直接受け取る)。スプラッシュ・バージョン情報も同じ絵を使う。ファイルが無い・読めなくても画面は開く。
  • tebunko.ico は画面では読まない。インストーラー(tebunko.exe・セットアップ)とショートカットのアイコンなど、Windows が .ico しか受け付けない所だけで使う。
  • タスクバー・タイトルバーのアイコンは Window.Icon(上記)で出る。画面は powershell.exe で動くため、タスクバーのボタンは PowerShell と同じグループにまとめられる(アイコン自体は tebunko のものが出る)。独立したボタンにするには P/Invoke(SetCurrentProcessExplicitAppUserModelID)が要り、実行時コンパイルを使わない方針に反するため行わない(画面の実装)。
  • tebunko.bat 自体のアイコン(エクスプローラー上の表示)は Windows の仕様で変更できない。デスクトップ等にアイコン付きで置きたい利用者は、自分でショートカットを作る(ツールはショートカットを作らない)。

右クリックのメニュー

どの画面の右クリックのメニューも、同じ見た目と決まりにする。

  • 見た目: 共通の Style(scripts/shared/xaml/theme.xaml。幅 216・項目の高さ 31・丸い角と影・ホバーの色・区切り線)。メニューや項目を XAML や PowerShell の中で作るときも、Style を指定せずに作れば自動で効く(キー無しの Style は型が同じものに効く)。赤にする項目(削除)は MenuItemDanger を付ける。
  • 並び: 先頭の項目は太字(一番よく使う動き)。区切り線のあとに、使う頻度が低いものや取り返しのつかないものを置く。
  • 文言: 「…」は、ダイアログが開く項目にだけ付ける。キー操作(ショートカット)は項目に書かない。
  • 開き方: 右クリックした行を先に選んでから出す。行の無い所(列見出し・余白・スクロールバー)では出さない。表の行には、選んでいる別の行に効かないよう、押した行を対象にする。
  • 変えないもの: 入力欄(検索ワード・絞り込み・設定の欄)の右クリックは、Windows 標準のメニューのままにする(Style を当てない)。
  • 判断と画面の分け方: 並び・文言・太字・使えるかどうかは判断層(getResultMenuItems・getPreviewMenuItems・getIndexRowMenuEnabled)が決め、画面層はその結果を並べるだけにする。

各画面のメニューは、検索結果の行・ファイルの見出しが ファイルを開く、プレビューが 選択行のプレビュー、インデックスの行が インデックス一覧の管理 にある。

配布と実行ポリシー(Mark-of-the-Web)

flowchart TD
    B(["tebunko.bat を起動"]) --> U["scripts 配下の Mark-of-the-Web を Unblock-File で消す<br>(-Command の中身は実行ポリシーの対象外)"]
    U --> G["& $gui(環境変数 TEBUNKO_ROOT のフォルダの gui.ps1)を RemoteSigned で起動<br>(conhost.exe 経由・-WindowStyle Hidden)"]
    G --> G2["gui.ps1 も起動時に自フォルダの印を消す<br>(ショートカット起動・差し替え後のため)"]

起動は、zip 版は tebunko.bat、インストーラー版は起動口の tebunko.exe(installer/tebunko.cs)から行う。どちらも Windows の PowerShell 5.1 を、そのプロセスだけの実行ポリシー RemoteSigned で起動する。Bypass を使わない理由、実行ポリシーの設定を変えないこと、Mark-of-the-Web を解除する範囲は、安全性の Mark-of-the-Web の解除 にまとめている。ここには実装の決まりだけを書く。

  • なぜ Mark-of-the-Web(MOTW)が問題か:zip をブラウザ・メールでダウンロードして展開すると、展開後の各ファイルに「外部由来」の印(Zone.Identifier という代替データストリーム)が付く。RemoteSigned は、この印の付いた未署名 .ps1 の実行をブロックする(.xaml・.ico は実行ポリシーの対象外なので影響しない)。
  • 対策:tebunko.bat が起動する PowerShell の -Command の中で、まず自フォルダの scripts 配下の印を Get-ChildItem -Recurse -File \| Unblock-File で消し(work には数万件の TSV があり、起動のたびに全件へかけると TSV 1 万件あたり約 3 秒遅くなるため、実行するスクリプトのある scripts に限る)、続けて & $gui で画面を開く。ツールのフォルダは set "TEBUNKO_ROOT=%~dp0" の環境変数で渡し、-Command の中では $env:TEBUNKO_ROOT で読む(パスを -Command の文字列に埋め込むと、' などで PowerShell の構文エラーになり、何も知らせずに終わるため。先頭の setlocal EnableExtensions DisableDelayedExpansion で、パスの ! も消えない)。インラインの -Command の中身は実行ポリシーの対象外なので、印が付いていても Unblock-File は動く。& で呼ぶ gui.ps1 は RemoteSigned で調べられるため、印を消す前に呼ぶとブロックされる(順番に意味がある)。以前は印を消すためだけに PowerShell を別に起動していたが、PowerShell の起動 1 回分(1〜2 秒)画面が出るのが遅れるため、1 つのプロセスにまとめた。念のため tebunko/gui.ps1 も起動時に自フォルダの印を消す(利用者が自作したショートカットから起動したときや、あとでファイルを差し替えたときのため)。
  • セキュリティの警告:zip を解除せずに展開すると tebunko.bat 自体にも印が付くため、ダブルクリックで Windows の「開いているファイル - セキュリティの警告」(発行元を確認できません)が起動のたびに出る。[実行]を押すと bat が動き、[このファイルを開く前に常に確認する]のチェックを外して[実行]すると以降は出なくなる。展開する前に zip のプロパティで解除しておけば、この警告は出ない(README・手引きの書き方と同じ)。これは Windows の正規の確認であり、隠す対象ではない。
  • Bypass を使わない代わりの実測挙動(この PC・RemoteSigned で確認):印あり=ブロック(「デジタル署名されていません。実行できません」)/tebunko.bat の Unblock-File で印を消す=0 件/消した後は RemoteSigned で起動成功。
  • コンソールの窓を残さない:tebunko.bat は start "" conhost.exe powershell ... -WindowStyle Hidden -Command "..." で起動する。Windows 11 で既定のターミナルが Windows Terminal のとき(「Windows に任せる」の場合も含む)、コンソールの窓は Windows Terminal に渡され、Windows Terminal は -WindowStyle Hidden を無視する。そのため conhost.exe を通さないと、画面を閉じるまで PowerShell の窓(Windows Terminal のタブ)が開いたままになる。conhost.exe を通すと従来のコンソールで動き、-WindowStyle Hidden で窓が隠れる(起動の瞬間に一度だけ窓が見えることがある)。インデクサは画面のプロセスの中のスレッドで動くため(プロセスとスレッド)、別の窓は開かない。
  • インストーラー版:tebunko.exe は powershell.exe -NoProfile -STA -ExecutionPolicy RemoteSigned -Command で gui.ps1 を、窓を作らずに(CreateNoWindow)起動する。gui.ps1 のパスは環境変数で渡し、WildcardPattern.Escape を通して呼ぶ(-File はパスをワイルドカードとして読み、[ ] を含むフォルダで起動できないため)。インストーラーで入れたファイルには Mark-of-the-Web が付かないため、tebunko.bat の Unblock-File にあたる処理は要らない(gui.ps1 も起動時に同じ解除を行う)。
  • バッチの書式:tebunko.bat は ASCII・CRLF で書く。cmd はコードページ(日本語環境は CP932)と改行に敏感で、UTF-8 の日本語コメントや LF 改行だと行が結合して起動の行がコメントに飲み込まれる不具合が出るため。説明コメントは英語にし、日本語の説明はこのページに置く。
  • 起動の失敗の知らせ方:gui.ps1 の画面が出る前に起動が失敗したとき(制限言語モード・実行ポリシー・ファイル不足など)、tebunko.bat は & $gui を try/catch で包んで理由を分け、Notepad で示す(WPF・WinForms のメッセージボックスが出せない場面があるため)。詳しくは安全性の起動に失敗したときの知らせを参照。

確認ダイアログ(showConfirm)

本体の窓を親にして出すダイアログは、必ず showOwnedDialog(shell.ps1)で出す(待つ間のダイアログは例外で、showWaitDialog が同じ暗幕の数え方で出す)。開いている間は本体の窓の最上層の暗幕(ScrimOverlay。ui/shell/services.ps1 が setDialogScrim で渡す)を見せ、閉じたら(例外のときも)隠す。.ShowDialog( を直接呼ぶのは showOwnedDialog だけで、tests/meta/structure.Tests.ps1 が確かめる。

showConfirm は -title(OS の題の帯)と -form(normal / danger / choice。省略すると、選択肢が 2 つ以上なら choice、1 つで危険なら danger、それ以外は normal)を取る。幅は choice が 620、ほかは 520。danger は見出しに赤い「!」の丸を付け、実行のボタンを赤にする。

showErrorDialog は予期しないエラーの知らせで、赤い「!」・見出し・詳細の枠(選べる文字)・[内容をコピー][ログを開く][閉じる]を出す。

取り消せない操作・時間のかかる操作の確認は、MessageBox ではなく scripts/shared/xaml/dialog_confirm.xaml の自前のダイアログで行う(showConfirm)。説明を読まなくても、押す前に何が起きるか分かるようにするため。

sequenceDiagram
    actor U as 利用者
    participant G as 画面
    U->>G: 取り消せない・時間のかかる操作
    G->>U: showConfirm(見出し・結果・選択肢・補足)
    alt 主ボタン・選択肢を選ぶ
        U->>G: 実行(例: [削除する])
        G->>G: 操作を行う
    else [キャンセル]
        U->>G: 取りやめ
    end
部分 役割 書き方
見出し これから何をするか 1 行で読み切れる長さの問いかけ(「<名前>」のインデックスを削除しますか?)
結果 実行すると何がどうなるか ✗(消える・失われる、赤)・✓(残る、緑)・→(続けて起きること、青)の行。各行は「何がどうなるか」の 1 行と、場所・件数などの補足の 1 行(補足は空なら出さない)
選択肢 押せる操作 ボタンの文言そのものが操作([削除する][作り直す][中止する])。[キャンセル]の右に横に並べ、最後の 1 つを主なボタン(消す操作は赤の塗りつぶし)にする
補足 別のやり方の案内 読まなくても操作できる内容だけを書く(しばらく検索しないだけなら、削除せずに行のチェックを外してください。…)
  • ボタンの並べ方: 右下に[キャンセル]と選択肢のボタンを横に並べる。主なボタンは右端にする(キャンセルの文言は場面に合わせて変える。例:[閉じない][インデックス作成を始めない])。
  • 既定のボタン: 消す操作(Danger。ボタンを赤にする)・時間のかかる操作(Careful)・選択肢が 2 つ以上のときは、Enter で進まないよう[キャンセル]を既定にしてフォーカスを置く。そうでなければ主ボタンを既定にする。
  • 用語: 利用者に見える操作の呼び名は「更新」(インデックスを作る・新しくする操作。[すべて更新]・更新中・最終更新・更新済み・更新に失敗したファイル)にする。データの名前(取り込み一覧)とコード・設計書の indexing/ の呼び名は「取り込み」のまま。
  • 文言の決まり: 画面に出ない言葉(TSV・work\store\content・取り込み一覧)は書かない。利用者から見て何が消えて何が残るかだけを書く。「〜の場合は〜してください」という手順の説明は、結果ではなく補足に置く。
  • 使っている場面: インデックスの[削除]([インデックス管理]タブ)、インデックス作成の中止・インデックス作成中に閉じる(中止・終了・ログ)、元のファイルが見つからないとき(元のファイルが見つからないとき(元のフォルダを設定する))、前回残った Office の終了(前回残った Office の確認)。インデックス作成の確認(インデックス作成の確認ダイアログ)は、インデックスごとの件数を一覧で見せるため専用のダイアログにする。
  • 伝えるだけのダイアログ(エラー・警告・OK だけのもの)は、showMessage で出す(次のメッセージの画面)。

メッセージの画面(showMessage)

お知らせ・警告・エラー・確認の画面は、すべて scripts/shared/xaml/dialog_confirm.xaml の 1 つの形で出す。OS 標準の MessageBox は使わない。枠・題(アプリ名)・余白・ボタンの形(DialogButton/主ボタンは Primary)・見出しの左のアイコンと色が、showConfirm・showErrorDialog・showMessage・インデックス更新の確認で同じになる。

showMessage は呼び出しの引数と戻り値(OK/Yes/No/Cancel)を MessageBox.Show と同じにしてある。種類・ボタン・戻り値の決め方は、判断層の scripts/shared/ui/message_view.ps1 にまとめ、tests/shared/ui/message_view.Tests.ps1 で確かめる。

種類(icon) アイコン(theme.xaml) 色 使うとき
お知らせ(Information) Icon.Info Accent 結果や状態を知らせるだけ(操作は[OK]だけ)
警告(Warning) Icon.TriangleAlert Warn いまは操作できない・やり直しが要る理由を知らせる(「更新中は〜できません」など)
エラー(Error) Icon.CircleAlert Danger.Text 失敗した・続けられない。予期しない例外は showErrorDialog(詳細の枠と[内容をコピー]が付く)
確認(Question) Icon.CircleQuestionMark Accent 進めてよいかを聞く。結果の一覧が要るものは showConfirm、取り消せないものは赤い「!」(danger)
  • 文の分け方: メッセージの最初の段落(空行まで)が見出し、続く短い段落が補足になる。240 字を超える・5 行以上の続きは、詳細の枠(選べる文字)に出す。
  • ボタン: OK は[OK]、OKCancel は[OK][キャンセル]、YesNo は[はい][いいえ]、YesNoCancel は[はい][いいえ][キャンセル]。既定のボタン(Enter で押す・フォーカスを置く)は default の戻り値のボタンで、省略すると先頭。主ボタンの見た目は既定のボタンに付く。
  • Esc・閉じる: [キャンセル]があれば Esc で[キャンセル]。[OK]だけなら Esc で[OK]。[はい][いいえ]だけは、OS 標準と同じく Esc では閉じない(窓を閉じたときの戻り値は No)。
  • 窓の位置: 親の窓の中央に出す。親が無いときは画面の中央。ダイアログの上に重ねても、暗幕は外側のダイアログを閉じるまで残る。
  • OS 標準のまま出すところ: 画面の部品(テーマ・WPF)がまだ使えない場面だけ。2 つ目の起動の知らせ(gui_main.ps1)と、起動の失敗の知らせ(startup_error.ps1)。ほかのところで直接 MessageBox を呼ばないことは、tests/meta/structure.Tests.ps1 が確かめる。
  • 自前の画面を出せないとき(別のスレッドから呼ばれた・画面の定義が読めないなど)は、エラーログに残して OS 標準の MessageBox で出す。知らせること自体は止めない(shell.ps1 の showMessage だけに置く)。
  • テスト: 種類ごとのアイコン・ボタン・既定・戻り値は tests/gui/message.Tests.ps1(本物の WPF の窓)で確かめる。

待つ間のダイアログ(showWaitDialog)

終わるまで待つ場面(中止の途中・窓を閉じるときの待ち)で、shell.ps1 の showWaitDialog が出す(shared/xaml/dialog_wait.xaml)。見出し・説明・進み具合の棒・秒読みの 1 行・押せないボタンを持つ。

  • モーダルにしない: Show で出すので、呼び出し側の処理は止まらない。本体の窓を親にして、showOwnedDialog と同じく暗幕を掛ける(開いている数を enterDialogScrim / leaveDialogScrim で数える。ほかのダイアログと重なっても、全部閉じるまで暗幕は残る)。
  • 利用者は閉じられない: Alt+F4 も効かない。呼び出し側が closeWaitDialog で閉じる。本体の窓を閉じるときは、待つ間のダイアログ、暗幕、本体の窓の順に閉じる。
  • 書き換え: updateWaitDialog で見出し・説明・秒読み・ボタンの文字・棒を書き換える。説明・秒読み・ボタンは、空の文字にすると隠す。棒は件数が分からないとき流れる棒、分かるときは 0 から 1 の割合で出す。
  • 中止の途中: 暗幕で本体の操作を止める。検索は止まってから行う。
  • ワークスペースを移している間: 見出し ワークスペースを移しています…、説明 中身の量によっては時間がかかります。終わるまでお待ちください。(種類 Moving)を出し、棒は流れる棒にする。ボタンは無い。移している間に窓を閉じようとしたら、閉じるのを保留して説明を 移し終わると、画面を閉じます。(MovingClose)に替え、移し終わってから閉じる。移しの途中で止めることはしない。
  • 文言と値: 場面ごとの見出し・説明、秒読み(「あと N 秒で強制終了します」。端数は切り上げ、0 秒より小さいときは 0)、棒の値は判断層(tebunko/ui/wait_view.ps1)で決める。
  • 窓を閉じるときの待ち: 秒数は closeTimer の期限(60 秒。Office を止めたあとは 15 秒)までの残りで、500 ミリ秒ごとに書き換える。[閉じない]は押せない形で置き、押しても何も起きないことを見せる。

フォルダ選択ダイアログ([参照…])

Windows 標準のエクスプローラー形式のダイアログ(COM の IFileOpenDialog を、フォルダを選ぶ設定 FOS_PICKFOLDERS で開いたもの)を使う(shared/ui/folder_dialog.ps1 の selectFolder)。利用者が見慣れた画面のため、クイックアクセス・OneDrive・ネットワーク・検索・[新しいフォルダー]がそのまま使える。

[+ フォルダを追加]・詳細のフォルダパスの[変更…](名前とフォルダパスの編集)、元のファイルのフォルダを選んでもらう場面(元のファイルが見つからないとき(元のフォルダを設定する))、ワークスペースの[変更…]([設定]タブ)で共通に使う。

項目 仕様
タイトル 呼び出し元が渡す文言。追加・編集は インデックスにする、ファイル(Excel・PowerPoint・Word・PDF・テキスト)のあるフォルダを選んでください
最初に開くフォルダ 呼び出し元が渡したフォルダ([参照…]は今の入力値)。ネットワークのパスは、画面のスレッドで有無を調べない。 ローカルなら、無ければその上の、今もあるフォルダ(getExistingAncestorFolder)。ネットワークのパスは、直前の「フォルダの状態」の確認で「ある」と分かったフォルダ(編集中のインデックスの元のフォルダで、場所を書き換えていないとき)だけを、調べずにそのまま使う(selectFolder の knownExisting)。それ以外はどこにも無いのと同じ扱いにする。どこにも無ければ Windows に任せる(前回開いた場所)
親ウィンドウ 呼び出し元のウィンドウ(主画面)。閉じるまで親は操作できない
一覧 フォルダだけが出る(フォルダを選ぶ設定では、Windows がファイルを出さない)
選んだとき 選んだフォルダのパスを normalizeFolderPath で整えて返す
[キャンセル] 何も返さない

呼び出し方:IFileOpenDialog を PowerShell から直接呼ぶにはインターフェースの定義が要り、自分で定義すると実行時コンパイル(csc.exe)が要る(実行時コンパイル(csc.exe)を使わない)。そのため、WinForms(gui.ps1 で読み込み済み)が内部に持つ定義 FileDialogNative+IFileDialog をリフレクションで呼ぶ。csc.exe の起動・一時 DLL の生成・Add-Type の追加は無い(危険とされる処理の検査結果)。

  • 内部の型が見つからない・呼べないとき(.NET の変更など)は、エラーのログに記録し、同じエクスプローラー形式の「ファイルを開く」ダイアログ(OpenFileDialog。公開の API だけで開ける)で、選びたいフォルダの中に入って[開く]を押してもらう。ツリー形式の FolderBrowserDialog は、中身が見えず目的のフォルダにたどり着きにくいため使わない。