【问题标题】:Windows Service: Install fontsWindows 服务:安装字体
【发布时间】:2016-02-14 21:11:51
【问题描述】:

我有一个应该安装字体的 Windows 服务。我有一个包含字体的文件夹,我使用以下代码安装它们:

[DllImport("gdi32.dll", EntryPoint = "AddFontResourceW", SetLastError = true)]
    public static extern int AddFontResource([In][MarshalAs(UnmanagedType.LPWStr)]
                                     string lpFileName);


var fontDestination = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), fontName);

        if (File.Exists(fontDestination))
        {
            return;
        }

        logger.Info(String.Format("Installing font: {0}", fontName));

        try
        {
            File.Copy(fontFullPath, fontDestination);

            // Retrieves font name
            var fontCollection = new PrivateFontCollection();
            fontCollection.AddFontFile(fontDestination);
            var actualFontName = fontCollection.Families[0].Name;

            //Add font
            AddFontResource(fontDestination);
            var error = Marshal.GetLastWin32Error();
            if (error == 0)
            {
                //Add registry entry
                logger.Info(String.Format("Font {0} installed successfully", fontName));
                Registry.SetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",
                    actualFontName, fontName, RegistryValueKind.String);
            }

字体将被复制到 fontDestination(Environment.GetFolderPath(Environment.SpecialFolder.Fonts)) 中,然后 AddFontResource 会将其添加到会话中。

如果我将服务作为控制台应用程序或在调试模式下运行,一切都会按预期运行。字体在记事本、word 等中可用,无需重新启动机器。 如果我安装它并将其作为服务运行,则日志确认字体安装成功,添加了注册表,该文件位于 Windows/fonts 文件夹中,但在使用它的应用程序中不可用(记事本、word、等)

如果我重新启动计算机,我怀疑 Windows 在注册表中查找,在 Windows/fonts 文件夹中看到该文件,并使其可供应用程序使用。 编辑:重启后它实际上是可用的。

我需要在不会重新启动的虚拟机上运行此服务,因此我需要在安装后立即使用字体。

我怀疑这与服务的用户权限有关。我指定该服务作为 LocalSystem 登录。

【问题讨论】:

  • “我怀疑”的哪一部分是怀疑,哪一部分实际发生了?目前的措辞表明所有部分都是推测,因此:是否重新启动后可用的字体?
  • 是的,如果它们是从 Windows 服务安装的,它们在重新启动后可用。如果我运行我在控制台应用程序中发布的代码(或将服务作为控制台应用程序运行),那么它们无需重新启动即可使用。
  • 都以管理员身份运行? (即使用管理员凭据安装的服务,控制台以管理员身份运行?)
  • 我相信您需要在用户会话的上下文中以及您自己的上下文中调用 AddFontResource。您可以使用 WTSQueryUserToken 和 CreateProcessAsUser 在用户会话中启动进程,搜索这些术语应该会找到一些示例。
  • 是的,它们都是使用管理员权限运行的。 @Harry:是的,我同时想到了这一点。谢谢,但我认为这种方法不好,我会尝试以不同于它自己的服务的方式安装字体,因为它会产生太多的开销。谢谢大家的建议。

标签: windows service fonts access-rights


【解决方案1】:

尝试禁用或重新启动字体缓存的windows服务

【讨论】:

    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    相关资源
    最近更新 更多