Programming in C#, Java, and god knows what not

IsRunning

In quite a lot of code I see following check for whether thread is running or not:

public bool IsRunning {
    get {
        return (this.Thread != null)
               && (this.Thread.ThreadState == ThreadState.Running);
    }
}

This code has big chance of working except in one quite often used case - if you have Sleep() inside of your code. Once that enters your main thread loop, you cannot count on your thread being in Running state all of the time. And Sleep() might not even be in your code (e.g. it might be in some external library).

Better check would be:

public bool IsRunning {
    get {
        return (this.Thread != null)
               && ((this.Thread.ThreadState == ThreadState.Running)
               || (this.Thread.ThreadState == ThreadState.WaitSleepJoin));
    }
}

P.S. If you like to mess with IsBackground thread property, also check for ThreadState.Background.

Simplest Service

Windows service is somewhat considered relic of the past. It is just not sexy enough for users. More often than not I see business applications that need to be always on sitting in tray processing their data. And there is mandatory “do not log off” paper sitting on keyboard.

And I always hear same excuses. My version of Visual Studio does not support it (from Express clan); It is very hard to debug it; It is confusing; etc. Worst thing is that Windows services made is C# is neither hard to create nor it is (too) hard to debug. You just need to do things your way.

First thing to keep in mind is that service is just simple Windows Form application. There is no reason why you need to debug it any differently. Just go into properties and set Program.cs (or App.cs, as I like to name it) to be startup object. When code starts running, just check for command line parameter (I like to use /Interactive). If that parameter is present DO NOT use ServiceBase.Run but start background thread manually.

Other annoying thing about services is installing them via installutil. You do not need to do that either. For install just execute:

ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });

For uninstall it is:

ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });

Of course, that can be done with /Install and /Uninstall parameters on command line.

As far as threading goes there is no escape. You must have your code in different thread in order to run a service. Windows Service Manager will call your OnStart and OnStop methods but it will not wait forever for result. My preferred method is just creating static class with methods Start, Stop and Run. Start gets called from OnStart and it starts a thread that executes private Run method (new Thread(Run)). Stop method gets called from OnStop to kill the party. Yes, there is some signaling needed for properly canceling everything but there is not much more to it.

Jut check sample application and happy background grinding.

Avoiding COMException

Illustration

Imagine following scenario. You are minding your own business and calling some nice COM function. Suddenly you got COMException going on. And it is not your fault. Code is perfect, women are nice and all you have in that line is simple check (e.g. myCom.Show(handle) == NativeMethods.S_OK). To make things worse you get also “The operation was canceled by the user. (Exception from HRESULT: 0x800704C7)” (or something similar).

Ok, you admit to your self, I did press the cancel button. But this function clearly says that it will return code different than S_OK. It never says anything about any exceptions. And can COM even raise exception in my code? Aha! Real culprit must sit in COM interop layer.

Precise dose of googling (or binging) gives source of misery. Some helpful soul in .NET design team decided that COMException will be thrown whenever HRESULT returns anything that is not success. And thus, something that ought to handled by simple conditional statement (formerly known as if) is now trashing our carefully woven code. Fortunately, smart guy from same team gave us antidote in form of PreserveSig attribute. Small dose of said attribute at function call alleviates all issues.

P.S. Normal person would just say to apply PreserveSig attribute to any function whose result code is handled within your code.

P.P.S. Even smarter person would give you the code:

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[PreserveSig()]
uint Show([In, Optional] IntPtr hwndOwner);

Running .NET 3.5 Application on .NET 4 (And Beyond)

Illustration

Few days ago I tried to get my VHD Attach to run on Windows Thin PC.

Initial diagnosis was easy - there was no .NET Framework installed. While there is no way to install .NET Framework 3.5 on Windows Thin PC, .NET Framework 4.0 installs just fine.

Next run gave us another clue with System.IO.FileNotFoundException: Could not load file or assembly 'System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.

While .NET 4 is backward compatible, Microsoft made intentional decision that it will not run applications made with earlier runtimes. This is not a big issue in Windows 7. There you have 2.0, 3.5 and 4.0 installed side-by-side and each application can pick whatever it needs. However, in Windows Thin PC there is only 2.0 and 4.0. Notice that one version is missing and it was the one I needed.

To make long story short, there is solution that does not involve recompiling. Just add Application Configuration Files (App.config) and put following text into it:

<?xml version="1.0"?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" />
        <supportedRuntime version="v2.0.50727" />
    </startup>
</configuration>

This will tell application to run on .NET 4 if possible and to fallback to 3.5, 3.0 and 2.0 as a backup solution. This might not be most beautiful solution but it is a solution that works.

P.S. Yes, supportedRuntime cannot distinguish between .NET 2.0, 3.0 and 3.5.

Renaming a File

Renaming a file is quite simple job in C#. You can just call File.Move(oldPath, newPath) and it works. That is until it doesn’t. Problem with this function is that it cannot rename file that differs only in case. E.g. test cannot be renamed to Test. And believe it or not, people sometime want to change case of their file.

Solution that first comes to mind is renaming file to something temporary and then back. E.g. test will be renamed to test-temp and then back to Test. While this solution works it makes exception handling annoying. Just what are you supposed to do if there is exception after you already created test-temp?

Fortunatelly Windows API is not so restrictive. Things can be as simple as calling MoveFile function. Or in our case MoveFileEx with parameters that ensure that we can move between volumes (MOVEFILE_COPY_ALLOWED) and that function returns only after work is done (MOVEFILE_WRITE_THROUGH). Quite straightforward code indeed:

public static void MovePath(string currentPath, string newPath) {
    if (currentPath.StartsWith(@"\\?\", StringComparison.Ordinal) == false) { currentPath = @"\\?\" + currentPath; }
    if (newPath.StartsWith(@"\\?\", StringComparison.Ordinal) == false) { newPath = @"\\?\" + newPath; }
    if (NativeMethods.MoveFileExW(currentPath, newPath, NativeMethods.MOVEFILE_COPY_ALLOWED | NativeMethods.MOVEFILE_WRITE_THROUGH) ==  false) {
        var ex = new Win32Exception();
        throw new IOException(ex.Message, ex);
    }
}

internal static class NativeMethods {
    public const uint MOVEFILE_COPY_ALLOWED = 0x02;
    public const uint MOVEFILE_WRITE_THROUGH = 0x08;


    [DllImportAttribute("kernel32.dll", EntryPoint = "MoveFileExW", SetLastError=true)]
    [return: MarshalAsAttribute(UnmanagedType.Bool)]
    public static extern bool MoveFileExW([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpExistingFileName, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpNewFileName, uint dwFlags);
}

OpenFolderDialog

Illustration

I hate FolderBrowserDialog. It is limited, ugly and stuck in Windows 2000 GUI. Whenever I had to select folder, I would resort to using SaveFileDialog instead. User would select any file name and I would just use directory part. It was non-optimal but still better than FolderBrowserDialog.

Vista brought new common file dialogs but I pretty much ignored them - most of my programs need to run under XP so there was not much benefit in using Windows Vista specific controls. However, those controls had special mode that finally brings folder selection in normal FileOpenDialog.

Code (after you define all needed COM interfaces) is actually quite straightforward. Once FOS_PICKFOLDERS is set, half of work is done. All other code is just plumbing to show the form and get user’s selection in form of path.

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

Full code with Windows XP compatibility and little bit more error checking is available for download. However do notice that all unneeded COM fat has been trimmed in order to have it concise. Short and sweet I say.

[2012-02-12: Fixed bug in source code.]

Downloading File With Progress

As I was creating upgrade procedure for few programs of mine I had a need to download file. With progress bar. Most of you can already see a solution: HttpWebRequest in BackgroundWorker.

Base idea is creation of HttpWebRequest, getting it’s response as stream and iterating through all bytes until we read them all. Heart of (DoWork) code is:

var request = (HttpWebRequest)HttpWebRequest.Create(url);
using (var response = (HttpWebResponse)request.GetResponse()) {
    using (var stream = response.GetResponseStream()) {
        using (var bytes = new MemoryStream()) {
            var buffer = new byte[256];
            while (bytes.Length < response.ContentLength) {
                var read = stream.Read(buffer, 0, buffer.Length);
                if (read > 0) {
                    bytes.Write(buffer, 0, read);
                    bcwDownload.ReportProgress((int)(bytes.Length * 100 / len));
                } else {
                    break;
                }
            }
        }
    }
}

Before we send result back to RunWorkerCompleted event we need to get file name that was actually delivered. While this step is optional, I find it especially useful if there are some redirections on web site (e.g. pointing you to newer version of file):

[csharp highlight=“1”] string fileName = response.ResponseUri.Segments[response.ResponseUri.Segments.Length - 1]; e.Result = new DownloadResult(fileName, bytes.ToArray()); [/csharp]

P.S. Do notice that DownloadResult is our own class - there is no such class in .NET Framework.

In RunWorkerCompleted we only must save file as such:

var res = (DownloadResult)e.Result;
var file = new FileInfo(res.FileName);
using (var frm = new SaveFileDialog() { FileName = file.Name }) {
    if (frm.ShowDialog(this) == DialogResult.OK) {
        File.WriteAllBytes(frm.FileName, res.Bytes);
        MessageBox.Show(this, "Done.", "Something", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

And with that you have your file downloaded.

Full source code (with all missing parts of code) is available for download.

Mercurial Keyring

There is one non-intuitive thing with securing Mercurial. You should remove all authentication data from URL and TortoiseHg will actively enforce it (assuming that you are Yes guy). However even with mercurial_keyring extension enabled it will ask for a user name and password. And it will ask every time you push.

Don’t worry. It isn’t that mercurial_keyring extension is broken, we are just missing some data in %USERPROFILE%\mercurial.ini configuration file:

[extensions]
mercurial_keyring = 

[auth]
bb.schemes = http https
bb.prefix = bitbucket.org
bb.username = jmedved

Example above is something I use for BitBucket but it is applicable for any other server. Only thing that needs to change is prefix (bb in this case) that needs to be unique within configuration file and prefix of your server.

Drag & Drop

It is sad how often I see applications that could have use of drag&drop mechanism but are blissfully unaware of it. Sad part is that half of those annoying applications are mine. :)

And it is annoyingly easy to implement. In addition to setting AllowDrop=true on your favorite control or form you need to implement two events:

private void list_DragEnter(object sender, DragEventArgs e) {
    e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Move : DragDropEffects.None;
}

private void list_DragDrop(object sender, DragEventArgs e) {
    if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
        var files = (string[])e.Data.GetData(DataFormats.FileDrop);
        DoSomething(files);
    }
}

And this is all there is to it.

Ping

Few days ago I needed to check whether certain server was dead or alive. Any network guy will tell you that ping is your mate. While he also might tell you that ping might not work at all times (damn you firewall) I will ignore this unfortunate part for a moment. Suffice to say that ping works for my scenario.

While I used to solve this issues with good old P/Interop, I decided to check whether .NET Framework 3.5 (one that I used) is smarter that old grandpa 2.0. And what do you know, there is Ping class available inside System.Net.NetworkInformation namespace.

Class was made by someone who clearly hadn’t read Framework Design Guidelines but it does provide complete solution. At least code is easy enough:

var ping = new Ping();
var reply = ping.Send("www.example.com");
if (reply.Status == IPStatus.Success) {
    Debug.WriteLine(reply.RoundtripTime + " ms.");
}