発生したこと
Windowsのフォントフォルダに存在するフォントファイルの一覧を取得し、各フォントファイルのGlyphTypeFaceを生成する処理を実装したところ、
一部のフォントでNullReferenceException
( オブジェクト参照がオブジェクト インスタンスに設定されていません。 )
が発生する場合があることがわかりました。
※EnumCharのユーザー様からの障害報告で気づきました。
例外のスタックトレース
場所 MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.TryGetValue(Int32 key, UInt16& value)
場所 System.Windows.Media.GlyphTypeface.Initialize(Uri typefaceSource, StyleSimulations styleSimulations)
場所 System.Windows.Media.GlyphTypeface..ctor(Uri typefaceSource)
場所 ConsoleApplication1.Program.Main(String[] args)
原因
フォントを上書きインストールしたことのある環境では、古いフォントがフォントフォルダに残っており、
その古いフォントにアクセスしようとすると、実体が無いようで、
exceptionが発生するというのが原因でした。
下記のサイトが参考になります。
http://d.hatena.ne.jp/itouhiro/20120603
コード
実際にexception が発生するコードがこちらになります。※実際にビルドするには、PresentationCoreを参照設定する必要があります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media; // 参照設定で PresentationCoreをONにする必要がある。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// フォントファイルのパス取得
string fontfolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
// フォントファイルの一覧取得
string[] fontfiles = System.IO.Directory.GetFiles(fontfolder);
foreach (string fontfile in fontfiles)
{
// 拡張子を切り出す
string ext = System.IO.Path.GetExtension(fontfile);
if ((String.Compare(ext, ".ttf", true) == 0) || (String.Compare(ext, ".otf", true) == 0))
{
/* TTF, OTF */
try
{
Console.WriteLine(fontfile); // debug
GlyphTypeface typeface = new GlyphTypeface(new Uri(fontfile));
}
catch (NullReferenceException nullex)
{
Console.WriteLine(nullex.Message); // debug
}
}
}
Console.ReadKey();
}
}
}
実行結果
苦労したこと
・フォントフォルダをExplorerで見る限りは、フォントが1個しか存在しないため、原因の特定に時間がかかりました。
・また、現象が発生するフォントをアンインストールしても現象が発生したため、迷宮入りしそうになりました。
0 件のコメント:
コメントを投稿