【问题标题】:How do I launch a WPF app from command.com. I'm getting a FontCache error如何从 command.com 启动 WPF 应用程序。我收到 FontCache 错误
【发布时间】:2010-04-06 21:47:20
【问题描述】:

我知道这并不理想,但我的限制是我有一个用 Clipper 编写的遗留应用程序。

我想从应用程序内部启动一个新的 WinForms/WPF 应用程序(以便于过渡)。这个用 Clipper 编写的遗留应用程序使用以下命令启动:

SwpRunCmd("C:\MyApp\MyBat.bat",0)

批处理文件包含类似以下命令的内容:

C:\PROGRA~1\INTERN~1\iexplore "http://QASVR/MyApp/AppWin/MyCompany.MyApp.AppWin.application#MyCompany.MyApp.AppWin.application"

它正在启动我们通过 ClickOnce 部署的 WinForms/WPF 应用程序。在我们将 WPF 引入应用程序之前,一切都很顺利。我们能够轻松地从旧版应用程序启动。

由于我们引入了 WPF,但是,我们有以下行为。如果我们首先通过 Clipper 应用程序启动,启动应用程序时会出现异常。错误文本是:

The type initializer for 'System.Windows.FrameworkElement' threw an exception.
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Panel..ctor()
   at System.Windows.Controls.DockPanel..ctor()
   at System.Windows.Forms.Integration.AvalonAdapter..ctor(ElementHost hostControl)
   at System.Windows.Forms.Integration.ElementHost..ctor()
   at MyCompany.MyApp.AppWin.Main.InitializeComponent()
   at MyCompany.MyApp.AppWin.Main..ctor(String[] args)
   at MyCompany.MyApp.AppWin.Program.Main(String[] args)

The type initializer for 'System.Windows.Documents.TextElement' threw an exception.
   at System.Windows.FrameworkElement..cctor()

The type initializer for 'System.Windows.Media.FontFamily' threw an exception.
   at System.Windows.Media.FontFamily..ctor(String familyName)
   at System.Windows.SystemFonts.get_MessageFontFamily()
   at System.Windows.Documents.TextElement..cctor()

The type initializer for 'MS.Internal.FontCache.Util' threw an exception.
   at MS.Internal.FontCache.Util.get_WindowsFontsUriObject()
   at System.Windows.Media.FontFamily.PreCreateDefaultFamilyCollection()
   at System.Windows.Media.FontFamily..cctor()

Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString, UriKind uriKind)
   at MS.Internal.FontCache.Util..cctor()

如果我们首先通过 URL(在 IE 中)或通过桌面上的图标启动应用程序,我们不会收到异常并且应用程序会按预期启动。

巧妙的是,我们首先启动的内容决定了应用程序是否会启动。因此,如果我们首先使用旧版启动,它会立即中断,即使我们使用其他成功的 URL 或图标启动,我们也无法让应用程序运行。要让它工作,我们必须注销并重新登录,然后从 URL 或图标启动它。

如果我们首先使用 URL 或图标,那么从那时起从旧版应用程序启动(直到我们注销并重新登录)都没有问题。

另一条信息是我们能够以以下方式模拟问题。如果我们使用“cmd.exe”输入命令提示符并执行从 URL 启动的语句,我们就成功了。但是,如果我们使用“command.com”输入命令提示符并执行相同的语句,我们就会遇到中断行为。

我们认为这是因为 Clipper 中的旧版应用程序使用 command.com 的等价物来创建 shell 以生成其他应用程序。我们尝试了很多技巧,比如让 command.com 运行 cmd.exe 或 psexec 然后执行,但似乎没有任何效果。

我们有一些解决方法的想法(比如让应用在启动时启动,因此我们强制从 URL 成功启动,使所有后续启动都成功),但即使我们有很大的控制权,它们都不是最佳的在我们的工作站上。

为了减少这与权限相关的可能性,我们已授予启动帐户管理权限(以及非管理权限,以防产生影响)。

任何想法都会非常感激。就像我说的,我们有一些变通办法,但我很想避免它们。

谢谢!

【问题讨论】:

  • 我要问一个愚蠢的问题。您的应用程序以哪个版本的 .NET Framework 为目标,该版本是否安装在客户端计算机上?
  • 框架是 .NET 3.5 SP1。它安装在客户端上。此外,如果我们以正确的顺序(即直接而不是通过旧版)启动应用程序,应用程序运行良好,并且一切都按预期运行。

标签: wpf clickonce cmd command clipper


【解决方案1】:

以这种方式启动应用程序时,Presentation Font Cache 服务似乎无法启动。 如果您可以控制客户端环境,可以尝试将 Windows Presentation Font Cache 启动设置为自动而不是手动。

【讨论】:

    【解决方案2】:

    这是用不完整的信息在黑暗中拍摄的:

    command.com 和 cmd.exe 完全不同。 AFAIK,command.com 的存在是为了与旧版兼容,因此您从中运行的应用程序将以不同的方式运行。我无法测试任何东西来完成我的帖子,因为我相信 command.com 在 16 位模式下运行,而 64 位版本的 Windows(我正在运行)不再支持该模式,因此不再需要 command.com我。

    话虽如此,尝试运行 32 位应用程序(包括托管应用程序)时应该没有区别。

    我不知道您的环境有哪些限制,但您可以尝试以下方法:

    • 将您的 .bat 重命名为 .cmd 以确保它以 cmd.exe 而不是 command.com 开头
    • 使用start 控制台命令让您的.bat 启动程序
    • 拥有一个非 WPF 程序来调用您的 WPF 程序,并提供更健全的环境

    【讨论】:

    • 批处理文件的扩展名不会改变哪个应用程序将执行它。 .bat.cmd 都使用 cmd.exe 运行。 start 在这里也没有任何区别,只是短暂地打开另一个控制台窗口。
    【解决方案3】:

    问题是使用command.com时没有设置windir环境变量。

    因此,在您的情况下,将行 set windir=C:\Windows 添加到 bat 文件的开头将解决问题(假设您的 Windows 安装在 C:\Windows 中。

    另一个问题可能是主机应用程序在兼容模式下运行command.com。最好是在运行cmd.exe(使用set 命令)之后列出所有环境变量,并将其与您在bat 文件中设置的set 命令的输出进行比较

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-15
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多