Here I will post problems I and my colleagues met and solutions we found.

Wednesday, August 20, 2008

SystemEvents.PowerModeChanged Event and services

As I posted before I wrote small application to know how much time my daughter logged on computer. To do this I used SENS events. And then I noticed that numbers are to big. And the problem was that these events did not trigger when computer went to sleep or hibernate modes. And service did not stop either. .NET has SystemEvents.PowerModeChanged event that I decided to use. Surprise, it doesn't work from service. The solution was found in System.Management name space and ManagementEventWatcher class.

Here is the fragment of the code I used:



WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();


when my service started.

_watcher.Stop();

when it stopped.



void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
Log(ex.Message);
}
}


- event handler.

Sunday, August 17, 2008

InkEdit does not work when there are no recognition package for your language

It was a midnight when I got pinged by my boss from Mexico. The Ink control that we inserted into our application didn't work. And we used InkEdit.

It was tested before, everything worked fine, there were no recent changes that could break it, and I didn't have Tablet PC at home to duplicate it. We had terminal session and I just couldn't get it. It worked before.

Finally, we realized that standard pop up control (with virtual keyboard) didn't work either. And then we noticed that current language was Spanish, and then we switched to English and everything worked.

So, what they (customer) did - they changed default keyboard input to Spanish, and InkEdit stopped working. Which makes some sense, InkEdit supposed to be used to recognize what you entered, not just store pictures. If you need just store everything was scrubbled without attempting to recognize it, InkPicture should be used.

Getting File size using ContentLength when downloading from FTP server

There is a property ContentLength of class FtpWebResponse. When I wrote the code similar to example, provided by MSDN, this property always returned -1. As it turned out, it was important to read fine print. I had to set method to GetFileSize to get proper value. So, what I got in result that worked was this:

// Get file size
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_uri);
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Credentials = credential;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
long fileSize = response.ContentLength;

// Download file
request = (FtpWebRequest)WebRequest.Create(_uri);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = credential;
response = (FtpWebResponse)request.GetResponse();


And then getting stream from response etc.

Saturday, August 09, 2008

How to implement LinkControl in WPF

There is no LinkControl in WPF, so if you need to have hyperlink in your form, different approach is needed. I used this:

XAML:

<TextBlock>Go<Hyperlink NavigateUri="http://counttime.alexeyev.org" Click="Hyperlink_Click">http://counttime.alexeyev.org</Hyperlink></TextBlock>

C#:

private void Hyperlink_Click(object sender, RoutedEventArgs e)

{
Hyperlink link = (Hyperlink)sender;
Process.Start(link.NavigateUri.AbsoluteUri);
}

Thursday, August 07, 2008

InkEdit recognize in WinForms

In our recent project we used InkEdit control, and we did it in WinForms. Doing that found there are some tricky things there.

Here is the problem. Let's say I need to close modal window with this control. Before doing that I would like to call Recognize to get latest data from control. However, the procedure is not synchronized. It works this way.

Thread A: call to method recognize returns immediately.
Thread B: event Recognition is raised, if there are data to recognize.

So, I created EventWaitHandle object in thread A and set signal in thread B. Then I waited for WaitHanlde for up to 1 second. If I got event signal - there was text to get from control and if I didn't, there were just nothing new to recognize.

However, it didn't work. And the reason it didn't work was that for data to get into control, it had to get some time in main thread, which is thread A. So, I just got kind of deadlock here.

Unfortunately, I couldn't resolve the problem without call to Application.DoEvents(), which I always try to avoid.

Final Result.

Thread A:
Recognize with WaitHandle
Wait for WaitHandle signal.
If signal received - call ApplicationDoEvents.
Get value from control.

Thread B:
Event handler for Recognition set signal for EventWaitHandle.