Soledad Pano's Blog

Just Technical Stuff

October 2007 - Posts

CCF HAT - Making use of DDAs from Legacy Adapters

Although Data Driven Adapters (DDAs) are mainly designed for Automation Adapters in HAT, we can make use of them from legacy adapters, too. Here's an example of an external VB application, which is configured to use a legacy application adapter and a WinDataDrivenAdapter with the corresponding bindings:

<?xml version="1.0" encoding="utf-16"?>

<initstring>

    <interopAssembly>

        <URL>C:\MyApp.exe</URL>

        <WorkingDirectory>C:\</WorkingDirectory>

        <hostInside />

    </interopAssembly>

    <UseTopLevelWindow class="ThunderRT6Form" />

    <adapter>

        <URL>C:\MyApplicationAdapters.dll</URL>

        <type>Microsoft.Ccf.QuickStarts.MyExtVBAppAdapter</type>

    </adapter>

    <DataDrivenAdapterBindings>

        <Type>Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter,

              Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter</Type>

        <Controls>

            <AccControl name="button1">

                <Path>

                    <Next>OK</Next>

                </Path>

            </AccControl>

        </Controls>

    </DataDrivenAdapterBindings>

    <optimumSize x="800" y="600" />

    <minimumSize x="640" y="480" />

</initstring>

 

One thing to take into account is that, if the application uses an alternative top level window, the DDA must be instantiated with that top level window instead of the process MainWindowHandle. The picture shows how the alternate top level window configuration is seen in the Admin Console:

And here is the code of the legacy adapter making use of the data driven adapter to automate the hosted application's UI:

using System;

using Microsoft.Ccf.Csr;

using Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter;

namespace Microsoft.Ccf.BancoGalicia.ApplicationAdapters

{

    public class MyExtVBAppAdapter : ApplicationAdapter

    {

        protected DataDrivenAdapterBase _dda;

        public override bool Initialize()

        {

            //IntPtr topLevelWnd = Process.MainWindowHandle;//this won't work for a VB app

            IntPtr topLevelWnd = GetTopLevelWndHandle();

            //Initialize Data Driven Adapter with proper top level window handle

            _dda = DataDrivenAdapterBase.CreateInstance(ApplicationInitString, topLevelWnd);

            return _dda != null;

        }

        public override bool DoAction(Action action, RequestActionEventArgs args)

        {

            switch (args.Action)

            {

                case "DefaultAction":

                    break;

                case "PressButton":

                    PressButton();

                    break;

            }

            return base.DoAction(action, args);

        }

        private void PressButton()

        {

            if (_dda.FindControl("button1"))

            {

                _dda.ExecuteControlAction("button1");

            }

        }

        //Find the top level window of the VB application (for example of class "ThunderRT6Form")

        private IntPtr GetTopLevelWndHandle()

        {

            IntPtr agentDesktopPtr = Win32API.FindWindow(null, "Agent Desktio");

            if (agentDesktopPtr != IntPtr.Zero)

            {

                IntPtr tabWindowHandle = Win32API.FindWindowByText(agentDesktopPtr, "MyApp");

                if (tabWindowHandle != IntPtr.Zero)

                {

                    return Win32API.FindWindowByText(tabWindowHandle, "MyAppTopLevelWndCaption");

                }

            }

            return IntPtr.Zero;

        }

    }

Posted: Oct 30 2007, 11:34 PM by spano | with 1 comment(s)
Filed under:
CCF 2008 Hosted Application Toolkit

The Hosted Application Toolkit (HAT) is a new component of CCF 2.6 (2008) that facilitates the task of automating the UI of the hosted applications. It consists of two main parts: the Data Driven Adapters (DDA) and the Automations (WF workflows) that automates the hosted application using the DDAs.

Data Driven Adapters

DDAs must inherit from DataDrivenAdapterBase in Microsoft.Ccf.HostedApplicationToolkit. CCF supports two implementations out of the box: WinDataDrivenAdapter and WebDataDrivenAdapter. We can inherit from any of the three to extend the DDA as necessary. The methods the DDAs expose to manipulate the hosted application UI are ExecuteControlAction, FindControl, GetControlValue and SetControlValue. These methods take a friendly name as parameter and lets the application adapters interact with the hosted application UI abstracting from the details of how to obtain the control from that friendly name. The mapping between the controls' friendly names and the directions for the DDA to finding them is called Data Driven Adapter Binding and is part of the hosted app initialization string:

<DataDrivenAdapterBindings>

    <Type>Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter</Type>

    <Controls>

        <AccControl name="okButton">

            <Path>

                <FindWindow>

                    <ControlID>15</ControlID>

                </FindWindow>

            </Path>

        </AccControl>

        <AccControl name="cancelButton">

            <Path>

                <FindWindow>

                    <ControlID>15</ControlID>

                </FindWindow>

            </Path>

        </AccControl>

    </Controls>

</DataDrivenAdapterBindings>

 

Note: It is a known issue that the initialization string of a hosted application is limited to 3902 characters. This may result a problem if several controls must be listed.

Although DDAs can be used from any custom adapter (and even outside CCF), they were mainly thought to support Automations in HAT.

 

Automations

In previous versions of CCF we could choose to use an Application Adapter to implement the actions' logic. In version 2.6 we can choose between Automation Adapter, Legacy Adapter, or no adapter at all. The Legacy Adapter is the Application Adapter from the previous versions. We can implement our own Legacy Adapter inheriting from the [Web]ApplicationAdapter class. The Automation Adapter is the adapter that makes use of the new Workflow Foundation (WF) feature. The AutomationAdapter implements the IAutomationAdapter interface. However, if we choose AutomationAdapter in the hosted app configuration in the AdminConsole, we can't choose our own implementation of IAutomationAdapter.

If a hosted application is configured to use the AutomationAdapter, we can specify a WF workflow to implement an action's logic. Workflows in HAT are called Automations.

In order to orchestrate an action automation, a set of WF Activities are provided by CCF that interact with the DDAs to access the UI controls. There are activities for calling an action in a hosted application, setting or getting a control's value, accessing the context, register for an application event, etc.

All together

The connection between the Automations and the DDAs is achieved by the AutomationBridgeService, which is in turn connected to the AutomationAdapter. As the bridge service is added to the WF runtime, it is accessible from the CCF WF activities. We can extend the set of activities and make use of this server, too.

The following diagram depicts the relationship between the components mentioned above:

 

 

 

More detailed documentation can be found in chapter 9 of the CCF 2008 Development Guide.

Posted: Oct 26 2007, 01:40 AM by spano | with 1 comment(s)
Filed under:
Silverlight article published this month

My colleagues Ariel Neisen, Federico García, Rodolfo Finochietti and I wrote the cover article of the #42 edition of the .Code Magazine (in Spanish) about Silverlight. The article talks about this new technology's fundamentals, architecture, programming tools, advanced features, code samples and a lot more.

 

Choosing the right WCF binding

A WCF binding is the endpoint component that defines how the client needs to communicate with the service. It groups settings such as underlying transport protocol, security requirements, and message encoding.

WCF provides nine built-in bindings:

  1. BasicHttpBinding: Basic web service communication. Exposes WCF services as legacy ASMX web services. Used for interoperability. No security by default.
  2. WSHttpBinding: Web services with WS-* support. Supports transactions and reliable messaging.
  3. WSDualHttpBinding: Web services with duplex contract and transaction support.
  4. WSFederationHttpBinding: Web services with federated security. Supports transactions.
  5. MsmqIntegrationBinding: Communication directly with MSMQ applications. Supports transactions.
  6. NetMsmqBinding: Communication between WCF applications by using queuing. Supports transactions.
  7. NetNamedPipeBinding: Communication between WCF applications on same computer. Supports duplex contracts and transactions.
  8. NetPeerTcpBinding: Communication between computers across peer-to-peer services. Supports duplex contracts.
  9. NetTcpBinding: Communication between WCF applications across computers. Supports duplex contracts and transactions.

Although most bindings will work on scenarios they are not designed for, it's a good practice to choose the right binding for a given endpoint. In chapter one of the "Programming WCF Services" book, Juval Lowy provides a very useful decision-activity diagram for choosing the right binding:

"The first question you should ask yourself is whether your service needs to interact with non-WCF clients. If the answer is yes, and if the client is a legacy MSMQ client, choose the MsmqIntegrationBinding that enables your service to interoperate over MSMQ with such a client. If you need to interoperate with a non-WCF client and that client expects basic web service protocol (ASMX web services), choose the BasicHttpBinding, which exposes your WCF service to the outside world as if it were an ASMX web service (that is, a WSI-basic profile). The downside is that you cannot take advantage of most of the modern WS-* protocols. However, if the non-WCF client can understand these standards, choose one of the WS bindings, such as WSHttpBinding, WSFederationHttpBinding, or WSDualHttpBinding. If you can assume that the client is a WCF client, yet it requires offline or disconnected interaction, choose the NetMsmqBinding that uses MSMQ for transporting the messages. If the client requires connected communication, but could be calling across machine boundaries, choose the NetTcpBinding that communicates over TCP. If the client is on the same machine as the service, choose the NetNamedPipeBinding that uses named pipes to maximize performance. You may fine-tune binding selections based on additional criteria such as the need for callbacks (WSDualHttpBinding) or federated security (WSFederationHttpBinding)."

You can download the book's sample chapter to read more on this subject. You would also find the diagram in Juval's article WCF Essentials - A Developer's Primer on the CoDe Magazine.  

Posted: Oct 02 2007, 12:43 AM by spano | with 5 comment(s)
Filed under:
More Posts