Thursday, November 6, 2008

Services for Windows Mobile in managed code

Services for Windows Mobile in managed code

Friday, April 18, 2008 @ 23:57

Services in Windows Mobile and Windows CE are DLL libraries loaded by service.exe and then run as ..... well as a services. Unfortunately these DLLs has to be written in native code. But why to use native code when man just needs little "invisible" application, that will survive Windows Mobile memory management?

ServiceApplication class

I wrote ServiceApplication class that is used in similar way as Application class in Windows Forms. In fact it is the console application with main loop that processes system messages. ServiceApplication can be controlled from outside world by interprocess messages. Simple WM_USER windows messages. The easiest service can look like this.

const int WM_USER = 0x400;
const int WM_QUIT_SERVICE = WM_USER + 5001;
const int WM_CLEAR_LOG = WM_USER + 5002;

static void Main(string[] args)
{
// Set register name
ServiceApplication.Name = "MyFirstService";

// Register messages
ServiceApplication.RegisterMessage(Interprocess.WM_QUIT_SERVICE);
ServiceApplication.RegisterMessage(Interprocess.WM_CLEAR_LOG);

// Set event handler for registered messages
ServiceApplication.OnRegisteredMessage +=
new ServiceApplication.RegisteredMessageEventHandler(ServiceApplication_OnRegisteredMessage);

// Start main application loop
ServiceApplication.Run();
}

There is a service name set, which is actually name of MessageWindows that represents the service. All messages to control the service is send to this MessageWindow. All messages that should be processed by service has to be registered. Whenever the registered message arrived, event is fired. Event handler may look like this.

static void ServiceApplication_OnRegisteredMessage(ref Microsoft.WindowsCE.Forms.Message message)
{
switch (message.Msg)
{
case Interprocess.WM_QUIT_SERVICE:
ServiceApplication.Exit();
break;

case Interprocess.WM_CLEAR_LOG:
ClearLogFile();
break;
}
}

Talking to service

As I mentioned earlier, service is controlled through windows messages. Following code sends message to the service.
const int WM_USER = 0x400;
const int WM_QUIT_SERVICE = WM_USER + 5001;
const int WM_CLEAR_LOG = WM_USER + 5002;

public void StopService()
{
IntPtr hwnd = FindWindow(IntPtr.Zero, "MyFirstService");
Message msg = Message.Create(hwnd, WM_QUIT_SERVICE, (IntPtr)0, (IntPtr)0);
MessageWindow.SendMessage(ref msg);
}

[DllImport("coredll.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);

Example application

ServiceApplication class is bundled in little demo application. Whole solution consists of three projects. Fisrt project CallLoggerLib is library containing ServiceApplication class and Interprocess class for communication with service. Second project is service implementation itself. Very simple CallLoggerService thats logs information about last phone call into the file. Third project CallLogger is a simple UI application which is used to start and stop the service.

When deploying to the device all files has to be in same directory!!

Download file: CallLogger.zip [60 Kb]

CODEPLEX library

Updated at 9th June 2008.Peter Nowak did some improvements on my sample code and publish it as a complete library on Codeplex: Managed Services for Windows Mobile.

Firing thread safe events in Compact Framework

Firing thread safe events in Compact Framework

Friday, December 7, 2007 @ 09:54
Threading is one of the most important thing in application development on Windows platform. Almost none of the serious applications can run in single thread. You will always need to perform some operations on background. The only problem with threads is, when they try to share some critical resources. One of the typical case are UI elements. Whenever you try to change some UI control from different thread than UI thread you will end up with the exception.

Changing UI from thread

Before we look at the events, lets have a look at possibilities for changing UI from thread. All UI controls has methods Invoke and/or BeginInvoke. These methods accepts delegates as parameters. Invoking means, that the delegate given as the parameter will be exceuted in thread that is owner of the UI control. This will not cause parallel access to the UI resource, so no exception will be thrown.

The first option for invoking uses BeginInvoke method and WaitCallback delegate.

public partial class Form1 : Form
{
Thread thr;

public Form1()
{
InitializeComponent();
thr = new Thread(new ThreadStart(ThreadWorker2));
thr.Start();
}

private void ThreadWorker()
{
int i = 0;

while(true)
{
string message = string.Format("Value of i={0}", i++);
UpdateStatus(message);

Thread.Sleep(1000);
}
}

private void UpdateStatus(object status)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new WaitCallback(UpdateStatus), status);
return;
}

label1.Text = (string)status;
}
}
This solution is suitable for most situations where simple status reporting is required. Disadvantage of this solution is the only one argument of WaitCallback delegate. In case of multiple informations to be given, you will need to pass structure or array as the argument. Anyway, I'am still using this solution a lot.

Second option offers more scalability and more arguments to be passed, because of custom delegate instead of the WaitCallback. Following code is also part of the previous Form1 class.

public delegate void StatusEventHandler(DateTime date, string message);

private void ThreadWorker2()
{
int i = 0;

StatusEventHandler statusHandler = UpdateStatus2;

while (true)
{
string message = string.Format("Value of i={0}",i++);
this.Invoke(statusHandler, new object[] { DateTime.Now, message});
Thread.Sleep(1000);
}
}

private void UpdateStatus2(DateTime date, string message)
{
label1.Text = date.ToShortTimeString();
label1.Text += " " + message;
}

Firing thread safe events

Applications are usually splited into two or three layers, where UI and business logic are different layers. When event comes from business layer to UI layer we need to update some status or information. Problem is, if logic in business layer is running in thread. In that case, we need to catch the event and pass the status into thread safe Invokation described above. Such a design is really lousy, because UI logic must in fact rethrow the event to itself and layers are no more strictly separated.

It is necessary to fire event in business layer thread safe way, so that UI layer can immidiately show the status. Since delegates and events in Compact Framework has no Target property as it's in full .NET Framework, we need some workaround. Let's have a look at following class. It is simple worker class representing business layer. Class has UIControl property which represent the UI control that will be Invoked. So FireStatusUpdate method Invokes the control and fires the event. This means, the event will be fired in thread which owns the UIControl.

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

namespace ThreadTest
{
public class WorkerClass
{
private Thread thr;

// UI control for update
public Control UIControl { get; set; }

public delegate void StatusUpdate(DateTime dateTime, string message);
public event StatusUpdate OnStatusUpdate;

// Starts thread
public void Start()
{
thr = new Thread(new ThreadStart(MainWorker));
thr.Start();
}

// Main thread worker
public void MainWorker()
{
int i = 0;

while (true)
{
string message = string.Format("Value of i={0}", i++);
FireStatusUpdate(DateTime.Now, message);

Thread.Sleep(1000);
}
}

// Fire thread safe event
private void FireStatusUpdate(DateTime dateTime, string message)
{
// UIControl is set and OnStatusUpdate has subscriber
if (UIControl != null && OnStatusUpdate != null)
{
if (UIControl.InvokeRequired)
{
UIControl.Invoke(new StatusUpdate(FireStatusUpdate),
new object[] { dateTime, message });
return;
}

OnStatusUpdate(dateTime, message);
}
}
}
}

Following code is simple UI layer for WorkingClass.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ThreadTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

WorkerClass worker = new WorkerClass();
// add event handler
worker.OnStatusUpdate += new WorkerClass.StatusUpdate(worker_OnStatusUpdate);
// add UI control to invoke
worker.UIControl = this;
worker.Start();
}

void worker_OnStatusUpdate(DateTime dateTime, string message)
{
label1.Text = dateTime.ToLongTimeString();
label1.Text += " " + message;
}
}

Thread safe events in full framework

Following snippet shows the modification of the FireStatusUpdate method, to be used in full .NET Framework. There is no need for UIControl property, because delegates contains automaticaly filled property Target.
// Fire thread safe event
private void FireStatusUpdate(DateTime dateTime, string message)
{
// if OnStatusUpdate has subscriber
if (OnStatusUpdate != null)
{
// List all handlers
foreach (StatusUpdate handler in OnStatusUpdate.GetInvocationList())
{
// if handler target is control then Invoke it
if (handler.Target is Control)
(handler.Target as Control).Invoke(handler, new object[] { dateTime, message });
else
handler(dateTime, message);
}
}
}

Input mode in smart phone application

Input mode in smart phone application

Friday, October 5, 2007 @ 14:03
If you ever used TextBox control in smart phone application, you may found a bit confusing that input mode is selected to numbers. Entering alphabetic strings is then quite uncomfortable. Solution for this behavior is already included in .NET Compact Framework, but not so many coders knows about it.

InputModeEditor

Microsoft.WindowsCE.Forms namespace contains class InputModeEditor with single static method SetInputMode that takes two arguments. First parametr is the object that takes the input (usually TextBox), second one is the enumeration InputMode which contains values like AlphaABC, AlphaT9, Numeric etc.. Usage is obvious:
using Microsoft.WindowsCE.Forms;

......

InputModeEditor.SetInputMode(textBox1, InputMode.AlphaABC);

Compact Web Server in Compact Framework

Compact Web Server in Compact Framework

Monday, October 22, 2007 @ 15:42
Today I want to write about small class library I wrote some times ago. It is the compact web server written in C#. Class library implements functionality of the single threaded web server, which can run in Windows CE powered system as well as desktop version of Microsoft Windows. Currently only the GET method is supported, but it's possible to pass query strings and process 'em in custom code. Let's see some examples.

Configuring web server

Configuration for web server is stored in WebServerConfiguration class. Here it's possible to setup server root, listening port, IP address etc.. Important thing is the possibility to configure default files like default.html, index.html or other. Do not forget to register MIME types for files that will be handled by the web server. Setting right mime types is necessary for correct response header of the server.

Special files are those files, that need to be treat in custom method and not just send to the client. CompactWeb server supports virtual directories so you can request directory placed outside the server root.

WebServerConfiguration webConf = new WebServerConfiguration();

webConf.IPAddress = IPAddress.Any;
webConf.Port = 80;

// Folder where the web is stored
webConf.ServerRoot = @"\Inetpub";

webConf.AddDefaultFile("default.html");
webConf.AddMimeType(".htm", "text/html");
webConf.AddMimeType(".html", "text/html");
webConf.AddMimeType(".png", "image/png");
webConf.AddMimeType(".jpg", "image/jpg");
webConf.AddMimeType(".gif", "image/gif");
webConf.AddMimeType(".bmp", "image/bmp");
webConf.AddMimeType(".cgi", "text/html");

// .cgi files will be special handled
webConf.AddSpecialFileType(".cgi");

// Register virtual directory
webConf.AddVirtualDirectory("photos", @"\My Documents\Photos");
Necessary step is to setup server root physically in the file system. Simply create the folder and put the website in. file system server root

Start me up

Starting the web server is the easiest thing in whole process. Registering OnLogEvent is fine to track client connections, response sending and exceptions. OnSpecialFileType is raised whenever the file registered as special is requested by client. Delegate for this event can handle output to the client.
webServer = new WebServer(webConf);
webServer.OnLogEvent += new WebServer.LogEvent(webServer_OnLogEvent);
webServer.OnSpecialFileType += new WebServer.SpecialFileType(webServer_OnSpecialFileType);
webServer.Start();
From here, your server is running and ready to serve all files placed in the server root. sample server home page

ASP, PHP, CGI whatever you want

If it's necessary to process some files in special way, you can use delegate to OnSpecialFileType and take the control over processing. Next piece of code handles file with .cgi extension. It takes the content of the file and replace <%=RESULT%> pattern with parameter userName passed in the query string. In case that you will call following URL http://127.0.0.1/form.cgi?userNamer=Joshua the <%=RESULT%> pattern will be replaced with Joshua.
void webServer_OnSpecialFileType(CompactWeb.WebRequest webRequest, out IO.Stream outputStream)
{
outputStream = new MemoryStream();

if (webRequest.FileName == "form.cgi")
{
// Read the requested file template
FileStream sourceFile = new FileStream(webRequest.FullPath, FileMode.Open);
StreamReader streamReader = new StreamReader(sourceFile);
string response = streamReader.ReadToEnd();
streamReader.Close();
sourceFile.Close();

// Parse query string into NameValueCollection
NameValueCollection query = WebServer.ParseQueryString(webRequest.QueryString);

// Replace <%=RESULT%> with the username
string userName = query["userName"];
response = response.Replace("<%=RESULT%>", userName);

// Creat response
byte[] buffer = Encoding.ASCII.GetBytes(response);
outputStream.Write(buffer, 0, buffer.Length);
}
}
file system server root

Download and Conclusion

Complete CompactWeb class library with this sample code is possible to download here CompactWebServer.zip . Even if the code is written in compact framework it can be compiled and used with full version of .NET framework. Usage is NOT limited to windows mobile. Feel free to suggest any ideas and improvements, or change the code for your needs. I believe that you will find this library useful.

Simulate keystrokes in Windows Mobile

Simulate keystrokes in Windows Mobile

Thursday, August 2, 2007 @ 00:39
I must say that I'am always amazed how many useful things you can perform just by simulating the keystrokes in Windows Mobile. In Windows CE SDK is the function keybd_event which generates WM_KEYUP or WM_KEYDOWN message. In fact it means, that you can "broadcast" the key press through whole system. It's unbelievable how many functions is binded to the keys even if it's not physically present on the device.

On this page in MSDN you can find list of many keys supported in Windows CE systems. There are interesting keys like VK_OFF, VK_NONAME, VK_ESC, VK_KEYLOCK. To be honest much better list is in book Programming Microsoft WindowsCe .Net. So let's look on some of the keys and how to play with them.

Sending application into background

Dreaming of minimizing application in Smartphone? If you want to send your application into background, just like the the back-button do - why not press it from application. Just send the VK_ESC key (0x1B).

Showing the Today screen

How to show today screen? Simulate the "home" button which is represented by F4 key. This VK_F4 has value of 0x73.

Lock the device keys

If you want to lock the device, just like it happens after idle time - you can perform it also by key press. On the Smartphone you need VK_APP6 key (0xC6). On the Pocket PC you will use VK_F22 or VK_KEYLOCK key (0x85). Windows Mobile 6.0 has the API function SHDeviceLockAndPrompt which puts device into a lock state as well.

Preventing the device from locking or sleeping

If you are using for instance TomTom navigation and PIN lock on your device, than you are probably fed up by the screen locking after idle time. You can prevent this locking by simulating key press, so the device will think you are still working on your device. But what key to press? You may think about shift or caps-lock, BUT thEn yOyR uSeR INpuTs WiLL loOk liKE tHiS. It must be the key without affects on the input. The VK_NONAME key (0xFC). Key actually does nothing and is reserved for the future use. In my opinion, the time is here.

Turn off the device

I was really surprised that you can simulate press of the key like power button is. The VK_OFF key (0xDF) performs soft reset on Smartphone and screen off on the Pocket PC.

Activate the Speakerphone

If you will read this post from Peter Foot, you will find how VK_F16 key (0x7F) can be useful, when you want to toggle Speakerphone while talking.

Putting it into C# class

Following class encapsulates SendKey function which simulates press of specified key. Function do two P/Invoke calls to keyb_event with KEYUP and KEYDOWN parameters set. You can use this class in Compact Framework 1.0.

using System.Runtime.InteropServices;

...

public class SystemCalls
{
//See more at http://msdn2.microsoft.com/en-us/library/ms927178.aspx
public const byte VK_NONAME = 0xFC; // Do nothing
public const byte VK_ESC = 0x1B; // Smartphone back-button
public const byte VK_F4 = 0x73; // Home Screen
public const byte VK_APP6 = 0xC6; // Lock the keys on Smartphone
public const byte VK_F22 = 0x85; // Lock the keys on PocketPC (VK_KEYLOCK)
public const byte VK_F16 = 0x7F; // Toggle Speakerphone
public const byte VK_OFF = 0x7F; // Power button

///
/// Puts `key` into to global keyboard buffer
///

///
public static void SendKey(byte key)
{
const int KEYEVENTF_KEYUP = 0x02;
const int KEYEVENTF_KEYDOWN = 0x00;
keybd_event(key, 0, KEYEVENTF_KEYDOWN, 0);
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
}

[DllImport("coredll", SetLastError = true)]
private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
}
The class is static so the usage is obvious.
SystemCalls.SendKey(SystemCalls.VK_F22);

Creating shortcuts in Windows Mobile Smartphone

http://bansky.net/blog/2007/07/creating-shortcuts-in-windows-mobile-smartphone/

Creating shortcuts in Windows Mobile Smartphone

Tuesday, July 24, 2007 @ 10:44
Sometimes people ask me about differencies in Windows Mobile for Smartphone and PocketPC. Hmm, I should say Windows Mobile Standard and Professional. Well, the most significant differences are in UI, and now I know the next one. In Smartphone you are not able to create shortcuts to file on your file system. To be precise you have no option how to create it.

On pocket PC it's quite easy, just select the file in explorer, tap and click Copy. Then go to the folder where you want to place the shortcut, tap and click Paste Shortcut. Unfortunately Smartphones has no Paste Shortcut option. So, it was only matter of time when someone will ask me how to fix this glitch.

How the shortcut works?

In Windows CE (so Windows Mobile) the shortcut file is very simple plain text file. If you open some *.lnk file in notepad, you will see something like this:

42#"\Program Files\Total Commander\cecmd.exe"
The number 42 is of course Answer to Life, the Universe, and Everything. But in this case it is the length of the command placed in shortcut. So that Program Files\Total Commander\cecmd.exe without the quotes. The quotes are neccesary when the path contains spaces. Don't think that you can put qoutes everywhere. If the path has no spaces than put no quotes. Like in this example:
18#\Windows\notes.exe
The # sign is just the delimiter. In cases you want to pass some arguments to the exacutable, you can add it right after the path. Don't forget to add length of the parameters to begining number. Following examples shows executing with parameters. First one executes Total Commander and pass \Windows as the parametr. Second one executes autoprof and pass two parameters. Quotes are NOT count to the length.
51#"\Program Files\Total Commander\cecmd.exe" \Windows


27#\Windows\autoprof -s Silent

Do it from C#

The principles mentioned above is obviously very easy to rewrite into the C# code. So here is the method and example how to place short cut to Total Commander into the start menu.
/// 
/// Creates the link file
///

/// Destination of the shortcut
/// Shortcut file name
/// Parameters

/// true if link was created
private bool CreateLink(string destination, string shortCut, string parameters)
{
try
{
bool isQuoted = false;

// when path contains spaces the set quote
destination = destination.Trim();
if (destination.IndexOf(' ') > -1) isQuoted = true;


// count length. +1 for space between path and arguments
string link = destination;
int len = destination.Length + parameters.Length + 1;

// add quotes when neccesary
if (isQuoted)
link = """ + link + """;

// add parametrs if any
if (parameters != null && parameters.Length > 0)
link += " " + parameters;

// write everything into the file
FileStream fs = new FileStream(shortCut, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(len.ToString()+"#"+link);
sw.Close();
fs.Close();
}
catch
{
// Your exception handling here
return false;
}

return true;
}
Usage:
CreateLink(@"\Program Files\Total Commander\cecmd.exe",
@"\Windows\Start Menu\go windows.lnk", "\Windows");

Complete application

I wrote application called ShortcutMaker as the complete solution for creating shortcuts in smartphones. It is written in C# and uses Compact Framework 1.0, so that it will run without other requirements on WM 2003 and above. Since CF 1.0 has no support for standard file-open and folder-browsing dialogs, I utilize the one from Peter Foot. You can download it from here with examples. Those are now implementeted in OpenNETCF.

Download the instalation cabinet file: ShortcutMakerInstall.cab