我想获取字体的文件名。这不是那么难......我知道,已经存在一个非常类似的问题,但问题的答案不可能是它。
我想要做的是通过TCP / IP将Font文件发送给其他客户端,如果他请求的话。我在FontDialog上选择了所需的字体,我可以从框架中获取FontName。我无法找到可以说大部分时间都可以使用的字体文件。
.NET在哪里知道系统上安装了哪些字体?它不能是框架依赖于一直无法运行的解决方案,例如CodeProject上的解决方案和Stackoverflow中的建议。必须有一种安全的方法来检索字体文件。 FontDialog可以将它们全部列在一个框中,并且安装的字体必须具有其文件的路径。
有兴趣帮助我吗?
答案 0 :(得分:7)
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();
}
}
}
答案 1 :(得分:2)
首先,您的问题描述了Windows操作系统的问题。因此,您的解决方案需要是Windows特定的解决方案。在您的评论中,您提到该解决方案可能无法在其他操作系统上运行。
肯定不行。
每个操作系统都需要单独处理。此外,您不能假设在客户端的操作系统上以相同的方式安装字体。
关于获取字体文件名的问题。 CP上提供的解决方案没有任何问题。在许多情况下,在Windows中获取内容的唯一方法是进行API调用。 .Net根本不支持我们可能需要做的一些事情。因此,依赖API并不会使其自动错误或不受欢迎。
修改强>
在.NET 4.0中,字体是一个可以像这样访问的特殊文件夹
var fontsFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
答案 2 :(得分:0)
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;
}