<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jonathan C Dickinson &#187; Top Hacks</title>
	<atom:link href="http://jonathan.dickinsons.co.za/blog/category/top-hacks/feed/" rel="self" type="application/rss+xml" />
	<link>http://jonathan.dickinsons.co.za/blog</link>
	<description>&#34;Jonathan Chayce Dickinson&#34;.ToString()</description>
	<lastBuildDate>Sat, 26 Feb 2011 14:21:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Android: Emulator Can&#8217;t Find Images</title>
		<link>http://jonathan.dickinsons.co.za/blog/2010/06/android-emulator-cant-find-images/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2010/06/android-emulator-cant-find-images/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 11:07:31 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=201</guid>
		<description><![CDATA[Fix the 'could not find virtual device named' error with Android Emulator.]]></description>
			<content:encoded><![CDATA[<p>If you are getting an error message from the Android emulator similar to:</p>
<pre class="brush: plain;">
emulator: ERROR: unknown virtual device name: 'xxx'
emulator: could not find virtual device named 'xxx'
</pre>
<p>It&#8217;s because the Android emulator works a little differently from the rest of the SDK (the rest of the SDK is Java, emulator.exe is C/++). The rest of the SDK behaves correctly in terms of user home folder (I move mine to a different hard disk) and emulator.exe has it hardcoded (depending on your OS). In Windows 7 and Vista that means it ALWAYS looks in &#8220;C:\Users\&lt;username&gt;\.android&#8221;. The fix for this is simple (in a command prompt under Vista/Win7):</p>
<pre class="brush: plain;">
C:
cd C:\Users\&lt;user name&gt;
mklink /j .android &lt;new home directory&gt;\.android
</pre>
<p>Worked for me. Source: <a href="http://forum.xda-developers.com/showpost.php?p=5612951&#038;postcount=12">XDA Developers</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2010/06/android-emulator-cant-find-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Block Toggler</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/12/code-block-toggler/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/12/code-block-toggler/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 22:42:34 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Top Hacks]]></category>
		<category><![CDATA[Tricks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=171</guid>
		<description><![CDATA[Handy snippet to switch between two code blocks.]]></description>
			<content:encoded><![CDATA[<p>I came across one of the most awesome meta-language features for C-style languages (specifically any language that has /* */ and // comment support). The nitty-gritties are up at <a href="http://theycallmemrjames.blogspot.com/2009/06/toggle-between-code-blocks.html">a rather good blog</a>. I whipped up a snippet to handle this automatically.</p>
<p>It has a few notable features &#8211; it gives a reason for the flip, it wraps it in a region, it has a auto-task FLIP: prefix and it explains how it&#8217;s used.</p>
<pre class="brush: csharp;">
            #region Flip - This new behaviour is experimental. -
            // FLIP: This new behaviour is experimental.
            //*/// Two proceding slashes will activate the first block, one will activate the second.
            Console.ReadLine();
            /*/
            Console.ReadLine();
            //*/
            #endregion Flip - This new behaviour is experimental. -
</pre>
<p>Drop it in your My Code Snippets folder. In VS select the code you want to flip-comment, Hold CTRL, Press K, Press S, Release CTRL, Press M, Press Enter, Press F, Press Enter (I wish you could assign hot keys to snippets!).</p>
<p><a href='http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/12/flipper.txt'>Code Block Flipper</a> (WordPress won&#8217;t let me upload .snippet &#8211; so you will need to rename it)</p>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/12/code-block-toggler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It Works on My Virtual Machine</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/07/it-works-on-my-virtual-machine/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/07/it-works-on-my-virtual-machine/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 07:27:37 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=125</guid>
		<description><![CDATA[It Works on My Machine for developers and QA specialists that employ virtual environments.]]></description>
			<content:encoded><![CDATA[<h2> Origin </h2>
<p>After reading <a href="http://jcooney.net/archive/2007/02/01/42999.aspx" target="_new">Joseph Cooney&#8217;s post on &#8220;Works on My Machine&#8221;</a> I was inspired to integrate this prestigious certification program into my company&#8217;s typical workflow.</p>
<h2> Introduction </h2>
<p>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 &#8220;It Works on My Virtual Machine&#8221; logo.</p>
<div id="attachment_126" class="wp-caption aligncenter" style="width: 310px"><a href="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/worksonmyvm_logo.png"><img src="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/worksonmyvm_logo-300x136.png" alt="Click for a high-res version." title="It Works on My Virtual Machine" width="300" height="136" class="size-medium wp-image-126" /></a><p class="wp-caption-text">Click for a high-res version.</p></div>
<h2>Compatibility with other Certification Programs</h2>
<p>This certification is compatible with <a href="http://jcooney.net/archive/2007/02/01/42999.aspx">&#8220;It Works on My Machine&#8221;</a>. It will not qualify and application under &#8220;It Works on My Machine&#8221; automatically, nor will &#8220;It Works on My Machine&#8221; automatically qualify an application under &#8220;It Works on My Virtual Machine&#8221;. Each certification program needs to be met independently.</p>
<h2>Technical Certification Requirements</h2>
<ol>
<li>Compile your latest application code with the relevant compiler. This should include changes from other developers.</li>
<li>Launch the application/site that has just been compiled.</li>
<li>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):
<ul>
<li>Changing CPU registers (typically the instruction pointer) by manipulating the virtual machine host.</li>
<li>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.</li>
<li>Manipulating the operating system and supplementary services (e.g. SQL) to ensure the path executes correctly.</li>
</ul>
</li>
<li>Check the code changes into your version control system.
<ul>
<li>If the snapshot feature was used, ensure you return to the original state before checking the code in.</li>
</ul>
</li>
</ol>
<h2>Notification Requirements</h2>
<p>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:</p>
<ul>
<li>Splash screen on rich clients.</li>
<li>Click-through interstitial landing page on websites.</li>
<li>Ascii art in terminals.</li>
<li>Using it to xor-encrypt sensitive data:
<ul>
<li>The character string &#8220;It Works On My Virtual Machine&#8221; (without quotes) repeated for the duration of the plaintext.</li>
<li>The byte stream of the logo image repeated for the duration of the plaintext.</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/07/it-works-on-my-virtual-machine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Remove System Menu Icon in WPF</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/07/remove-system-menu-icon-in-wpf/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/07/remove-system-menu-icon-in-wpf/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 13:40:47 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code 7 Contest]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/2009/07/remove-system-menu-icon-in-wpf/</guid>
		<description><![CDATA[Howto remove the caption bar in WPF.]]></description>
			<content:encoded><![CDATA[<p>I am entering the <a href="http://code7contest.com" target="_blank">Code7 Contest</a> and part of my project is to mimic the network notification icon.</p>
<div id="attachment_61" class="wp-caption aligncenter" style="width: 312px"><a href="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/Windows7Network.png"><img class="size-full wp-image-61" title="Windows 7 Network Menu" src="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/Windows7Network.png" alt="Windows 7 Network Menu" width="302" height="454" /></a><p class="wp-caption-text">Windows 7 Network Menu</p></div>
<p>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:</p>
<ul>
<li>Implement a template to mimic the real window template. Not too sure how glass would work here.</li>
<li>Use API calls to do it instead.</li>
</ul>
<p>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.</p>
<div class="code-header">Remove Caption in WPF</div>
<div id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:63529eaa-0ca6-4208-853f-10b57d792814" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">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 &amp;= ~WS_SYSMENU;
      currentStyle &amp;= ~WS_CAPTION;
      int ret = SetWindowLong(hwnd, GWL_STYLE, new IntPtr(currentStyle)).ToInt32();
  }

}</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>You simply call that from OnSourceInitialized.</p>
<div class="code-header">How to use the method</div>
<div id="scid:DFDE9937-D816-47f4-A306-7B60D5CE5AC0:bac81a08-a2b0-4291-9490-ade63e6320ea" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">protected override void OnSourceInitialized(EventArgs e)
{
  base.OnSourceInitialized(e);
  WindowInteropHelper wih = new WindowInteropHelper(this);
  NativeMethods.RemoveMenu(wih.Handle);
}</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>And you will get the following result:</p>
<div id="attachment_63" class="wp-caption aligncenter" style="width: 309px"><a href="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/Windows7Mimic.png"><img class="size-full wp-image-63" title="Windows 7 Mimic'ed Menu" src="http://jonathan.dickinsons.co.za/blog/wp-content/uploads/2009/07/Windows7Mimic.png" alt="Windows 7 Mimic'ed Menu" width="299" height="364" /></a><p class="wp-caption-text">Windows 7 Mimic&#39;ed Menu</p></div>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/07/remove-system-menu-icon-in-wpf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The hunt for the error in the Workflow.Targets</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/06/the-hunt-for-the-error-in-the-workflowtargets/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/06/the-hunt-for-the-error-in-the-workflowtargets/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 15:21:18 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[K2]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=27</guid>
		<description><![CDATA[How to get more helpful messages with K2 builds.]]></description>
			<content:encoded><![CDATA[<p>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 &#8211; especially when it&#8217;s something like the use of an unassigned variable.</p>
<p>The solution isn&#8217;t obvious &#8211; simply right click on suspect events and view the code (having the XOML file open is fine &#8211; no need for individual CS files). When you build with the XOML open you will get two errors for each real error &#8211; one will point to Workflow.targets and the other to the actual file (line number and everything).</p>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/06/the-hunt-for-the-error-in-the-workflowtargets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wrapping on Specific Characters</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/06/wrapping-on-specific-characters/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/06/wrapping-on-specific-characters/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 08:27:16 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Migrated]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=22</guid>
		<description><![CDATA[How to inform GDI+ that a certain character can be automatically wrapped.]]></description>
			<content:encoded><![CDATA[<p>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\&#8230;.\Foo) and not wrapping  options.</p>
<p>I wasn&#8217;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&#8217;t cut it) &#8211; 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).</p>
<p>How do we use it? Simply do the following:</p>
<div class="code-header">Wrap after backslashes</div>
<pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; "> string wrappable = unwrappable.Replace("\\", "\\\u200B");</pre>
<p>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&#8217;t usually wrap) or not wrap before/after a character (that  usually wraps) - but it was decidedly boring; so I never finished it.</p>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/06/wrapping-on-specific-characters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to close a XML Element using XmlTextWriter</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/06/how-to-close-a-xml-element-using-xmltextwriter/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/06/how-to-close-a-xml-element-using-xmltextwriter/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 08:20:34 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Migrated]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=12</guid>
		<description><![CDATA[You can't close an XML element using the XmlTextWriter class unless you write a conflicting state to the document (e.g. Comment). Here is how to get around that.]]></description>
			<content:encoded><![CDATA[<p>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):</p>
<div class="code-header">Single opening tag</div>
<pre class="brush: xml; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">&lt;stream:stream xmlns="http://etherx.jabber.org/streams"  xmlns="jabber:client" from="bob" to="server"&gt;</pre>
<p>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&#8217;t work.</p>
<p>My previous methodology used a comment to close it. Thus something like this  was sent out:</p>
<div class="code-header">Using a comment to transfer state</div>
<pre class="brush: xml; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">&lt;stream:stream xmlns="http://etherx.jabber.org/streams"  xmlns="jabber:client" from="bob" to="server"&gt;&lt;!-- Start Stream --&gt;</pre>
<p>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.</p>
<p>I finally decided to give fixing it a go. I created a root XML writer class  that had one abstract method: CompleteElement(). I won&#8217;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&#8217;t work. XmlWriter.Create() hands  out XmlWellFormedWriters (you can&#8217;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.</p>
<p>Here it is (most of it is purely wrappers):</p>
<div class="code-header">Complete Streaming XML Writer</div>
<pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">    /// &lt;summary&gt;
    /// Represents a streaming xml text writer.
    /// &lt;/summary&gt;
    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 });
        }
    }</pre>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/06/how-to-close-a-xml-element-using-xmltextwriter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TFS Build Server 2005 with VS 2008 Solutions</title>
		<link>http://jonathan.dickinsons.co.za/blog/2009/06/tfs-build-server-2005-with-vs-2008-solutions/</link>
		<comments>http://jonathan.dickinsons.co.za/blog/2009/06/tfs-build-server-2005-with-vs-2008-solutions/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 08:18:08 +0000</pubDate>
		<dc:creator>Jonathan Dickinson</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Migrated]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Top Hacks]]></category>

		<guid isPermaLink="false">http://jonathan.dickinsons.co.za/blog/?p=10</guid>
		<description><![CDATA[How to use build VS 2008 projects on TFS Build Server 2005.]]></description>
			<content:encoded><![CDATA[<p>I am currently RNDing Continuous Integration for our build process, as well  as automating certain build processes that we use throughout the company.</p>
<p>One issue that I found is that TFS Build Server 2005 plain refuses to build  Visual Studio 2008 solution files, and after some research I found that it is  because of the SLN version number. One method involves using a shim in place of  MSBuild to call the .Net 3.5 MSBuild executable. The current shims are really  weak and don&#8217;t do the job properly, so I have made one that does.</p>
<p>It handles incoming input, as well as the standard out and error streams.  This will allow MSBuild to report back to the server on things such as compile  errors.</p>
<p>To use the tool, rename shim.exe to the name of the original file (in this  case MSBuild.exe) and replace that file. Open regedit and create (or open) a key  at HKLM\Software\jonathand\Shim. In this key place a new string value with the  original file as the name and the new file as the value. The shim will now call  the file as it should. This should theoretically also help with MSTest.exe (I  think that&#8217;s the name) when it comes to integrated unit tests.</p>
<div class="code-header">Shim tool</div>
<pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true; ">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using Microsoft.Win32;
using System.Diagnostics;
using System.Threading;

namespace Shim
{
    class Program
    {
        private static Process _process;

        static int Main(string[] args)
        {
            if (TargetFile == "")
            {
                Console.Error.WriteLine("No target for shim found in registry for '{0}'.", EntryAssemblyFileName);
                return 9009; // File not found.
            }

            // Create process.
            _process = new Process();
            _process.StartInfo.Arguments = Arguments;
            _process.StartInfo.CreateNoWindow = true;
            _process.StartInfo.FileName = TargetFile;
            _process.StartInfo.RedirectStandardError = true;
            _process.StartInfo.RedirectStandardInput = true;
            _process.StartInfo.RedirectStandardOutput = true;
            _process.StartInfo.UseShellExecute = false;
            _process.StartInfo.WorkingDirectory = Environment.CurrentDirectory;

            // Wire up events.
            _process.OutputDataReceived += new DataReceivedEventHandler(_process_OutputDataReceived);
            _process.ErrorDataReceived += new DataReceivedEventHandler(_process_ErrorDataReceived);
            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            _process.Start();
            _process.BeginErrorReadLine();
            _process.BeginOutputReadLine();

            // Create read thread.
            Thread readThread = new Thread(ReaderWorker);
            readThread.IsBackground = true; // Terminate when I terminate.
            readThread.Start();

            _process.WaitForExit();

            return _process.ExitCode;
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            e.Cancel = true;
            _process.Kill();
        }

        static void ReaderWorker()
        {
            while (true)
            {
                string data = Console.ReadLine();
                _process.StandardInput.WriteLine(data);
            }
        }

        static void _process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.Error.WriteLine(e.Data);
        }

        static void _process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.Out.WriteLine(e.Data);
        }

        private static string _targetFile;
        private static string TargetFile
        {
            get
            {
                if (_targetFile == null)
                {
                    using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\jonathand\\Shim"))
                    {
                        if (key == null)
                            _targetFile = "";
                        else
                            _targetFile = (string)key.GetValue(EntryAssembly.ToLowerInvariant(), "");
                    }
                }
                return _targetFile;
            }
        }

        private static string _arguments;
        private static string Arguments
        {
            get
            {
                if (_arguments == null)
                {
                    _arguments = Environment.CommandLine;
                    int remString = EntryAssembly.Length + 1;
                    if (_arguments.StartsWith("\""))
                        remString += 2;
                    _arguments = _arguments.Remove(0, remString);
                }
                return _arguments;
            }
        }

        private static string _entryAssembly;
        static string EntryAssembly
        {
            get
            {
                if (_entryAssembly == null)
                {
                    _entryAssembly = Assembly.GetExecutingAssembly().CodeBase;
                    if (_entryAssembly.StartsWith("file:///"))
                        _entryAssembly = _entryAssembly.Remove(0, 8);
                    _entryAssembly.Replace('/', Path.DirectorySeparatorChar);
                }
                return _entryAssembly;
            }
        }

        private static string _entryAssemblyFileName;
        private static string EntryAssemblyFileName
        {
            get
            {
                if (_entryAssemblyFileName == null)
                    _entryAssemblyFileName = Path.GetFileName(EntryAssembly).ToLowerInvariant();
                return _entryAssemblyFileName;
            }
        }
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://jonathan.dickinsons.co.za/blog/2009/06/tfs-build-server-2005-with-vs-2008-solutions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

