tags:

views:

73

answers:

3

I couldn't find any close answers to this, so I'm consulting the experience of SO users:

Scenario:

I have two small C# winforms applications where one behaves as a server or host, the other as a client. They share data via SQL Server, in terms of configuration settings.

I am currently launching the client application (which only needs to run periodically) from the server application via Process.Start() and terminating it via Process.CloseMainWindow() (after finding it in the process list).

While it seems clean enough, I wondered if there's a better way.

Question:

Which way would be best to instruct the client application to shut down:

  • Continue using Process.CloseMainWindow()?
  • Implement WCF between the applications? (I would need help on how to do this.)
  • Set a variable in SQL that the client application checks for?
  • Some other way?
+1  A: 
  • Some other way?

You can use .Net Remoting.

However, you should probably use WCF instead.

SLaks
I hadn't heard of this; reading up on it now, thanks.
JYelton
I think this is a valid answer but I would also like to add that Microsoft recommends the use of WCF over Remoting, see http://stackoverflow.com/questions/1294494/is-net-remoting-really-deprecated/1294532#1294532 and http://msdn.microsoft.com/en-us/library/72x4h507%28VS.85%29.aspx.
0xA3
For such a simple bit of information, WCF seems very complicated to me, perhaps it is overkill; on the other hand, .NET remoting seems easier (so far) though I dislike the idea of using something that's "on its way out."
JYelton
I realize that WCF is a better choice. I'm just presenting another option.
SLaks
Perhaps I should ask a separate question about WCF: Is it possible to set up between two winforms applications alone? And thanks for the info.
JYelton
+1  A: 

Given that Process.CloseMainWindow() works indicates that both programs run on the same machine. Given that a true service cannot start programs that are visible on the desktop anymore indicates that your server program runs as a regular user app.

It now makes no longer any sense to have separate programs. Simply have the server create a visible window. Interaction is trivial since everything runs in one program and has access to all state of that program.

If the server processing gets in the way of keeping the client window alive then display that window on a thread. This helper class gets the job done:

using System;
using System.Threading;
using System.Windows.Forms;

static class ClientView {
    private static Form mView;

    public static void Start(Form view) {
        if (Busy) throw new InvalidOperationException("View already running");
        mView = view;
        mView.FormClosed += (o, e) => { mView = null; }
        Thread t = new Thread(() => Application.Run(view));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }
    public static void Stop() {
        if (Busy) mView.Invoke(new MethodInvoker(() => mView.Close()));
    }
    public static bool Busy { get { return mView != null; } }
}

Sample usage:

ClientView.Start(new ClientForm());
Hans Passant
I have some reasons for having them be separate applications, but this is a valid and useful idea.
JYelton
+1  A: 

Given that Process.Start(string)

A new Process component that is associated with the process resource, or null, if no process resource is started (for example, if an existing process is reused).

Process myProcess = Process.Start("client.exe");

You can then use this value to call CloseMainWindow:

myProcess.CloseMainWindow();

The only overload that doesn't return a Process component is the parameterless method.

(BTW I didn't read the comments on the question until after I posted this answer)

ChrisF
This is most similar to what I used, thanks.
JYelton