Launching WPF application using CLR hosting from C++ application

Recently, I was working with one of my developer customers. Customer's objective was to launch a WPF application from a C++ console based application.

To achieve the same the customer was using CLRHosting and launching WPF application by calling ExecuteInDefaultAppDomain method.

 

The customer developed the application, but when he tried to execute it, C++ application failed with a first chance exception on ExecuteInDefaultAppDomain and WPF application which prevented it from getting launched.

Here is the code used for CLR hosting and launching a method in assembly (WPF) by calling ExecuteInDefaultAppDomain. 

int main(int argc, _TCHAR* argv[])

{

    // Bind to the runtime.

    ICLRRuntimeHost *pClrHost = NULL;

    HRESULT hrCorBind = CorBindToRuntimeEx(

        NULL, // Load the latest CLR version available

        L"wks", // Workstation GC ("wks" or "svr" overrides)

        0, // No flags needed

        CLSID_CLRRuntimeHost,

        IID_ICLRRuntimeHost,

        (PVOID*)&pClrHost);

 

    // Construct our host control object.

    DHHostControl *pHostControl = new DHHostControl(pClrHost);

   

    // Notify the CLR that this host implements hosting managers.

    pClrHost->SetHostControl(pHostControl);

 

    // Now, start the CLR.

    HRESULT hrStart = pClrHost->Start();

    // Load an assembly and execute a method in it.

    HRESULT hrExecute = pClrHost->ExecuteInDefaultAppDomain(

        pwzAssemblyPath, pwzAssemblyName,

        pwzMethodName, pwzMethodArgs,

        &retVal);

}

pwzMethodName in the code above, is the method defined in WPF application, the purpose of this method in WPF application is to launch the WPF application itself by calling Main method while pwzAssemblyName is the name of WPF application.

The code snippet is part of following MSDN article which talks about CLR hosting:

msdn.microsoft.com/en-us/magazine/cc163567.aspx

Please note that code above can be used to launch a method from any assembly and is not specific to WPF.

Running the code outside the debugger gave the following error-

System.Windows.Markup.XamlParseException: Cannot create instance of 'Window1' defined in assembly WpfApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error in markup file 'Window1.xaml' Line 1 Position 9. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: The calling thread must be STA, because many UI components require this.

As the message clearly indicates that calling thread needs to be STA and it's known that WPF is also STA. taking the clue I used following line of code to make the C++ console based application STA.

CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);

Adding the above line of code did the trick and the WPF application launched fine!

Content By – Sumit Gupta

Comments

  • Anonymous
    August 19, 2010
    great info, always wondered about this STA business when hosting the clr. thanks!

  • Anonymous
    August 20, 2010
    Thanks Wpslider! I forgot to mention in my post that same information applies for Winforms also because its also STA. -Sumit