views:

329

answers:

2

I'm trying to use Linq to loop through all fonts in the %windir%\Fonts folder and find the one that has a property title of "Arial" (or any Font Family name supplied), but I can't seem to access the font properties (things like "Title", "Font style", "Designed for", etc.).

The following is only giving me the basic file info:

     Dim fontDir = Environment.GetEnvironmentVariable("windir") & "\Fonts\"
     Dim fontFiles = From file In My.Computer.FileSystem.GetFiles(fontDir)
     Dim fontInfo = From fontFile In fontFiles Select _
               My.Computer.FileSystem.GetFileInfo(fontFile)

What I'd love to put on the end is something like ...Where fontFile.Title = "Arial". Any advice here?

The reason I need to do this is to find the one with one or more properties, like Title, and then physically copy that font file to another directory.

+2  A: 

Instead of doing that you can use the framwework System.Drawing.Text.InstalledFontCollection class and ask for the installed font. Get the list and use linq to execute that.

Alternatively, doing it with your way above you will have to load the font into System.Drawing.Text.PrivateFontCollection then applied query just like above to find the font.

Edited to add this so other can spot it easily: To find the file association, I had to do it by enumerating one or both of these registry key to find the font name and their corresponding font file. The font folder is always located in "%Windows%\Fonts"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts
Fadrian Sudaman
I do need access to the physical file once I've found what I needed. For example, in this case, I need to find the one that has Arial as the title and then copy the font file to a different directory. If `InstalledFontCollection` has a property of `Path` then I would use it for sure.
Otaku
I remember I have done something on this in C++. Dig out some old code and found the way :) You actually have to enumerate registry key to find all the name of the font and the data is the font file. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontsWrite some code that will go through all the entries in this key. The path to the font is always %windows%\Fonts folder. If you are not in controlled environment, try also to read this keyHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts
Fadrian Sudaman
Otaku
+2  A: 

You should probably be using the System.Drawing.Text.InstalledFontCollection class instead of probing the filesystem directly. You could then do something like so:

var arialFontFamilies = from fontFamily in new InstalledFontCollection().Families
                        where fontFamily.Name.Contains("Arial");

If you wanted to access more properties, you could create Font objects:

var arialFonts = from fontFamily in new InstalledFontCollection().Families
                 where fontFamily.Name.Contains("Arial")
                 select new Font(fontFamily, FontSize.Regular);

If you still need to access a custom set of fonts from anywhere on disk, you could use the PrivateFontCollection class:

var fontFiles = from fileInfo in (from file in My.Computer.FileSystem.GetFiles(fontDir) select Computer.FileSystem.GetFileInfo(file));

var privateFonts = new PrivateFontCollection();
foreach (var fontFile in fontFiles)
{
    privateFonts.AddFontFile(fontFile.FullName);
}

var arialFonts = from fontFamily in new privateFonts.Families
                 where fontFamily.Name.Contains("Arial")
                 select new Font(fontFamily, FontSize.Regular);
jrista
Interesting, I hadn't thought of that. Let me check it out.
Otaku
Unfortunately, it's not working. It still doesn't give me the font properties of Title, Font style, etc.
Otaku