It Works on My Virtual Machine

Origin

After reading Joseph Cooney’s post on “Works on My Machine” I was inspired to integrate this prestigious certification program into my company’s typical workflow.

Introduction

The program applies only to developers and QA specialists who use virtual environments (VMWare, VPC, VirtualBox, etc.) for primary development and/or quality assurance. If the application meets the strict requirements stipulated below it may be branded with the “It Works on My Virtual Machine” logo.

Click for a high-res version.

Click for a high-res version.

Compatibility with other Certification Programs

This certification is compatible with “It Works on My Machine”. It will not qualify and application under “It Works on My Machine” automatically, nor will “It Works on My Machine” automatically qualify an application under “It Works on My Virtual Machine”. Each certification program needs to be met independently.

Technical Certification Requirements

  1. Compile your latest application code with the relevant compiler. This should include changes from other developers.
  2. Launch the application/site that has just been compiled.
  3. Set a breakpoint in the code and reach it. Use any means possible to ensure the path to the breakpoint executes, this may include (but is not limited to):
    • Changing CPU registers (typically the instruction pointer) by manipulating the virtual machine host.
    • Using the snapshot feature of the virtual machine host to return to a previous snapshot where the code path executed successfully. Depending on your virtual machine software you may have to take a snapshot before navigating to alternates.
    • Manipulating the operating system and supplementary services (e.g. SQL) to ensure the path executes correctly.
  4. Check the code changes into your version control system.
    • If the snapshot feature was used, ensure you return to the original state before checking the code in.

Notification Requirements

Customer and partners need not be informed of the branding; however, it is a preferable to place this logo in a clear location to indicate the quality of the software. Typical examples include:

  • Splash screen on rich clients.
  • Click-through interstitial landing page on websites.
  • Ascii art in terminals.
  • Using it to xor-encrypt sensitive data:
    • The character string “It Works On My Virtual Machine” (without quotes) repeated for the duration of the plaintext.
    • The byte stream of the logo image repeated for the duration of the plaintext.
Posted in Ideas, Software, Top Hacks | 1 Comment

Websites for IDIOTS

People want to make websites – they just don’t know how (honestly, it’s not that hard). The last time anyone made an attempt at website development for the masses was FrontPage. It was a disaster, we had thousands of cookie-cutter websites springing up all over the place. I will bring such calamity to the web again; although it will be more artful cookies this time round.

I like to think I am pretty familiar with website development; and I have used a wide variety of platforms (from ASP.Net to PHP to RoR). That’s what it comes down to – I know what works and what doesn’t.

Data

Ah yes, the nuts and bolts of any website (even your Wordpress blog uses it). Unfortunately you qualify as a DBA alone (and nothing else) for a reason – databases are as hard as hell to get right. If you think for one minute that you know exactly what you are doing – you are doing it wrong. How do we present this to users in an easy fashion? Something that they are familiar with? Spreadsheets! Everyone knows (or at least should know) Excel. Instead of confusing users with data relationships and so forth give it to them in the following format (more or less):

Blog Posts
Title Date Content
My first post 18 January 2009 This is my first post, I am really excited about blogging. YOU ALL SUCK!!!1!!ONE
Fish 18 January 2009 I like fish – do you.

Granted, those are pretty short and are probably a poor example. It would work like an RDBMS (think Excel but more constrained) with the following exceptions:

  • We don’t call them tables, we call them sheets.
  • Types are more user friendly. For example: short text, long text, formatted text, date, image etc.
  • Columns can have formulas; but they apply to the entire column (aggregated columns or excel formulas).
  • Users can willy-nilly alter the schema as they see fit. No constraints like RDBMS (read no-RDBMS).

Now that we have given the user data we need to give them a way to shoot themselves in the foot with it.

Design

ASP.Net has one of these fantastic features: master pages. That’s a confusing term – Word terminology will save the day ‘Templates’. Essentially you design a web page but leave bits of it as ‘todos’. If you really wanted to use tables it might look a bit like the following:

My Cool Websites
(Body placeholder) (Repeating widget)

The placeholder is where you would put the body content. For example, the body post out of the ‘Content’ column. These are fully nest-able; so you could define a template for your entire website – and then have child templates for the blog area, the product area, the home page and so forth.

Widgets? ASP.Net controls in a nutshell. The repeating widget would allow you to create something that repeats (the obvious one here would be posts). Everything would be driven by widgets – there would be no HTML (unless within the HTML widget) editing available.

Let me re-iterate that, NO HTML.

Next, any good website would use CSS. The idea here is to kindly steer users toward using (Word again) ‘Styles’. These define how things look (as CSS is supposed to), obviously the true noobies could just ignore them.

Wizards

My friend recently bought himself a printer that could print onto CDs or DVDs. It has one unique feature: down to earth wizards. The main wizard actually has an option called “I’m in a rush – just make me a label.” That’s the kind of stuff I am going to head for.

  • What type of website do you want? [Blog] [Products] [Brochure]
  • Blog
  • [Just make me a blog, I will finish it up later] [Answer some questions about how it want it to work]

I’m sure you get the idea. After working at K2 for so long I am partially poisoned – wizards will be rife.

Doing Something with Data

Once you have a design and data you need to render that. The obvious choice here would be to have special folders, for instance we could allow the user to construct an address by defining a simple format, for example:

<Date>/<Title>

Any field used in that would obviously be made ‘web safe’ by the engine. These folders would then have a single webpage that would allow the user to define how to use that data. The obvious thing here would be to drag the content into the Body placeholder.

Publish It

Why is every website today ASP/PHP/RoR/etc. based? They don’t need to be, for crying out loud. The publishing wizard will compile the entire website down to static web pages (html) and blast them to the server (or to a folder); no fuss, no expensive hosting.

Widgets

Are the most important feature. They will probably take me the longest – I would obviously need a good coverage of them. The obvious thing to do would also allow third parties to author widgets.

Well that about sums it up. Oh yes, it will have all that Office 2007 look goodness.

Posted in Programming, Software | Leave a comment

Remove System Menu Icon in WPF

I am entering the Code7 Contest and part of my project is to mimic the network notification icon.

Windows 7 Network Menu

Windows 7 Network Menu

The trick to this is to set the caption of the window to null (not empty string) and remove the system menu – at least as far as Windows Forms goes. WPF doesn’t let you do this. I had a few options:

  • Implement a template to mimic the real window template. Not too sure how glass would work here.
  • Use API calls to do it instead.

The second option seemed to be more sensible. As it turns out Windows Forms is doing quite a bit of heavy lifting under the covers – you don’t set the title to null; you actually need to remove the caption (Windows Forms does this for you). In the end it’s as simple as clearing two style flags for the Window.

Remove Caption in WPF
private class NativeMethods
{
  [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
  static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
  static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
  {
      if (IntPtr.Size == 8)
          return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
      else
          return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
  }

  [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
  private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex);
  [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
  private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
  public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
  {
      if (IntPtr.Size == 8)
          return GetWindowLongPtr64(hWnd, nIndex);
      else
          return GetWindowLongPtr32(hWnd, nIndex);
  }

  const int GWL_STYLE = (-16);
  const int WS_SYSMENU = 0x00080000;
  const int WS_CAPTION = 0x00C00000;

  public static void RemoveMenu(IntPtr hwnd)
  {
      int currentStyle = GetWindowLong(hwnd, GWL_STYLE).ToInt32();
      currentStyle &= ~WS_SYSMENU;
      currentStyle &= ~WS_CAPTION;
      int ret = SetWindowLong(hwnd, GWL_STYLE, new IntPtr(currentStyle)).ToInt32();
  }

}

You simply call that from OnSourceInitialized.

How to use the method
protected override void OnSourceInitialized(EventArgs e)
{
  base.OnSourceInitialized(e);
  WindowInteropHelper wih = new WindowInteropHelper(this);
  NativeMethods.RemoveMenu(wih.Handle);
}

And you will get the following result:

Windows 7 Mimic'ed Menu

Windows 7 Mimic'ed Menu

Posted in C#, Code 7 Contest, Programming, Top Hacks | 1 Comment

VMWare Headaches

One of the teams here uses build scripts with hardcoded paths; and while I was on that team I needed to fit in (when you are in Rome be a Roman). In a nutshell I needed a second (D) hard-disk.

That’s long gone now; so today I did some file pruning and deleted the VMDKs I used for that drive; VMWare refused to boot my machine because there was a snapshot with that file somewhere in the hierarchy.

As it turns out the snapshot was a sibling of my current one – which seems odd; logic dictates that the VMDK should only be needed for the descendants of that snapshot. In any case I had to kill nearly every snapshot to be able to boot the VM (Murphy made sure that it was the last snapshot I deleted); on top of that I needed to remove the drive and RAM file locks.

This is the first time I have had a gripe with VMWare. It wasn’t really a train smash but inconvenient at best. My snapshot nesting was getting ridiculous, so I shouldn’t really complain.

Posted in Software | Leave a comment

Getting into GTD

Getting things done is one of the concepts introduced by life hacking (where programmers apply productivity paradigms they encounter while programming to real life).

Truth be told I tried GTD but I found that it stymied my productivity. I spent most of my time running around trying to GTD instead of GTD. I recently read an article on Havard Business that said you should have 3 ‘inboxes’:

  • Follow Up – Stuff you need to follow up soon.
  • Hold – Stuff you are waiting for.
  • Archive – Important information you need to keep.

On top of that you should do quick responses immediately. It’s a great concept: but my email volume is too high for even that (I would spend my life sorting my inbox). I go for a slightly hybrid approach. I won’t be giving a click-through tutorial here: rather a broad overview.

  1. Create a folder for Archive.
  2. Create a folder for Pend (stuff that doesn’t fall under one of the others automatically).
  3. If you have any existing filters keep them – only move the target under the appropriate folder (e.g. my “Source=Someone in the Company” folder is under Pend, mailing lists go under Archive).
  4. Create two categories (Hold and Follow Up).
  5. Assign hot-keys to the categories.
  6. Create search folders for those categories.
  7. Drop those search folders into your favourite folders.

You now have hot-keys for to categorise things and views for those categories.

Email becomes manageable again!

Posted in Brutal, GTD, Ideas | 2 Comments

The hunt for the error in the Workflow.Targets

Have you ever built a K2 Workflow only to get a really helpful error pointing toward Workflow.targets? A source code file and line number would be a big help – especially when it’s something like the use of an unassigned variable.

The solution isn’t obvious – simply right click on suspect events and view the code (having the XOML file open is fine – no need for individual CS files). When you build with the XOML open you will get two errors for each real error – one will point to Workflow.targets and the other to the actual file (line number and everything).

Posted in K2, Top Hacks | Leave a comment

Wrapping on Specific Characters

Recently on a project I was working I needed to wrap on backslash characters (file and registry paths). Unfortunately the only help StringFormat can provide is intelligent trimming (e.g. C:\Program Files\….\Foo) and not wrapping options.

I wasn’t so keen on writing my own text drawing/wrapping algorithm, but how to wrap at a specific character? One of my co-workers gave me the spark I needed to figure the whole thing out: use spaces. Now, that is a hack that is visible to the user, and is plain nasty (C:\ Foo\ Bar just doesn’t cut it) – but we live in a unicode world; and unicode has some very interesting characters. The one that helps in this situation is ZERO WIDTH SPACE (U + 200B).

How do we use it? Simply do the following:

Wrap after backslashes
 string wrappable = unwrappable.Replace("\\", "\\\u200B");

That will allow wraps after backslashes. I am sure you could find non-wrap counterparts for most wrap characters as well (e.g. NON BREAK SPACE). I started writing a util class to allow you to wrap before/after any character (that doesn’t usually wrap) or not wrap before/after a character (that usually wraps) - but it was decidedly boring; so I never finished it.

Posted in C#, Migrated, Programming, Top Hacks | Leave a comment

Unbox Enum as an Integral Value

I needed a way to get the integral value of an System.Enum that is boxed. The solution wasn’t immediately obvious after my experimentation mainly because:

  • My enum was derived from byte (and I was trying to cast it to an int).
  • My .Net jitsu wasn’t up to scratch.

Lucky thanks to a friendly guy called Guffa I managed to create generic solution.

As it turns out you can unbox an enum value to its base type. As such the following can be unboxed to an uint.

Unboxing an enum when the underlying type is known
struct FoolishStruct : uint
{
   Gluttony,
   Pride,
   Jealousy
}

object sinner = FoolishStruct.Gluttony;
uint value = (uint)sinner; // This works.

This gave me the necessary knowledge to hash out the following solution:

Unboxing an enum when the underlying type is not known
    /// <summary>
    /// Gets the integral value of an enum.
    /// </summary>
    /// <param name="value">The enum to get the integral value of.</param>
    /// <returns></returns>
    public static T ToIntegral<T>(this object value)
    {
        if(object.ReferenceEquals(value, null))
            throw new ArgumentNullException("value");
        Type rootType = value.GetType();
        if (!rootType.IsEnum)
            throw new ArgumentOutOfRangeException("value", "value must be a boxed enum.");
        Type t = Enum.GetUnderlyingType(rootType);

        switch (t.Name.ToUpperInvariant())
        {
            case "SBYTE":
                return (T)Convert.ChangeType((sbyte) value, typeof(T));
            case "BYTE":
                return (T) Convert.ChangeType((byte) value, typeof(T));
            case "INT16":
                return (T) Convert.ChangeType((Int16) value, typeof(T));
            case "UINT16":
                return (T) Convert.ChangeType((UInt16) value, typeof(T));
            case "INT32":
                return (T) Convert.ChangeType((Int32) value, typeof(T));
            case "UINT32":
                return (T) Convert.ChangeType((UInt32) value, typeof(T));
            case "INT64":
                return (T) Convert.ChangeType((Int64) value, typeof(T));
            case "UINT64":
                return (T) Convert.ChangeType((UInt64) value, typeof(T));
            default:
                throw new NotSupportedException();
        }
    }

HTH.

Posted in C#, Migrated, Programming | Leave a comment

How to Use Is.Gd/Tiny Url/Bookmarklet-X in Chrome

This morning I got sick of having to constantly open my bookmark toolbar to use Is.Gd (it just messes with the zen of Chrome) so I tried to figure out how to have it as a shortcut.

One option is to name the bookmark something like !gd, while this works, you have to type it in and press (down) twice, then enter. Not my cup of tea.

As it turns out Chrome doesn’t really need a query for a search engine, if you make a engine with no location for the query string pressing Enter will invoke it immediately.

So here are the steps:

  1. Right click on the link.
  2. Select copy link address.
  3. (Wrench) -> Options
  4. Basics tab.
  5. To the right of “Default Search:” click Manage.
  6. Click Add.
  7. Give it a name (mine was Is.Gd)
  8. Give it a keyword (like !isgd).
  9. Paste in the URL.
  10. Ok. Close. Close.
  11. Right click the bookmark on your bookmark tab.
  12. Delete.

I tend to create bang-like keywords; just put an exclamation point in front of them.

The only shortcoming right now is that the bookmarks cant contain braces (“{” and “}”) and you may need to tweak them – a little. Jon Galloway has an ace bookmarklet that will switch MSDN to the low bandwidth view. The original format of the link is:

Original bookmarklet
javascript:
 if(document.cookie.indexOf('LoBandEnabled=yes')<0)
 {
  document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';
 }
 else
 {
  document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';
 }
 window.location.reload();

The first thing you can do is to strip off the window.location.reload();, Chrome does that in any case. The second thing you will have to do is to split it into two seperate bookmarklets.

Seperate bookmarklets
document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';

document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';

Finally turn them into methods and add the javascript prefix:

Final bookmarklets
javascript:void(document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';)

javascript:void(document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';)

You can then create two bookmarklets. Mine were !mlon and !mloff.

Posted in Migrated, Tricks, Web | Leave a comment

How to close a XML Element using XmlTextWriter

Recently with my forays into the XMPP land, I have needed to handle the case of writing out the following XML (as is, without the closing tag):

Single opening tag
<stream:stream xmlns="http://etherx.jabber.org/streams"  xmlns="jabber:client" from="bob" to="server">

Note that the tag is closed. The .Net XML writer keeps that open until you try and go into a conflicting state such as a new start tag, comment, PI, or such. Calling Flush() simply doesn’t work.

My previous methodology used a comment to close it. Thus something like this was sent out:

Using a comment to transfer state
<stream:stream xmlns="http://etherx.jabber.org/streams"  xmlns="jabber:client" from="bob" to="server"><!-- Start Stream -->

Not the best. Some clients dont like comments and the XMPP specification says that comments SHOULD NOT be used (note, not MUST NOT), so some parsers fall over.

I finally decided to give fixing it a go. I created a root XML writer class that had one abstract method: CompleteElement(). I won’t paste that class in because it is trivial. I cracked open Reflector and figured out if there was a common method in XmlTextWriter that handles this. I was in luck, there was (AutoComplete)! My first attempt simply reflected over the XmlTextWriter and found the method, enum and enum field. It didn’t work. XmlWriter.Create() hands out XmlWellFormedWriters (you can’t instantiate these directly, the class is internal). So I looked at it using Reflector and I was in luck again! The only thing that is different is the name of the method (AdvanceState) and everything else was exactly the same.

Here it is (most of it is purely wrappers):

Complete Streaming XML Writer
    /// <summary>
    /// Represents a streaming xml text writer.
    /// </summary>
    public class StreamingXmlTextWriter : StreamingXmlWriter
    {
        private static object __autoCompleteComment;
        private static MethodInfo __autoCompleteMethod;

        static StreamingXmlTextWriter()
        {
            // Get the type.
            Type wellFormedWriter = typeof(XmlTextWriter).Assembly.GetType("System.Xml.XmlWellFormedWriter");

            // Find the method.
            __autoCompleteMethod = wellFormedWriter.GetMethod("AdvanceState", BindingFlags.Instance | BindingFlags.NonPublic);

            // Find the argument.
            Type tokenEnum = wellFormedWriter.GetNestedType("Token", BindingFlags.NonPublic);
            FieldInfo tokenField = tokenEnum.GetField("Comment", BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            __autoCompleteComment = tokenField.GetValue(null);
        }

        private XmlWriter writer;
        public StreamingXmlTextWriter(Stream stream, Encoding encoding)
            : base(stream, encoding)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = encoding;
            settings.OmitXmlDeclaration = true;

            writer = XmlWriter.Create(stream, settings);
        }

        #region Wrapped Methods
        public override void Close()
        {
            writer.Close();
        }

        public override void Flush()
        {
            writer.Flush();
        }

        public override string LookupPrefix(string ns)
        {
            return writer.LookupPrefix(ns);
        }

        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            if (skippedAttribute)
                return;

            writer.WriteBase64(buffer, index, count);
        }

        public override void WriteCData(string text)
        {
            if (skippedAttribute)
                return;

            writer.WriteCData(text);
        }

        public override void WriteCharEntity(char ch)
        {
            if (skippedAttribute)
                return;

            writer.WriteCharEntity(ch);
        }

        public override void WriteChars(char[] buffer, int index, int count)
        {
            if (skippedAttribute)
                return;

            writer.WriteChars(buffer, index, count);
        }

        public override void WriteComment(string text)
        {
            writer.WriteComment(text);
        }

        public override void WriteDocType(string name, string pubid, string sysid, string subset)
        {
            writer.WriteDocType(name, pubid, sysid, subset);
        }

        public override void WriteEndAttribute()
        {
            if (skippedAttribute)
            {
                skippedAttribute = false;
                return;
            }

            writer.WriteEndAttribute();
        }

        public override void WriteEndDocument()
        {
            writer.WriteEndDocument();
        }

        public override void WriteEndElement()
        {
            writer.WriteEndElement();
        }

        public override void WriteEntityRef(string name)
        {
            if (skippedAttribute)
                return;

            writer.WriteEntityRef(name);
        }

        public override void WriteFullEndElement()
        {
            writer.WriteFullEndElement();
        }

        public override void WriteProcessingInstruction(string name, string text)
        {
            writer.WriteProcessingInstruction(name, text);
        }

        public override void WriteRaw(string data)
        {
            writer.WriteRaw(data);
        }

        public override void WriteRaw(char[] buffer, int index, int count)
        {
            writer.WriteRaw(buffer, index, count);
        }

        private bool skippedAttribute;
        public override void WriteStartAttribute(string prefix, string localName, string ns)
        {
            // XSI/XSD must not be emitted.
            if (prefix == "xmlns" || localName == "xmlns")
            {
                if (localName == "xsi" || localName == "xsd")
                {
                    skippedAttribute = true;
                    return;
                }

                ApplyNamespace(prefix, localName, ref ns);
            }
            writer.WriteStartAttribute(prefix, localName, ns);
        }

        public override void WriteStartDocument(bool standalone)
        {
            writer.WriteStartDocument(standalone);
        }

        public override void WriteStartDocument()
        {
            writer.WriteStartDocument();
        }

        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            writer.WriteStartElement(prefix, localName, ns);
        }

        public override System.Xml.WriteState WriteState
        {
            get { return writer.WriteState; }
        }

        public override void WriteString(string text)
        {
            if (skippedAttribute)
                return;

            writer.WriteString(text);
        }

        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
        {
            if (skippedAttribute)
                return;

            writer.WriteSurrogateCharEntity(lowChar, highChar);
        }

        public override void WriteWhitespace(string ws)
        {
            if (skippedAttribute)
                return;

            writer.WriteWhitespace(ws);
        }

        public override XmlWriterSettings Settings
        {
            get
            {
                return writer.Settings;
            }
        }

        public override string XmlLang
        {
            get
            {
                return writer.XmlLang;
            }
        }

        public override XmlSpace XmlSpace
        {
            get
            {
                return writer.XmlSpace;
            }
        }
        #endregion

        public override void CompleteElement()
        {
            PerformAutoComplete();
        }

        private void PerformAutoComplete()
        {
            __autoCompleteMethod.Invoke(writer, new object[] { __autoCompleteComment });
        }
    }
Posted in C#, Migrated, Programming, Top Hacks | Leave a comment