如何从 command.com 启动 WPF 应用程序。我收到 FontCache 错误

发布于 2024-08-28 09:52:04 字数 2687 浏览 8 评论 0原文

我知道这并不理想,但我的限制是我有一个用 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 成功启动,使所有后续启动都成功),但尽管我们对工作站有很大的控制权,但它们都不是最佳的。

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

任何想法将不胜感激。就像我说的,我们有一些解决方法,但我很想避免它们。

谢谢!

I know this is not ideal, but my constraint is that I have a legacy application written in Clipper.

I want to launch a new, WinForms/WPF application from inside the application (to ease transition). This legacy application written in Clipper launches using:

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

The batch file contains something like this command:

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

It is launching a WinForms/WPF app that is we deploy via ClickOnce. Everything has been going well until we introduced WPF into the application. We were able to easily launch from the legacy application.

Since we have introduced WPF, however, we have the following behavior. If we launch via the Clipper application first, we get an exception when launching the application. The error text is:

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()

If we launch the application via the URL (in IE) or via the icon on the desktop first, we do not get the exception and application launches as expected.

The neat thing is that whatever we launch with first determines whether the app will launch at all. So, if we launch with legacy first, it breaks right away and we can't get the app to run even if we launch with the otherwise successful URL or icon. To get it to work, we have to logout and log back in and start it from the URL or icon.

If we first use the URL or the icon, we have no problem launching from the legacy application from that point forward (until we logout and come back in).

One other piece of information is that we are able to simulate the problem in the following fashion. If we enter a command prompt using "cmd.exe" and execute a statement to launch from a URL, we are successful. If, however, we enter a command prompt using "command.com" and we execute that same statement, we experience the breaking behavior.

We assume it is because the legacy application in Clipper uses the equivalent of command.com to create the shell to spawn the other app. We have tried a bunch of hacks like having command.com run cmd.exe or psexec and then executing, but nothing seems to work.

We have some ideas for workarounds (like making the app launch on startup so we force the successful launch from a URL, making all subsequent launches successful), but they all are sub-optimal even though we have a great deal of control over our workstations.

To reduce the chance that this is related to permissions, we have given the launching account administrative rights (as well as non-administrative rights in case that made a difference).

Any ideas would be greatly-appreciate. Like I said, we have some work arounds, but I would love to avoid them.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

霞映澄塘 2024-09-04 09:52:04

听起来当应用程序以这种方式启动时,演示字体缓存服务无法启动。
如果您可以控制客户端环境,则可以尝试将 Windows 演示字体缓存启动设置为自动而不是手动。

It sounds like the Presentation Font Cache service has trouble starting when the app is launched in this way.
If you have control over the client environment, you could try setting the Windows Presentation Font Cache startup to automatic instead of manual.

我要还你自由 2024-09-04 09:52:04

这是在黑暗中使用不完整的信息进行的尝试:

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

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

我不知道您的环境有哪些限制,但您可以尝试的一些操作是:

  • .bat 重命名为 .cmd 以确保它以 < 开头code>cmd.exe 而不是 command.com
  • 让您的 .bat 使用 start 控制台命令启动
  • 程序-WPF 程序可在更健全的环境中调用您的 WPF 程序

This is a shot in the dark made with incomplete information:

command.com and cmd.exe are quite different. AFAIK, command.com exists for legacy compatibility, so applications you run from it will run differently. I can't test anything to complete my post because I believe that command.com runs in 16-bit mode and 64bit versions of Windows (on which I'm running) don't support that mode anymore so no more command.com for me.

That being said, there should be no difference when trying to run 32-bit applications (including managed applications).

I'm not aware of what are the limitations of your environment, but some things you may try are:

  • Rename you .bat into .cmd to make sure it starts with cmd.exe rather than command.com
  • Make your .bat start the program using the start console command
  • Have a non-WPF program to invoke your WPF one with a more sane environment
瑾夏年华 2024-09-04 09:52:04

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

因此,就您的情况而言,将行 set Windir=C:\Windows 添加到 bat 文件的开头即可解决问题(假设您的 Windows 安装在 C:\Windows

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

The problem is that the windir environmental variable is not set when using command.com.

So, in your case, adding the line set windir=C:\Windows to the beginning of the bat file will solve the problem (assuming that you have your Windows instalation in C:\Windows.

An additional issue might be that the host application is running command.com in compatibility mode. The best is to list all the environmental variables after running cmd.exe (using the set command) and comparing it to the output of the set command that you set in your bat file

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文