views:

320

answers:

2

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!

A: 

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
Miguel Ventura
The extension of the batch file does *not* change which application will execute it. Both `.bat` and `.cmd` are run with `cmd.exe`. `start` won't make any difference here either, except briefly opening another console window.
Joey
+1  A: 

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.

Robert Jeppesen