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.

VHD Attach 3.00 Beta 2

Illustration

It is time for second 3.00 beta. You might have noticed that there was no post about first beta at all - I forgot to write it. :)

Most notable update for 3.00 is addition of virtual disk creation. It currently allows creating only dynamic disks but fixed disks will also be supported in future.

Setup is changed a little in order to offer selection of context-menu items before application is even started. That way you can use your favorite combination from first run.

Due to popular demand there is in-application check for upgrade. It will not check automatically but only upon user’s request. In next few weeks I will push few test upgrades so keep on checking.

There is lot of small cosmetic adjustments. Like switching focus to Explorer upon attaching Bit Locker drive or drag&drop support in main window. And lets not forget that those who love analyzing virtual disks just got few more details about VHD.

Download is available on VHD Attach beta page.

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.

8 Grams of Bullshit

Illustration

My last visit to McDonald I noticed that my meal has “8 grams of whole wheat” printed on package. I was quite surprised to see US company use Système international d’unités to express how much of health they pack in the box.

To put things into perspective 8 grams is almost 4 times less than legal amount of marijuana in California. That whole grain thing is really potent stuff indeed.

While someone might say that McDonald is not doing anything wrong and that this is just reporting fact I would not agree. I think that this is pure game of numbers that targets USA citizens that quite often have no feeling what grams are (as I have no feeling for ounces). This is pure sham intended to represent their food as a healthy choice.

McDonald food is probably the next best thing one can do to his body after a car crash and that probably holds true for fast food in general. Of course I will grab occasional meal or two because I don’t have time for anything better and because (shame) I do like taste of it. Just please stop bullshitting be. Let my cholesterol rise in peace.

P.S. For my SI challenged USA friends 8 grams is 0.28 ounces. :)