84221

Retrieve Filename of a font

<h3>Question</h3>

I would like to get the filename of a font. This can't be that hard... I am aware, there is a very similar question already, but the answer to that question just can't be it.

What I want to do is to send a Font file over TCP/IP to an other client, if he requests it. I select the desired font over a FontDialog, I can get the FontName from the framework. I can't find the font file in a way that I can say will work most of the time.

Where does .NET know which fonts are installed on the system? It can't be that the framework relies on a solution which does not work all the time, like the solution on CodeProject and suggested in Stackoverflow. There must be a secure way to retrieve the font file. The FontDialog can list them all in a box and the fonts installed must have a path to their file.

Anyone interested in helping me?


<h3>Answer1:</h3>
using System; using System.Drawing; using System.Text.RegularExpressions; using Microsoft.Win32 public static string GetSystemFontFileName(Font font) { RegistryKey fonts = null; try{ fonts = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion\Fonts", false); if(fonts == null) { fonts = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Fonts", false); if(fonts == null) { throw new Exception("Can't find font registry database."); } } string suffix = ""; if(font.Bold) suffix += "(?: Bold)?"; if(font.Italic) suffix += "(?: Italic)?"; var regex = new Regex(@"^(?:.+ & )?"+Regex.Escape(font.Name)+@"(?: & .+)?(?<suffix>"+suffix+@") \(TrueType\)$", RegexOptions.Compiled); string[] names = fonts.GetValueNames(); string name = names.Select(n => regex.Match(n)).Where(m => m.Success).OrderByDescending(m => m.Groups["suffix"].Length).Select(m => m.Value).FirstOrDefault(); if(name != null) { return fonts.GetValue(name).ToString(); }else{ return null; } }finally{ if(fonts != null) { fonts.Dispose(); } } }
<h3>Answer2:</h3>

For one, your problem describes issues with Windows OS. Hence your solution needs to be a Windows specific solution. In your comment you mentioned that the solution may not work on other OS.

It surely WILL NOT work.

Each OS will needs to be handled separately. Also, you can't assume that installation of fonts will happen in the same way on client's OS.

As for the problem with getting font file names. There is nothing wrong with the solutions provided on CP. In many instances the only way to get something in windows is to make API calls. .Net simply has no support for a number of things we may need to do. So relying on API is doesn't make it automatically wrong or undesirable.

EDIT:

In .NET 4.0 Fonts is a special folder that can be accessed like so

var fontsFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
<h3>Answer3:</h3>
Dictionary<string, List<string>> _fontNameToFiles; /// <summary> /// This is a brute force way of finding the files that represent a particular /// font family. /// The first call may be quite slow. /// Only finds font files that are installed in the standard directory. /// Will not discover font files installed after the first call. /// </summary> /// <returns>enumeration of file paths (possibly none) that contain data /// for the specified font name</returns> private IEnumerable<string> GetFilesForFont(string fontName) { if (_fontNameToFiles == null) { _fontNameToFiles = new Dictionary<string, List<string>>(); foreach (var fontFile in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.Fonts))) { var fc = new PrivateFontCollection(); try { fc.AddFontFile(fontFile); } catch (FileNotFoundException) { continue; // not sure how this can happen but I've seen it. } var name = fc.Families[0].Name; // If you care about bold, italic, etc, you can filter here. List<string> files; if (!_fontNameToFiles.TryGetValue(name, out files)) { files = new List<string>(); _fontNameToFiles[name] = files; } files.Add(fontFile); } } List<string> result; if (!_fontNameToFiles.TryGetValue(fontName, out result)) return new string[0]; return result; }

来源:https://stackoverflow.com/questions/21525377/retrieve-filename-of-a-font

Recommend

  • Android Studio logcat printing lot of errors
  • Google Maps JS API v3 will not load inside Flex Mobile StageWebView
  • Sort a list from Arrays.asList() changes also the origin array?
  • IMAP access to mail office 365 with javamail
  • XPath locating element using text() not working
  • c++ declare an array of arrays without know the size
  • Pandas weird behavior using .replace() to swap values
  • How to call R functions from Fortran?
  • Asp.net “disable” authentication in development environment
  • Changing white-space on the beginning of a file name [closed]
  • runtime error project source code not found and invalid string null exception? [closed]
  • Finding a value in an array of arrays (similar to VLOOKUP function in Excel) in Swift
  • How to appropriately include schemalocation to refer a xsd file in xml
  • spring security client_credentials grant_type - support for refresh token
  • Close expandable ListView on child click
  • SQL connection to localhost
  • PowerShell parameters from file
  • Convert HEX to ASCII, data from GPS tracker
  • Laravel: Google contacts API gives empty results
  • How to implement 'if' in Gherkin
  • How to bend a cylinder in three.js?
  • Decimal to ASCII Conversion [closed]
  • plot dirac function in matlab
  • Smarter Removing Unnecessary WhiteSpace CSV
  • Admob in ListView not clickable
  • .Net core Hosted Services guaranteed to complete
  • Keep rows with certain values always at the bottom while sorting in jquery tablesorter plugin
  • opencv deskewing a contour
  • How to define a custom accuracy in Keras to ignore samples with a particular gold label?
  • JavaMail connection problems [duplicate]
  • Getting the type of a “Type” in C# reflection
  • Comparing variables with strings bash
  • Using redis as an LRU cache for postgres
  • How to get rgb from transparent pixel in js
  • Why my AngularJS async test in Jasmine 1.3.x is not working?
  • Capture SIGFPE from SIMD instruction
  • Jersey serializes character value to ASCII equivalent numeric string
  • How to use FirstOrDefault inside Include
  • WPF custom control and direct content support
  • Write to .csv file with PHP (Commas in Data Error)