Control WPF application from another application

c#, wpf

Solution

Yes, this is possible and there are various methods available to do so. If they are both on the same network you could make a TCP connection between them, both need a TCPlistener and a TCP client.

However, what I would recommend you look at is WCF. With WCF you will be able to do what you require (and probably a lot more!), but it will take a lot of reading in order to be come sufficiently familiar with the WCF library.

You can start by looking at the following:

Efficient communication between two .Net applications

Communication between two winform application using WCF?

Communication between two WPF applications

For the WCF side of things, the out line of what you need to do is:

A. Open a `ServiceHost` in each of the applications (in their constructors) using the same URIs as a reference. This will open a `NetNamedPipeBinding` with which you can communicate between the two applications.

Example:

public static ServiceHost OpenServiceHost<T, U>(T instance, string address) 
{
    ServiceHost host = new ServiceHost(instance, new Uri[] { new Uri(address) });
    ServiceBehaviorAttribute behaviour = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
    behaviour.InstanceContextMode = InstanceContextMode.Single;
    host.AddServiceEndpoint(typeof(U), new NetNamedPipeBinding(), serviceEnd);
    host.Open();
    return host;
}

B. Create a listener on the relevant channel. This can be done in both applications to allow two way communication.

Example:

/// <summary>
/// Method to create a listner on the subscribed channel.
/// </summary>
/// <typeparam name="T">The type of data to be passed.</typeparam>
/// <param name="address">The base address to use for the WCF connection. 
/// An example being 'net.pipe://localhost' which will be appended by a service 
/// end keyword 'net.pipe://localhost/ServiceEnd'.</param>
public static T AddListnerToServiceHost<T>(string address)
{
    ChannelFactory<T> pipeFactory = 
        new ChannelFactory<T>(new NetNamedPipeBinding(), 
                                     new EndpointAddress(String.Format("{0}/{1}",
                                                                                  address, 
                                                                                  serviceEnd)));
    T pipeProxy = pipeFactory.CreateChannel();
    return pipeProxy;
}

C. Create and interface that is used in both applications and inherited in the appropriate classes. Some `IMyInterface`.

You can set up a library that can be used in the two applications to allow a consistant code base. Such a library would contain the two methods above [and more] and would be used in the two applications like:

// Setup the WCF pipeline.
public static IMyInterface pipeProxy { get; protected set;}
ServiceHost host = UserCostServiceLibrary.Wcf
    .OpenServiceHost<UserCostTsqlPipe, IMyInterface>(
        myClassInheritingFromIMyInterface, "net.pipe://localhost/YourAppName");
pipeProxy = UserCostServiceLibrary.Wcf.AddListnerToServiceHost<IMyInterface>("net.pipe://localhost/YourOtherAppName");

Where `pipeProxy` is some class inheriting from `IMyInterface`. This allows both applications to know what is being passed (if anything - in your case it will be a void, just a 'prompt' to let the applications know to do something pre-specified via the interface). Note, that I have not show how the calls are made to each application and you can work this out for yourself...

There are some blanks in the above that you will have to fill in but using everything I have provided should facilitate you to do what you require.

I hope this helps.

Problem

I have a WPF application, which I want to control from another application. I want to have some basic functionality like, setting the focus on a particular control, get the text of the control and sending text/keys to the control. Is this possible?

Original source

Related problems