午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

C# フォント一覧じゃなくて、フォントファイル一覧取得


コード

github.com



using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

//参照したところ
//プログラミングな日々: WPF用縦書きテキストブロック Tategaki ver .2.1.0
//https://days-of-programming.blogspot.com/2015/01/wpf-tategaki-ver210.html

namespace _20211203_フォントファイル一覧取得
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var fontFileUris = GetFontUris();
            var fontFileList = fontFileUris.ToArray();
        }

        /// <summary>
        /// インストールされている全てのフォントファイルのUriリスト作成
        /// </summary>
        /// <returns></returns>
        private IEnumerable<Uri> GetFontUris()
        {
            //systemのフォントフォルダから一覧
            IEnumerable<Uri> result = MakeList(
                Environment.GetFolderPath(Environment.SpecialFolder.Fonts));

            //ユーザーのフォントフォルダが存在する場合は、
            //それも取得してConcatで付け加える
            string userPath = System.IO.Path.Combine(
                Environment.GetFolderPath(
                    Environment.SpecialFolder.LocalApplicationData),
                @"Microsoft\Windows\Fonts");
            if (System.IO.Directory.Exists(userPath))
            {
                result = result.Concat(MakeList(userPath));
            }

            //指定フォルダのフォントファイルすべてをUriにして取得
            static IEnumerable<Uri> MakeList(string folderPath)
            {
                IEnumerable<Uri> result =
                    System.IO.Directory.GetFiles(folderPath, "*.ttf").Concat
                    (System.IO.Directory.GetFiles(folderPath, "*.ttc")).Concat
                    (System.IO.Directory.GetFiles(folderPath, "*.otf")).Select
                    (x => new Uri(x));
                return result;
            }
            return result;
        }

    }
}

GetFilesで指定フォルダのなかのフォントファイル(ttf,ttc,otf)リストを取得して、それぞれのリストをLinqのConcatで連結してひとつのリストにしている




取得結果

f:id:gogowaten:20211203205426p:plain
結果
419個もあった
多分これで全部取得できていると思う

f:id:gogowaten:20211203205454p:plain
リストの先頭

f:id:gogowaten:20211203205509p:plain
リスト末尾

フォントファイルの場所は2箇所

  1. C:\Windows\Fonts
  2. C:\Users\ユーザー名\AppData\Local\Microsoft\Windows\Fonts




1.C:\Windows\Fonts

C:\Windows\Fontsを開くと

f:id:gogowaten:20211203211813p:plain
C:\Windows\Fontsフォルダ

フォントファイルのある場所を表示する

f:id:gogowaten:20211203211924p:plain
右上、その他のオプション

f:id:gogowaten:20211203211945p:plain
詳細

f:id:gogowaten:20211203212131p:plain
詳細表示

一覧の上のあたりを右クリックして

f:id:gogowaten:20211203212228p:plain
フォント ファイル名の項目表示

これで

f:id:gogowaten:20211203212328p:plain
ファイルの場所が表示された
見るとC:\Windows\Fonts以外の場所にあるフォントがある
それ以外にも表示なしの空白のフォントもある

f:id:gogowaten:20211203212454p:plain
表示なし

C:\Windows\Fontsのファイル全部取得

string path = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
string[] fList = System.IO.Directory.GetFiles(path, "*");

ワイルドカード*を指定しているからフォント以外のファイルも取得される

f:id:gogowaten:20211203213112p:plain
結果
602個あったけど
f:id:gogowaten:20211203213151p:plain
リスト末尾
足りない、C:\Windows\Fonts以外にあるファイルはやっぱり取得できていない




2. C:\Users\ユーザー名\AppData\Local\Microsoft\Windows\Fonts

f:id:gogowaten:20211203213618p:plain
フォルダ
足りないのがあった
このフォルダも特殊なフォルダのようで、
C:\Users\ユーザー名\AppData\Local\
ここまでは
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
これで取得
残りのMicrosoft\Windows\Fontsは手動で書いて付け足して
全体では

string path2 = System.IO.Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                @"Microsoft\Windows\Fonts");
string[] fList2 = System.IO.Directory.GetFiles(path2, "*");

実行してみると

f:id:gogowaten:20211203214501p:plain
結果
16個取得できた




場所が表示されないフォントは

f:id:gogowaten:20211203215624p:plain
場所が表示されないフォント

Meiryo UIとかは、このままだとプロパティも見れないけど

f:id:gogowaten:20211203215723p:plain
右クリックして開く

f:id:gogowaten:20211203215753p:plain
開いたところ

プロパティ!プロパティじゃないか!!!!11

f:id:gogowaten:20211203215806p:plain
右クリックしてプロパティ

f:id:gogowaten:20211203215824p:plain
プロパティ
見ると、ファイル名はmeiryo.ttcってことみたいで、meiryo ui.ttcとかじゃないのね…
場所もC:\Windows\Fontsになっているので、さっき1.で取得したリストを確認してみる

602個のなかに

f:id:gogowaten:20211203220536p:plain
meiryo.ttc
あった、Meiryo UIはこのmeiryo.ttcファイルの中に含まれているってことなんだと思う




感想

参照したところ

days-of-programming.blogspot.com

ここがなかったらわかんなかったねえ
フォント一覧取得はたくさん見つかるんだけど、フォントファイル一覧取得で検索するとなかなかなくて、あってもレジストリを参照するとか、APIを使うとか難しそうなのばかりだった

フォントファイルの場所も難しかった、ググって見つかるのはC:\Windows\Fontsばかりで、それ以外は見つからなかったので、C:\Users\ユーザー名\AppData\Local\Microsoft\Windows\Fontsの後半のMicrosoft\Windows\Fontsは手動で入力することになった、なので環境によってはこのフォルダが存在しない場合もあるかも

7年前にできなかった

これをWPFで再挑戦したいってのがあって、WPFにはGlyphの描画ってのがあって、それにはフォントファイルのUriパスが必要ってことで、今回の記事になった



関連記事
次回は5日後の

gogowaten.hatenablog.com