C# 如何删除/替换当前使用的字体

C# 如何删除/替换当前使用的字体,c#,fonts,windows-mobile,compact-framework,windows-ce,C#,Fonts,Windows Mobile,Compact Framework,Windows Ce,我希望在更新过程中以编程方式部署字体包。因此,我需要将\Windows\font中的旧字体文件替换为从ZIP存档中提取的新字体文件。删除现有字体文件将导致IOException,因为另一个进程正在访问该文件 我试图通过调用并通过消息传播更改来释放字体,但没有成功RemoveFontResource返回false,返回本机错误2(未找到文件?)和HRESULT-2147467259。该文件确实存在 示例代码: [DllImport("coredll.dll", SetLastError = tru

我希望在更新过程中以编程方式部署字体包。因此,我需要将
\Windows\font
中的旧字体文件替换为从ZIP存档中提取的新字体文件。删除现有字体文件将导致
IOException
,因为另一个进程正在访问该文件

我试图通过调用并通过消息传播更改来释放字体,但没有成功
RemoveFontResource
返回
false
,返回本机错误2(未找到文件?)和HRESULT-2147467259。该文件确实存在

示例代码:

[DllImport("coredll.dll", SetLastError = true)]
private static extern int RemoveFontResource(string lpName);

[DllImport("coredll.dll", SetLastError = true)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

private const int WM_FONTCHANGE = 0x001D;
private const int HWND_BROADCAST = 0xffff;

public const string SAMPLE_FILE = @"\Windows\Fonts\MyFont.ttf";

public void RemoveFont()
{
  if (!RemoveFontResource(SAMPLE_FILE)) 
  {
    throw new Win32Exception(Marshal.GetLastWin32Error());
  }

  SendMessage(new IntPtr(HWND_BROADCAST), WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);

  File.Delete(SAMPLE_FILE);
}

是否有一种干净的方法可以在系统范围内部署和替换字体?

如果字体文件是操作系统映像的一部分,则它们具有就地执行(XIP)属性集(只读、系统、ROM),不能简单地替换。虽然可以在顶部复制同名文件,但这会隐藏原始文件。如果删除在顶部复制的文件,则原始文件将返回。所有XIP文件都是这样

我建议您使用SysCache dir替换这些文件。这将适用于所有文件替换,无论它们是XIP、驱动程序、DLL、正在使用中还是锁定以进行替换

如果在syscache dir中放置与原始文件同名的文件,则将使用这些文件而不是原始文件。但在将文件放入syscache目录后,必须预热设备。Windows CE/Mobile将仅在操作系统启动期间识别和“使用”系统缓存文件

syscache dir的位置可能会有所不同,具体取决于操作系统版本和OEM决策。在WM 6设备上,它应该是\Windows\System\syscache。检查设备的文件系统以查找现有的syscache目录


顺便说一句:字体文件不需要放在\Windows\Fonts中,可以放在\Windows中。

实际上,它是一种自定义字体,不属于操作系统映像的一部分。我想问题在于,当后台服务试图替换字体时,应用程序在前台使用字体运行。无论如何,谢谢你对XIP文件的提示。web上的syscache目录中是否有任何资源?我找不到任何资源。你只需搜索“windows ce系统缓存”的web,你就会找到许多资源(不仅仅是我:-)。我找到了很多关于VMWare、NHibernate、windows 7和Spring的信息。。。但没有官方的MSDN文章或博客条目。不过,我会尝试一下:)