如何从 command.com 启动 WPF 应用程序。我收到 FontCache 错误
我知道这并不理想,但我的限制是我有一个用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来当应用程序以这种方式启动时,演示字体缓存服务无法启动。
如果您可以控制客户端环境,则可以尝试将 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.
这是在黑暗中使用不完整的信息进行的尝试:
command.com 和 cmd.exe 有很大不同。 AFAIK,command.com 的存在是为了兼容旧版本,因此您从中运行的应用程序将以不同的方式运行。我无法测试任何内容来完成我的帖子,因为我相信 command.com 在 16 位模式下运行,而 64 位版本的 Windows(我正在运行的)不再支持该模式,因此不再支持 command.com我。
话虽如此,尝试运行 32 位应用程序(包括托管应用程序)时应该没有区别。
我不知道您的环境有哪些限制,但您可以尝试的一些操作是:
.bat
重命名为.cmd
以确保它以 < 开头code>cmd.exe 而不是command.com
.bat
使用start
控制台命令启动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:
.bat
into.cmd
to make sure it starts withcmd.exe
rather thancommand.com
.bat
start the program using thestart
console command问题是使用
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 usingcommand.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 inC:\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 runningcmd.exe
(using theset
command) and comparing it to the output of theset
command that you set in your bat file