15 July, 2010

Auto Update Agent on Windows CE (interprocess comm.)

I today needed to create an autoupdate solution for an application on a device (Win CE, Windows Mobile 6.5 Professionel). The application is to support auto update, to allow the device to always be running the latest bits. Now, this can seem a pretty trivial task, but again – you are quite limited when it comes to support on the CE-device.

The issue is not so much how to download the new files from a remote server. The issue is more how do I shutdown an application in a nice way to be allowed to update parts of this application and next restart the application (in the illustration: how does ProcessB kill ProcessA?). Of course you could enumerate the processlist and invoke KILL on a process, but that would be like “pulling away the carpet” under the feet of the application. Not the best solution. I want to be allowed to inform the application that it should shutdown in it’s own pace.

The options I could come up with were these:
1) WCF
2) Interprocess Communication (named pipe)
3) Interprocess (tcp-sockets)
4) ClickOnce

 image

1) WCF
Well – this was quite a short adventure. It is not supported on CE-devices to host a WCF-service that one could call to shut down the Process (A). So, so much for that.

2) Interprocess Comm. (named pipe)
Again a pretty short adventure. Named pipes are not supported in any CE-framework.

3) Interprocess Comm. (tcp-sockets)
Now we are getting somewhere. This is supported by CE and is a viable route for this purpose.

4) ClickOnce
Again – this would have been the best solution of them all. But, ClickOnce is not supported on a CE-device.

Solution:
So we are left with option (3): Socket communication. As a POC, I made a system with 2 applications (Client to shutdown a Server). The 2 applications are seen here.

ClientCE       serverce

Server (to be shutdown, called “Process A” in above illustration):
This application does nothing (in this POC), but listening for an incoming message from the Client. Once this message is received and it contains the word “KILL”; it will gracefully shutdown after having freed resources.

Note: In a real life scenario – you would most likely want the listening part to run on a background thread. In the POC, this is run on the UI-thread hence it is pretty non-responsive when it comes to the UI of the application (as this thread is now blocked by the TcpListener!)

Code:

private void btnStart_Click(object sender, EventArgs e)
{

var ip = IPAddress.Loopback;
var listener = new TcpListener(ip, 9090);

lblStatus.Text = listener.LocalEndpoint.ToString();
listener.Start();
var client = listener.AcceptTcpClient(); //block and wait...

//if here - received data
byte[] buffer = new byte[1024]; //should be enough for now.
try
{
var ns = client.GetStream();
int index = 0;
while (true)
{
int readData = ns.Read(buffer, index, 1); //read one at the time (CHANGE)
index += readData;

if (readData == 0)
break;
}
}
finally
{
client.Close();
}

//write out buffer
string rcv = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
tbxData.Text = rcv;

bool doKill = (rcv == "KILL");

lblStatus.Text = "Stopped";
buffer = null;

if (doKill)
{
CleanUpResources(); //clean up stuff before shutting down
Application.Exit();
}
}

Client (to shutdown server, called “ProcessB” in the above illustration):
This application can ask the Server to shut down. It basically just establishes a socket connection to the Server, and tells this to shutdown. The “Command” sent is only a simple string at this time; but it could be an object that was serialized by the Client and then de-serialized on the Server side. This could carry more meaningful information.


Code:

private void btnKill_Click(object sender, EventArgs e)
{
var ip = IPAddress.Loopback;
var ipEp = new IPEndPoint(ip,9090);
var cl = new TcpClient();
cl.Connect(ipEp);

byte[] data = Encoding.ASCII.GetBytes("KILL");

cl.GetStream().Write(data, 0, data.Length);
cl.GetStream().Flush();
cl.GetStream().Close();

//done
}

6 comments:

Kevin Miller said...

It seems to me that so complicated code can understand only true IT guy!) Unfortunately I am not such type of users, thats why I use this incredible service https://yepdownload.com that makes my life easier and more comfortable.

anroidsupport.com said...

Hello! I simply wish to offer you a big thumbs up for the excellent information you have right here on this post.I am returning to your web site for more soon.

DEVELOPERS said...

Thanks for sharing nice information with us. i like your post and all you share with us is uptodate and quite informative, i would like to bookmark the page so i can come here again to read you, as you have done a wonderful job. vShare iOS 9

LETSDOIT said...

Great post I would like to thank you for the efforts you have made in writing this interesting and knowledgeable article. XmodGames iOS 11

2009 DREAM said...

This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post! Pangu

LAYS said...

This type of message always inspiring and I prefer to read quality content, so happy to find good place to many here in the post, the writing is just great, thanks for the post. Jailbreak iOS 11.3

iPhone/XCode - not all cases are equal!

This bit me! Having made some changes to an iPhone application (Obj-C); everything worked fine in the simulator. But, when deploying the s...