<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Visual Basic Feng Shui</title>
  <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/" />
  <link rel="self" href="http://www.darinhiggins.com/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2010-07-24T10:51:28.300875-05:00</updated>
  <author>
    <name>Darin Higgins</name>
  </author>
  <subtitle>Hear and forget. See and remember. Do and understand.</subtitle>
  <id>http://www.darinhiggins.com/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>The Antec Sonata Case</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/07/24/TheAntecSonataCase.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,b7e69926-30bf-4e52-bcc2-faea7b8fed15.aspx</id>
    <published>2010-07-24T10:51:28.300875-05:00</published>
    <updated>2010-07-24T10:51:28.300875-05:00</updated>
    <category term="Hardware" label="Hardware" scheme="http://www.darinhiggins.com/CategoryView,category,Hardware.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_4.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="left" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_thumb_1.png" width="229" height="229" />
          </a> I’ve
always been impressed by Antec cases, and the Sonata I just picked up for my NAS box
is definitely no exception.
</p>
        <p>
First, it’s packed well. 
</p>
        <p>
It came with a bag STUFFED to the gills with screws, knobs etc. way more than you’d
ever actually need.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_thumb.png" width="244" height="184" />
          </a>I
needed some drive rails to mount a CDRom. Hmm. Didn’t have any right off hand, but
lookee here, right behind the 5.25 drive bay cover… 
</p>
        <p>
Unbelievable. Rails clipped in behind it!
</p>
        <p>
Plus, Antec uses silicone vibration isolation washers for their harddrive mounts,
and special screws for that. Good stuff.
</p>
        <p>
        </p>
        <p>
The Sonata is not quite as nice as the P182<a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/TheAntecSonataCase_989F/image_thumb_2.png" width="229" height="229" /></a>… 
</p>
        <p>
but it’s cheaper and smaller, so it fits the bill better for a NAS box with 2 drives
in it and not a lot else.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=b7e69926-30bf-4e52-bcc2-faea7b8fed15" />
      </div>
    </content>
  </entry>
  <entry>
    <title>NAS&amp;rsquo;s, The Gigabyte M68M-S2P Motherboard and gigabit Lan Ethernet speed</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/07/24/NASrsquosTheGigabyteM68MS2PMotherboardAndGigabitLanEthernetSpeed.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,0efa8015-c314-4fdc-a042-5af6f66c4db5.aspx</id>
    <published>2010-07-24T10:44:08.0665-05:00</published>
    <updated>2010-07-24T10:44:08.0665-05:00</updated>
    <category term="Hardware" label="Hardware" scheme="http://www.darinhiggins.com/CategoryView,category,Hardware.aspx" />
    <category term="Networking" label="Networking" scheme="http://www.darinhiggins.com/CategoryView,category,Networking.aspx" />
    <category term="Windows 7" label="Windows 7" scheme="http://www.darinhiggins.com/CategoryView,category,Windows%2B7.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
One small element of replacing all my equipment damaged by a lightning strike was
to figure out what to do about my NAS.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; margin: 5px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" align="left" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb.png" width="230" height="227" />
          </a> I’d
picked up a sweet little Iomega StorCenter 1TB NAS server about 4 years back and it
had served me well (despite having Seagate drives in it, ack!). But, after the strike,
it was toast. What to do?
</p>
        <p>
My first inclination was to just replace it. The Iomega units tend to be a little
on the pricy side and Fry’s had a sale on Western Digital NAS boxes, so what the heck.
I picked up a My World Book II, 2TB (Dual 1TB drives) box and came on home.<a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_4.png"><img style="border-bottom: 0px; border-left: 0px; margin: 5px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb_1.png" width="229" height="229" /></a></p>
        <p>
Brought it up, restored my backup and all was well. Till a few hours later. The NAS
just dropped off the network. I could still ping it, but couldn’t browse to it, connect
via mapped driver letter, or anything else.
</p>
        <p>
I powered the box down, and brought it back up, and all was well, for a few more hours.
Then, same problem.
</p>
        <p>
After far too long on the phone with WD’s tech support, I wrapped it up and took it
back. After a few more false starts, I eventually decided that, heck, for the cost
of 2 2TB drives, an Antec Sonata case, some ram, a Motherboard and CPU, and an OS,
I could just BUILD a NAS box for about the same money.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_6.png">
            <img style="border-bottom: 0px; border-left: 0px; margin: 5px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" align="left" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb_2.png" width="229" height="229" />
          </a>So
off I went. Settled for the Gigabyte M68M-S2P motherboard with an AMD Athlon 64 X3
tricore. Pretty smooth sailing. Got the box running, hooked it up to the network,
and then started copying files over to it.
</p>
        <p>
SSSSSSLLLLLOOOOOOWWWWWW……
</p>
        <p>
What the heck!?
</p>
        <p>
Checked the network adapter and it was auto negotiating at 10mbps! This is the onboard
gigabit Ethernet port on the Gigabyte board. Googling came up with a number of people
having similar problems but no solutions.
</p>
        <p>
I tried downloading new drivers, installing WinXP 64, and Win7 64, you name it. I
could never get the drivers to negotiate at 1gbps.
</p>
        <p>
Finally, I happened to be in the Device Manager, and right clicked on the NVidia nForce
Ethernet controller (again, I’d done this plenty of times!)
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_8.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb_3.png" width="575" height="444" />
          </a>
        </p>
        <p>
I right clicked it, selected UPDATE DRIVER SOFTWARE, then clicked BROWSE MY COMPUTER
FOR SOFTWARE.
</p>
        <p>
Then, clicked LET ME PICK FROM A LIST OF DEVICE DRIVERS ON MY COMPUTER.
</p>
        <p>
Lo and behold, I get this:
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_10.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb_4.png" width="634" height="465" />
          </a>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
The NVidia drivers were selected, since I’d installed them off the CD that came with
the motherboard, BUT there was that "Microsoft” set of drivers. I selected it, let
it install and rebooted.
</p>
        <p>
Presto, the magic 1gbps connection speed!
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_12.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/NASsTheGigabyteM68MS2PMotherboardandgiga_96DE/image_thumb_5.png" width="603" height="484" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=0efa8015-c314-4fdc-a042-5af6f66c4db5" />
      </div>
    </content>
  </entry>
  <entry>
    <title>VSTO 3 in Visual Studio 2008 under Office 2010</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/07/24/VSTO3InVisualStudio2008UnderOffice2010.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,10bd32d3-bb4c-4a0d-b686-8a62ed83f03e.aspx</id>
    <published>2010-07-24T00:09:00.377-05:00</published>
    <updated>2010-07-24T00:09:00.377-05:00</updated>
    <category term="Office" label="Office" scheme="http://www.darinhiggins.com/CategoryView,category,Office.aspx" />
    <category term="Tweaks" label="Tweaks" scheme="http://www.darinhiggins.com/CategoryView,category,Tweaks.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ok, bit of a weird combination. If you’re developing for Office 2010, you’re using
VS2010, right? Uh huh…
</p>
        <p>
Seriously, if you’re like a lot of folks, you might not be upgrading to VS2010 soon,
so Microsoft can shake the bugs out in an SP1. But still, you have an Office VSTO
addin in VS2008, that you’d like to be able to run in Office 2010, while debugging
in the VS IDE.
</p>
        <p>
If you’ve tried this without having Office 2007 installed ALSO along with the Office
2007 Primary Interops, you’ve most likely gotten a nasty message in the errors window
telling you you “can’t compile this application because Office 2007 is not installed”
or some such.
</p>
        <p>
Well, fear not. With a little tweak to your addin’s project file, you should be good
as gravy.
</p>
        <p>
Here’s the untouched section from towards the bottom of a VSTO VBProj file. Notice
the nasty line that starts with “VSTO_COMPATIBLEPRODUCTS”.
</p>
        <pre class="csharpcode">
          <span class="rem">&lt;!-- This section defines VSTO properties
that describe the host-changeable project properties. --&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectExtensions</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">VisualStudio</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">FlavorProperties</span>
          <span class="attr">GUID</span>
          <span class="kwrd">="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectProperties</span>
          <span class="attr">HostName</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">HostPackage</span>
          <span class="kwrd">="{D2B20FF5-A6E5-47E1-90E8-463C6860CB05}"</span>
          <span class="attr">OfficeVersion</span>
          <span class="kwrd">="12.0"</span>
          <span class="attr">VstxVersion</span>
          <span class="kwrd">="3.0"</span>
          <span class="attr">ApplicationType</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">Language</span>
          <span class="kwrd">="vb"</span>
          <span class="attr">TemplatesPath</span>
          <span class="kwrd">=""</span>
          <span class="attr">DebugInfoExeName</span>
          <span class="kwrd">="#Software\Microsoft\Office\12.0\Word\InstallRoot\Path#WINWORD.EXE"</span>
          <span class="attr">DebugInfoCommandLine</span>
          <span class="kwrd">="/w"</span>
          <span class="attr">AddItemTemplatesGuid</span>
          <span class="kwrd">="{2606E7C9-5071-4B63-9A83-C66A32B1669F}"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Host</span>
          <span class="attr">Name</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">IconIndex</span>
          <span class="kwrd">="0"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">HostItem</span>
          <span class="attr">Name</span>
          <span class="kwrd">="MyAddin"</span>
          <span class="attr">Code</span>
          <span class="kwrd">="Connect.vb"</span>
          <span class="attr">CanonicalName</span>
          <span class="kwrd">="AddIn"</span>
          <span class="attr">CanActivate</span>
          <span class="kwrd">="false"</span>
          <span class="attr">IconIndex</span>
          <span class="kwrd">="1"</span>
          <span class="attr">Blueprint</span>
          <span class="kwrd">="Connect.Designer.xml"</span>
          <span class="attr">GeneratedCode</span>
          <span class="kwrd">="Connect.Designer.vb"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">Host</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectClient</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">VSTO_CompatibleProducts</span>
          <span class="attr">ErrorProduct</span>
          <span class="kwrd">="This
project requires Microsoft Office Word 2007, but this application is not installed."</span>
          <span class="attr">ErrorPIA</span>
          <span class="kwrd">="This
project references the primary interop assembly for Microsoft Office Word 2007, but
this primary interop assembly is not installed."</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Product</span>
          <span class="attr">Code</span>
          <span class="kwrd">="{XX12XXXX-XXXX-XXXX-X000-X000000FF1CE}"</span>
          <span class="attr">Feature</span>
          <span class="kwrd">="WORDFiles"</span>
          <span class="attr">PIAFeature</span>
          <span class="kwrd">="WORD_PIA"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">VSTO_CompatibleProducts</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">ProjectClient</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">FlavorProperties</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">VisualStudio</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">ProjectExtensions</span>
          <span class="kwrd">&gt;</span>
        </pre>
        <p>
The trick, it turns out, is to just comment that element out completely.
</p>
        <p>
You’ll end up with this…
</p>
        <pre style="width: 494px; height: 304px" class="csharpcode">
          <span class="rem">&lt;!--
This section defines VSTO properties that describe the host-changeable project properties.
--&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectExtensions</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">VisualStudio</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">FlavorProperties</span>
          <span class="attr">GUID</span>
          <span class="kwrd">="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectProperties</span>
          <span class="attr">HostName</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">HostPackage</span>
          <span class="kwrd">="{D2B20FF5-A6E5-47E1-90E8-463C6860CB05}"</span>
          <span class="attr">OfficeVersion</span>
          <span class="kwrd">="12.0"</span>
          <span class="attr">VstxVersion</span>
          <span class="kwrd">="3.0"</span>
          <span class="attr">ApplicationType</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">Language</span>
          <span class="kwrd">="vb"</span>
          <span class="attr">TemplatesPath</span>
          <span class="kwrd">=""</span>
          <span class="attr">DebugInfoExeName</span>
          <span class="kwrd">="#Software\Microsoft\Office\12.0\Word\InstallRoot\Path#WINWORD.EXE"</span>
          <span class="attr">DebugInfoCommandLine</span>
          <span class="kwrd">="/w"</span>
          <span class="attr">AddItemTemplatesGuid</span>
          <span class="kwrd">="{2606E7C9-5071-4B63-9A83-C66A32B1669F}"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Host</span>
          <span class="attr">Name</span>
          <span class="kwrd">="Word"</span>
          <span class="attr">IconIndex</span>
          <span class="kwrd">="0"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">HostItem</span>
          <span class="attr">Name</span>
          <span class="kwrd">="MyAddin"</span>
          <span class="attr">Code</span>
          <span class="kwrd">="Connect.vb"</span>
          <span class="attr">CanonicalName</span>
          <span class="kwrd">="AddIn"</span>
          <span class="attr">CanActivate</span>
          <span class="kwrd">="false"</span>
          <span class="attr">IconIndex</span>
          <span class="kwrd">="1"</span>
          <span class="attr">Blueprint</span>
          <span class="kwrd">="Connect.Designer.xml"</span>
          <span class="attr">GeneratedCode</span>
          <span class="kwrd">="Connect.Designer.vb"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">Host</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ProjectClient</span>
          <span class="kwrd">&gt;</span>
          <span class="rem">&lt;!--
BEGIN COMMENTED OUT SECTION --&gt;</span>
          <span class="rem">&lt;!-- &lt;VSTO_CompatibleProducts
ErrorProduct="This project requires Microsoft Office Word 2007, but this application
is not installed." ErrorPIA="This project references the primary interop assembly
for Microsoft Office Word 2007, but this primary interop assembly is not installed."&gt;</span>
          <span class="rem"> &lt;Product
Code="{XX12XXXX-XXXX-XXXX-X000-X000000FF1CE}" Feature="WORDFiles" PIAFeature="WORD_PIA"
/&gt;</span>
          <span class="rem"> &lt;/VSTO_CompatibleProducts&gt;</span>
          <span class="rem"> END
OF COMMENTING --&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">ProjectClient</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">FlavorProperties</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">VisualStudio</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">ProjectExtensions</span>
          <span class="kwrd">&gt;</span>
        </pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Happy VSTOing!
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=10bd32d3-bb4c-4a0d-b686-8a62ed83f03e" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Lightning Strikes</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/07/24/LightningStrikes.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,00d0ac82-7bd7-4e65-af0f-001ea3cf16eb.aspx</id>
    <published>2010-07-23T22:57:30.986375-05:00</published>
    <updated>2010-07-23T22:57:30.986375-05:00</updated>
    <category term="Rants" label="Rants" scheme="http://www.darinhiggins.com/CategoryView,category,Rants.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
And let me tell you, in this day and age, lightning can just plain suck.
</p>
        <p>
Garage Door opener, AC units, all my computers, UPS’s, TIVO, home audio, phone systems,
NAS drives, cable box. You name it, it got smoked.
</p>
        <p>
I’ve spent the last three weeks scrambling to get new machines setup, get backups
restored (fortunately, I had recent ones), get repair techs out for the big stuff,
and take care of the smaller stuff myself.
</p>
        <p>
And I had a whole house surge suppressor, and well as UPS units on all my machines
and some of my audio gear. Smoked them all as well.
</p>
        <p>
So, any lessons learned? Oh yeah.
</p>
        <ol>
          <li>
Make SURE you know what’s covered by your UPS “<strong>connected equipment guarantee</strong>”.
Keep all that paperwork filed somewhere for quick retrieval.</li>
          <li>
Keep good records of purchases of anything you plug in. I keep mine in Quicken. Then
keep backups of your Quicken data and the program disks so you can install to another
machine and retrieve the data.</li>
          <li>
You’ll typically have about 10 days to file a claim. So keeping recent backups of
that data will help immensely with quickly pulling together all your records of what
you had, when you bought it, and how much you paid.</li>
          <li>
Check with your <strong>homeowner’s insurance</strong>. You likely have a 1% or 2%
deductable. If your house is 250,000$, that’s a sizable chunk of change you’ll be
out. And keep in mind, the insurance companies will depreciate the value of your equipment
by how long you’ve owned it, so it might be even tougher to get up to that 1 or 2%.</li>
          <li>
UPS’s can protect equipment but they won’t always work. <strong>Have backups</strong>.
Make sure they’re restorable.</li>
          <li>
You can almost be guaranteed that it’ll cost you more to replace all the equipment
that you lost than it did to buy it in the first place. Why? Because if it’s computer
stuff, you’re not going to go out and buy an exact replacement, you’ll buy something
more modern, more harddrive space, bigger monitor, faster CPU, more memory, etc. Prices
have come down since you bought, after all.</li>
        </ol>
        <p>
With the backups I had, it took a while, but I’m back online, and with almost my complete
previous setup. Still lots of little stuff to take care of, but it’s getting there.
</p>
        <p>
The good news is, we weren’t home, and there was no damage to the house itself, short
of a few blown circuit breakers, and a blown GFCI.
</p>
        <p>
In other words, lucky!
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=00d0ac82-7bd7-4e65-af0f-001ea3cf16eb" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Word and the IsObjectValid Function</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/07/24/WordAndTheIsObjectValidFunction.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,444691fb-ad11-4231-98da-dcd64806a396.aspx</id>
    <published>2010-07-23T22:37:31.955125-05:00</published>
    <updated>2010-07-23T22:39:22.986375-05:00</updated>
    <category term="Office" label="Office" scheme="http://www.darinhiggins.com/CategoryView,category,Office.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
One thing that can be maddening about programming against the Word Object Model is
that objects have a habit of “disappearing” on you.
</p>
        <p>
Say you retrieve a range, retrieve the fields in that range, then delete the range.
</p>
        <p>
You still have references to those fields, but they no longer actually exist. Attempting
to access any of the properties or methods on a field in this condition will cause
Word to throw an exception with the message “That object has been deleted”.
</p>
        <p>
Most code I’ve seen tends to handle these kinds of situations in one of two ways…
</p>
        <ol>
          <li>
Attempt to write the code such that if you’ve caused an object to become “deleted”
that you simply don’t access it after that point. Sometimes this is easier said than
done. 
</li>
          <li>
Just wrap access to the object in a Try Catch, or On Error Resume Next. Test for any
error condition and react accordingly. However, this has that nasty “the normal flow
of code is through an exception” code smell. Not pretty.</li>
        </ol>
        <p>
Fortunately, there is third way.
</p>
        <p>
The Word APPLICATION object has a function tucked away on it, called, appropriately
enough, “IsObjectValid”.
</p>
        <p>
Pass it a Word object model object and it’ll pass back true if the object is valid,
or false if it’s been deleted.
</p>
        <pre class="csharpcode">
          <span class="kwrd">Dim</span> Rng = WordApp.Content <span class="kwrd">Dim</span> Fld
= Rng.Fields(1) Rng.Delete <span class="kwrd">If</span> WordApp.IsObjectValid(Fld) <span class="kwrd">Then</span> Debug.Print
Fld.Code.Range.Text <span class="kwrd">Else</span><span class="rem">'the FLD object
is no longer valid</span><span class="kwrd">End</span> If</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Yes, it’s been around for a good long while so this may not be news to everyone, but
it’s a handy trick to have in your toolbox if you work with Word regularly.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=444691fb-ad11-4231-98da-dcd64806a396" />
      </div>
    </content>
  </entry>
  <entry>
    <title>When Debug.Print Doesn&amp;rsquo;t Work Anymore</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/06/24/WhenDebugPrintDoesnrsquotWorkAnymore.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,6d02f984-2994-4315-99f3-6a12ad333f85.aspx</id>
    <published>2010-06-23T22:55:43.614625-05:00</published>
    <updated>2010-06-23T22:55:43.614625-05:00</updated>
    <category term=".NET" label=".NET" scheme="http://www.darinhiggins.com/CategoryView,category,.NET.aspx" />
    <category term="Troubleshooting" label="Troubleshooting" scheme="http://www.darinhiggins.com/CategoryView,category,Troubleshooting.aspx" />
    <category term="VB Feng Shui" label="VB Feng Shui" scheme="http://www.darinhiggins.com/CategoryView,category,VB%2BFeng%2BShui.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is one of those “back to basics” posts that, none-the-less, tripped me up for
a few minutes, just because it’d been so long since I’d even looking at the setting
involved.
</p>
        <p>
I’d been working on a project for a while, when, one day a few weeks back, debug.print
just stopped working. Even weirder, when I’d debug, the debugging would completely
skip over the Debug.print statement.
</p>
        <p>
When it first happened, I was right in the middle of working through some other problem
and didn’t want to get sidetracked. But it hit me again a few weeks later, and I decided
to start looking around.
</p>
        <p>
It didn’t take long before I realized this setting was amiss.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/WhenDebug.PrintDoesntWorkAnymore_14257/cap1_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="cap1" border="0" alt="cap1" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/WhenDebug.PrintDoesntWorkAnymore_14257/cap1_thumb.png" width="560" height="428" />
          </a>
        </p>
        <p>
It’s checked in the image above, but in my project, somehow it’d become UNCHECKED,
and in the Debug project configuration!?
</p>
        <p>
Still not sure how that happened, other than probably got a little click happy one
day with the mouse and didn’t realize it.
</p>
        <p>
Amazing how the little things can still get ya’ sometimes…
</p>
        <p>
(and nobody say anything about my dll base address &lt;g&gt;! )
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=6d02f984-2994-4315-99f3-6a12ad333f85" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Printing a Range of Pages from a PDF file, On the Cheap</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/06/23/PrintingARangeOfPagesFromAPDFFileOnTheCheap.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,19d73ed9-095b-406b-8a53-fdb9c79187f5.aspx</id>
    <published>2010-06-22T23:30:42.2615-05:00</published>
    <updated>2010-06-22T23:30:42.2615-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lets say you need to print some pages from a PDF file. But you don’t need to print
the whole file, just a specific range, say pages 3 to the end of the document.
</p>
        <p>
And let’s say you DON’T have any of those handy (and expensive) PDF libraries available.
But of course you do have Acrobat Reader.
</p>
        <p>
And let’s say you’ve got a whole pile of these PDFs that you need to get printed.
</p>
        <p>
What to do?
</p>
        <h1>First with the Printing
</h1>
        <p>
A little digging turned up that the AcroRd32.exe application (that actual Adobe Reader
app, at least for version 9.x) can be invoked with command line parameters to print
a file and exit:
</p>
        <pre class="csharpcode">AcroRd32.exe /p /h “filenamehere.pdf”</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p align="center">
          <em>
            <font size="1">It’ll print to the current default printer, but that’s good enough
for me for this purpose.</font>
          </em>
        </p>
        <p>
Simple enough, but you can’t specify which pages to print.
</p>
        <h1>The Secret Ingredient
</h1>
        <p>
I’d almost given up on this when I came across a very handy utility called the <a href="http://www.accesspdf.com/pdftk/">PDFToolkit</a>,
by Sid Steward. PDFTK is a very small, free, command line driven utility. It won’t
print, but it can slice and dice a PDF (or multiple PDFs) just about any which way
you can dream up.
</p>
        <p>
Say you have a PDF called <em>input.pdf</em></p>
        <p>
You want to print pages 3 to the end of the file.
</p>
        <p>
So, invoke PDFTK like so:
</p>
        <pre class="csharpcode">PDFTK.exe A=input.pdf cat A3-end output scratchfile.pdf</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
and then invoke the AcroRd32.exe line from above on the resulting <em>scratchfile.pdf</em>,
and presto, your pdf is printed minus the first two pages!
</p>
        <p>
Granted, if you’re developing a commercial product (or really even an inhouse utility),
you’ll be much better served shelling out (no pun intended) a few bucks for a decent
PDF library.
</p>
        <p>
But in a pinch, PDFTK and AcroRd32 can be a pretty powerful little combination.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=19d73ed9-095b-406b-8a53-fdb9c79187f5" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Configuring Log4Net in a .net VSTO Word Addin</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/06/10/ConfiguringLog4NetInANetVSTOWordAddin.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,b0ec06bb-07ff-4b90-9f86-a0a3e207743c.aspx</id>
    <published>2010-06-09T22:12:48.219125-05:00</published>
    <updated>2010-06-09T22:12:48.219125-05:00</updated>
    <category term="Code Garage" label="Code Garage" scheme="http://www.darinhiggins.com/CategoryView,category,Code%2BGarage.aspx" />
    <category term="Installations" label="Installations" scheme="http://www.darinhiggins.com/CategoryView,category,Installations.aspx" />
    <category term="log4net" label="log4net" scheme="http://www.darinhiggins.com/CategoryView,category,log4net.aspx" />
    <category term="VB Feng Shui" label="VB Feng Shui" scheme="http://www.darinhiggins.com/CategoryView,category,VB%2BFeng%2BShui.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://msdn.microsoft.com/en-us/vsto/default.aspx">VSTO</a> (Visual Studio
Tools for Office) is a great way to put together addins for the various MS Office
applications (especially Word, Excel, and Outlook).
</p>
        <p>
And <a href="http://logging.apache.org/log4net/">Log4Net</a> is a fantastic and unbelievably
flexible logging framework for .net applications. 
</p>
        <p>
So naturally, I wanted to use them together.
</p>
        <p>
And doing so is not bad at all, till it came to configuration…
</p>
        <h1>A Disclaimer (with a note of Encouragement)
</h1>
        <p>
Log4Net is not the most straightforward package out there. It’s extremely flexible,
and very easy to work with once you’ve gotten used to it, but getting into the <em>Tao</em> of
the thing took a few days, for me, anyway.
</p>
        <p>
Don’t let that discourage you. It really is a spectacular framework for handling virtually
any aspect of logging in your applications. And it really doesn’t take much “setup
code” at all to get it operational.
</p>
        <h1>The Super Highway
</h1>
        <p>
The easiest way to configure log4net in a .net application (VSTO addins included)
is to simply call <em>Configure </em>on the <em>XMLConfigurator</em> object:
</p>
        <pre class="csharpcode">log4net.Config.XmlConfigurator.Configure()</pre>
        <p>
That’ll work, but unfortunately, since your VSTO addin is a DLL, log4net will, by
default, look in the current app.config file, which, if you’re running in Word, for
instance, will be <em>WinWord.exe.config</em> in the folder where WinWord.exe lives.
</p>
        <p>
Since WinWord.exe.config is <em>Word’s</em> config file, it’s probably not the best
idea in the world to go shoe-horning your own (or log4net’s) config stuff in there
as well. Not to mention how do you get your config information easily into that file
during installation (or properly remove it during an uninstall).
</p>
        <h1>The Scenic Byway
</h1>
        <p>
What you really want is for your VSTO addin DLL to have it’s <em>own</em> config file.
Something that lives in the same folder as your DLL itself, and can easily be installed
and removed.
</p>
        <p>
Sure enough, that Configure method has an overload that accepts a FileInfo structure
for an arbitrary XML Config file. So you can just do this:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Dim</span> MyConfigFile = <span class="kwrd">Me</span>.<span class="kwrd">GetType</span>.<span class="kwrd">Assembly</span>.ManifestModule.Name
&amp; <span class="str">".config"</span><span class="kwrd">If</span> My.Computer.FileSystem.FileExists(MyConfigFile) <span class="kwrd">Then</span><span class="kwrd">Dim</span> fi
= My.Computer.FileSystem.GetFileInfo(MyConfigFile) log4net.Config.XmlConfigurator.Configure(fi) <span class="kwrd">End</span> If</pre>
        <p>
What this does effectively is construct a filename based on the name of whatever assembly
the current code is defined within, but with a “.config” extension.
</p>
        <p>
It then checks for the existence of that file. Since there’s no path on the file,
it only looks in the current directory, but that’s fine, since the config file will
always be located in the same folder as it’s DLL.
</p>
        <p>
And finally, if the file is found, it retrieves a FILEINFO object for it and configures
Log4Net with that file.
</p>
        <h1>Bumps along the Road
</h1>
        <p>
Unfortunately, that will get you farther, but not by much.
</p>
        <p>
There are two problems.
</p>
        <ol>
          <li>
In debug mode in the IDE, the “current directory” is, indeed, the same folder as the
one with your addin DLL in it. <em>But</em>, when running in release mode, in production,
with Visual Studio completely out of the picture, the current directory is very likely
the folder where WinWord.exe is located. Not good.</li>
          <li>
Worse, in production, VSTO addins are generally copied to a “shadow cache” folder
by the .net framework, so that the original files can be upgraded in place easily
while the application is in use.</li>
        </ol>
        <p>
Unfortunately, your config will <em>will not</em> get copied to the shadow cache.
</p>
        <p>
This means that for determining where to look for your config file, using something
like:
</p>
        <ul>
          <li>
Me.GetType.Assembly.CodeBase or 
</li>
          <li>
Me.GetType.Assembly.Location</li>
        </ul>
        <p>
won’t work, because often times, they’ll point you off into the wilds of the assembly
cache folder and <em>not</em>  the \Program Files\MyCompany\MyProduct\ folder
where you installed your addin and where you most likely would prefer your MyProduct.dll.config
file to live.
</p>
        <h1>Happy Trails
</h1>
        <p>
In the end, I found the best solution to be:
</p>
        <ol>
          <li>
Look in the “current directory” for your config file.</li>
          <li>
If you find it, use it from there. This accommodated easy debugging while in the IDE
because you can easily get to and edit your config file.</li>
          <li>
If you <em>don’t</em> find it, construct the path to the app’s \Program Files\ folder
and check there.</li>
          <li>
If it’s not there either, just fall back to the default and call<em> XMLConfigurator.Configure()</em> with
no parameters and let it default everything.</li>
        </ol>
        <p>
A routine that puts all that together looks like this:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Private</span>
          <span class="kwrd">Sub</span> ConfigureLog4Net() <span class="kwrd">Dim</span> MyConfig
= <span class="kwrd">Me</span>.<span class="kwrd">GetType</span>.<span class="kwrd">Assembly</span>.ManifestModule.Name
&amp; <span class="str">".config"</span><span class="kwrd">If</span><span class="kwrd">Not</span> My.Computer.FileSystem.FileExists(MyConfig) <span class="kwrd">Then</span><span class="rem">'----
not in current dir, so check in our Program Files folder</span><span class="kwrd">Dim</span> pth
= Path.Combine(My.Computer.FileSystem.SpecialDirectories.ProgramFiles, My.Application.Info.CompanyName)
pth = Path.Combinepth, My.Application.Info.ProductName) MyConfig = System.IO.Path.Combine(pth,
MyConfig) <span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">If</span> My.Computer.FileSystem.FileExists(MyConfig) <span class="kwrd">Then</span><span class="kwrd">Dim</span> fi
= My.Computer.FileSystem.GetFileInfo(MyConfig) log4net.Config.XmlConfigurator.Configure(fi) <span class="kwrd">Else</span> log4net.Config.XmlConfigurator.Configure() <span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">End</span> Sub</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
To use this, you’ll need to make sure that your installation package installs your
addin DLL <em>and</em> it’s config file into the \Program Files\Company Name\Product
Name folder.
</p>
        <p>
This is the pretty typical case, though, so that shouldn’t be a worry.
</p>
        <h1>Later on Down the Road
</h1>
        <p>
This obviously begs the next question. What about <em>other</em> application settings?
Log4Net reads stuff out of an arbtrary config file  you specify, but the My.Settings
object does not. It’ll still end up looking in the default place, which is the host
application’s config file (again, WinWord.exe.config, or Excel.exe.config, etc).
</p>
        <p>
I hope to cover a decent solution to that in a later post.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=b0ec06bb-07ff-4b90-9f86-a0a3e207743c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Implementing Document.SaveCopyAs in Word</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/06/03/ImplementingDocumentSaveCopyAsInWord.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,abc13d9e-e375-4eff-8ec9-d1320e8fb393.aspx</id>
    <published>2010-06-02T22:18:52.906375-05:00</published>
    <updated>2010-06-02T22:18:52.906375-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you’ve used the Excel object model, youmay have discovered how incredibly handy
the SaveCopyAs function is. Essentially, it allows you to save a currently loaded
Excel spreadsheet into some arbitrary file, <em>without</em> altering the state of
the loaded copy. In other words, if the user has altered the spreadsheet loaded into
Excel, but hasn’t saved it, after a "SaveCopyAs”, that copy of the sheet is still
considered dirty, and the saved file on disk <em>does not have</em> the user’s changes
saved within it.
</p>
        <p>
This is a <em>very wonderful thing!</em></p>
        <p>
Basically, it means you can save off the spreadsheet <em>as it currently exists in
memory, complete with all the users edits up to this point,</em> perform any operation
on that saved copy that you want, and then either keep that copy or throw it away,
and the copy that the user is currently working on is not affected <em>in anyway whatsoever!</em></p>
        <p>
Good stuff.
</p>
        <p>
But Word has never had it!
</p>
        <p>
I’d rectified this long ago, in VB6, but recently had a need for this capability again,
in VB.net this time.
</p>
        <p>
Turns out, it’s incredibly simple to implement with VB.net, and much more intuitive
to.
</p>
        <p>
With .net 3.5, you can even create the function as an Extension Method, and directly
add it to the Word Document object interface! Very cool!
</p>
        <p>
The thing is, I knew I’d done this before, but couldn’t remember exactly how. After
quite some time googling this, I came across a post where it was theorized it might
be possible to implement SaveCopyAs by using the Compare function in Word.
</p>
        <p>
Hmm, I’d never even tried the Compare, but it sounded interesting. After a few false
starts, I ended up with this:
</p>
        <pre class="csharpcode">
          <p>
            <span class="kwrd">Imports</span> System.Runtime.CompilerServices
</p>
          <p>
&lt;System.Runtime.CompilerServices.Extension()&gt; _ <span class="kwrd">Public</span><span class="kwrd">Sub</span> SaveCopyAs(<span class="kwrd">ByVal</span> Document <span class="kwrd">As</span> Word.Document, <span class="kwrd">ByVal</span> FileName <span class="kwrd">As</span><span class="kwrd">String</span>)
Document.Compare(Name:=Document.FullName, CompareTarget:=Microsoft.Office.Interop.Word.WdCompareTarget.wdCompareTargetNew) <span class="kwrd">With</span> Document.Application.ActiveDocument <span class="kwrd">If</span> .Revisions.Count
&gt; 0 <span class="kwrd">Then</span> .Revisions.RejectAll() .SaveAs(FileName, AddToRecentFiles:=<span class="kwrd">False</span>)
.Close() <span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">End</span><span class="kwrd">With</span> Document.Activate() <span class="kwrd">End</span> Sub
</p>
        </pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Notice that I’m using the CompilerServices.Extension attribute to flag this as an
extension method. This is what adds this method directly to the Word Document object
and makes it so much more intuitive to use.
</p>
        <p>
Essentially, the idea here is to:
</p>
        <ol>
          <li>
Compare the version of the document loaded in memory to the last saved version out
on disk. 
</li>
          <li>
Write the comparison result to a new document in memory (i.e. what becomes the active
document) 
</li>
          <li>
Check the revision count. 
</li>
          <li>
If there are revisions, you know there’s been changes made to the document since it
was last saved, so Reject all the revisions, save the active document and close it. 
</li>
          <li>
If there were no revisions, the user hasn’t made any changes to the document since
the last time they saved, so there’s really nothing else to do. 
</li>
          <li>
Reactivate the user’s originally active document</li>
        </ol>
        <p>
The real trick here was step 4. Originally, I was <em>accepting</em> the revisions
and then saving, and it wasn’t working at all. Eventually I traced the problem back
to the comparison order. It turns out, when you perform a compare to another file
from a loaded Document object in Word, the results of the comparison are the changes
required to convert from the version of the document you currently have open in Word
to <em>the other document.</em></p>
        <p>
So, if the user has added the word “Nostradamus” in a paragraph, then the comparison
would yield a revision that says, essentially, “remove the word <em>Nostradamus</em> from
this paragraph”. This is exactly backward from the behavior you want. Turns out that
all I had to do was “<em>Reject all changes” </em>instead.
</p>
        <p>
Believe it or not, this works a dream.
</p>
        <h1>But…
</h1>
        <p>
I can’t imagine that performing a compare, especially on a large document, is going
to be a particularly speedy process and I knew I’d done this before using a alternate
interface that the Word Document object implemented, albeit undocumentedly so. I just
couldn’t remember how…
</p>
        <p>
Suffice it to say, eventually I stumbled across the long forgotten interface. That
interface is the COM <a href="http://msdn.microsoft.com/en-us/library/ms687223%28VS.85%29.aspx">IPersistFile</a>.
It’s a basic interface COM typically uses when saving Structured Storage documents,
which are what Word files usually are (though, fortunately, it works with Word 2007
for saving DOCX style files).
</p>
        <p>
Turns out the Word Document object implements that interface. They just don’t make
that fact common knowledge.
</p>
        <p>
Using it is trivially easy, especially given that it’s a COM interface that the .net
framework happens to define natively (though do note, you’ll need to Import the InteropServices.ComTypes
Namespace as show below.
</p>
        <pre class="csharpcode">
          <p>
Imports System.Runtime.CompilerServices<br />
Imports System.Runtime.InteropServices.ComTypes
</p>
          <p>
&lt;System.Runtime.CompilerServices.Extension()&gt; _ <span class="kwrd">Public</span><span class="kwrd">Sub</span> SaveCopyAs(<span class="kwrd">ByVal</span> Document <span class="kwrd">As</span> Word.Document, <span class="kwrd">ByVal</span> FileName <span class="kwrd">As</span><span class="kwrd">String</span>) <span class="kwrd">Dim</span> pf
= <span class="kwrd">DirectCast</span>(Document, IPersistFile)   
<br />
pf.Save(FileName, <span class="kwrd">False</span>) 'pf.SaveCompleted(FileName) <span class="kwrd">End</span> Sub
</p>
        </pre>
        <p>
About that last commented line, that calls the SaveCompleted function. From the docs,
it <em>sounds</em> like that is necessary, but I’ve never found a situation where
it made a difference calling it or not.
</p>
        <p>
Maybe someone can illuminate that aspect of the interface better than me?
</p>
        <p>
But at any rate, the IPersistFile method is likely to be many times faster than the
Compare method, especially for large files or files that the user has made many changes
to without saving. Still, I thought the Compare method was interesting enough to warrant
a mention.
</p>
        <p>
So there you have it. SaveCopyAs for Word, implemented as an extension method that
directly extends the Word Document object.
</p>
        <p>
Yet more VB.net sweetness! <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style></p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=abc13d9e-e375-4eff-8ec9-d1320e8fb393" />
      </div>
    </content>
  </entry>
  <entry>
    <title>VB.net Instance Variable Initializers vs the Constructor</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/06/01/VBnetInstanceVariableInitializersVsTheConstructor.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,4ae600ea-eed1-48f8-86c9-90601df757aa.aspx</id>
    <published>2010-05-31T22:28:47.189125-05:00</published>
    <updated>2010-05-31T22:28:47.189125-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran into a very peculiar problem several days ago. Essentially, I had a class, with
a few properties. One of those properties had some initialization code for a backing
variable, like so:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Public</span>
          <span class="kwrd">Property</span> Count() <span class="kwrd">As</span><span class="kwrd">Integer</span><span class="kwrd">Get</span><span class="kwrd">Return</span> _count <span class="kwrd">End</span><span class="kwrd">Get</span><span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> Value <span class="kwrd">As</span><span class="kwrd">Integer</span>)
_count = Value <span class="kwrd">End</span><span class="kwrd">Set</span><span class="kwrd">End</span><span class="kwrd">Property</span><span class="kwrd">Private</span> _count <span class="kwrd">As</span><span class="kwrd">Integer</span> =
_collection.Count </pre>
        <p>
Now, granted, this is a little contrived. But the idea is that this particular property
is initialized with a value from a private object (the _collection variable), that
is set up during the constructor.
</p>
        <p>
The problem was that the app was throwing an object not initialized when try to initially
set the _count variable’s value.
</p>
        <p>
This completely threw me. How on earth was my constructor <strong>not</strong> being
called? After some debugging, I quickly discovered that the constructor is called <strong><em>after</em></strong> all
these private variable initialization lines are executed! Now, that doesn’t really
make a whole lot of sense, but, it’s what’s happening.
</p>
        <p>
Only later did I come across <a href="http://weblogs.asp.net/psteele/archive/2006/02/22/438840.aspx">this
post</a> by Patrick Steele. He’s got a great explanation and description of what’s
happening there, so I won’t repeat that.
</p>
        <p>
But the key to the whole issue is a quote by him from the Visual Basic Language Specification:
</p>
        <blockquote>
          <p>
When a constructor's first statement is of the form MyBase.New(...), the constructor
implicitly performs the initializations specified by the variable initializers of
the instance variables declared in the type. This corresponds to a sequence of assignments
that are executed <i><b>immediately after</b></i> invoking the direct base type constructor.
Such ordering ensures that all base instance variables are initialized by their variable
initializers before any statements that have access to the instance are executed.
</p>
          <p>
(The emphasis is Patrick’s)
</p>
        </blockquote>
        <p>
He goes on to quote the relevant part of the C# spec, which explicitly states exactly
the opposite behavior for it’s initializers and constructors!
</p>
        <p>
I haven’t been able to find any quote as to <strong><em>why</em></strong> there's
a difference in behavior, or more specifically, why on earth VB’s behavior in this
case seems so wrong.
</p>
        <p>
If anyone knows, please comment!
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=4ae600ea-eed1-48f8-86c9-90601df757aa" />
      </div>
    </content>
  </entry>
  <entry>
    <title>When is the VB.Net Replace function not Replace?</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/05/26/WhenIsTheVBNetReplaceFunctionNotReplace.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,d73c47ae-b55b-4090-9a26-8087d42ea04f.aspx</id>
    <published>2010-05-25T22:32:31.62375-05:00</published>
    <updated>2010-05-25T22:32:31.62375-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I ran into a little surprise a few days ago. With something as innocuous as the “Replace”
function, of all things!
</p>
        <p>
Now, Replace has been around since, well, forever. The basic function has always looked
like this:
</p>
        <p>
X = Replace(StringToSearch, StringToSearchFor, StringToReplaceWith)
</p>
        <p>
No big deal. Used it for years.
</p>
        <p>
So imagine my surprise when I got an “Object not set” error on a string variable that
I’d just used Replace on! How could that be?
</p>
        <p>
So I checked the variable value. It was, in fact, “Nothing". 
</p>
        <p>
Ok, So I rerun the code, stepping through. The variable starts out as a string containing
some data, then gets trimmed, and the resulting string in empty (still a string, just
containing no characters).
</p>
        <p>
Then I perform a replace on it, and suddenly, the string is Nothing?!
</p>
        <p>
So, I coded up the following little test snippet.
</p>
        <pre class="csharpcode">
          <p>
            <span class="kwrd">Private</span>
            <span class="kwrd">Sub</span> Test() <span class="kwrd">Dim</span> x
= <span class="str">"Test A B C"</span> Debug.Print(Replace(x, <span class="str">"A"</span>, <span class="str">"Z"</span>)) <span class="rem">'Results
in "Test Z B C"</span> Debug.Print(x.Replace(<span class="str">"A"</span>, <span class="str">"Z"</span>)) <span class="rem">'also
results in "Test Z B C"</span> x = <span class="str">""</span> x = x.Replace(<span class="str">"A"</span>, <span class="str">"Z"</span>)
Debug.Print(x <span class="kwrd">Is</span><span class="kwrd">Nothing</span>) <span class="rem">'result
is false, (x stays "")</span> x = <span class="str">""</span> x = Microsoft.VisualBasic.Replace(x, <span class="str">"A"</span>, <span class="str">"Z"</span>)
Debug.Print(x <span class="kwrd">Is</span><span class="kwrd">Nothing</span>) <span class="rem">'result
is true!?!</span> x = <span class="str">""</span> x = Replace(x, <span class="str">"A"</span>, <span class="str">"Z"</span>)
Debug.Print(x <span class="kwrd">Is</span><span class="kwrd">Nothing</span>) <span class="rem">'Result
is true!?!</span><span class="kwrd">End</span><span class="kwrd">Sub</span></p>
        </pre>
        <p>
The first two results are exactly as expected. The search string is replaced with
the replace string.
</p>
        <p>
The next result, ALSO, is as expected. x starts out as an empty string. I perform
a replace on it, and the result is, duh! an empty string! Now, for as long as I’ve
known the Replace function, this has not been how it works.
</p>
        <p>
But the next two results both result in FALSE, meaning the result of the String.Replace
function and of the Microsoft.VisualBasic.Replace function is Nothing, and not an
empty string!
</p>
        <h1>Google It!
</h1>
        <p>
So I started googling. I turned up <a href="http://connect.microsoft.com/VisualStudio/feedback/details/89920/bug-vb-net-replace-returns-nothing-when-an-empty-string-is-passed-in">this
bug report</a> from .net 1.1.
</p>
        <p>
The response from Microsoft is:
</p>
        <blockquote>
          <div class="comment">
            <div class="header &#xA;comment_microsoft">Posted by <strong>Microsoft</strong> on 5/18/2006
at 3:02 PM 
</div>
            <div class="content">Hi,<br />
Thank you very much for reporting this issue. Unfortunately, VB had this behavior
in previous version too and we can't change it due to backward compatibility problem. 
<br />
Thanks,<br />
VB Development Team. 
</div>
          </div>
        </blockquote>
        <p>
“Can’t be!” I yelled. Well, ok, I didn’t yell, but I exclaimed heartily &lt;g&gt;.
</p>
        <p>
So I fired up VB6 and wrote up another test program, then ran it.
</p>
        <p>
You can see the VB supplied variable inspector tooltip as I hovered over the value
of X <strong><em>after</em></strong> I’d just run the normal REPLACE function on it
in the EXACT SAME WAY as I’m doing in VB.net.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/WhenistheVB.NetReplacefunctionnotReplace_13C76/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/WhenistheVB.NetReplacefunctionnotReplace_13C76/image_thumb.png" width="442" height="272" />
          </a>
        </p>
        <p>
I hate to burst bubbles, but X starts out as an empty string, I run the REPLACE function
on it, and it ends up… wait for it… an empty string! Not a null/nothing variable.
</p>
        <p>
Maybe it’s another weird edge case scenario that the VB Team is talking about there,
but, come on! This has got to be THE SINGLE MOST COMMON invocation of Replace. Why
on earth should it work differently from VB6 to VB.net?
</p>
        <p>
And one other thing. String.Replace is part of the .net <strong>FRAMEWORK</strong> people.
It has virtually nothing to do with VB6 and certainly, compatibility shouldn’t have
been a concern there. May for the version in the VisualBasic namespace, but not that
String.Replace. Weak!
</p>
        <h1>Short version of the story
</h1>
        <p>
Be VERY CAREFUL of using either String.Replace or the Microsoft.VisualBasic.Replace
functions.
</p>
        <p>
If you DO need them (they have a nice case-insensitive switch, which makes them handy),
write a wrapper function that deals with this VB.net bug (yeah, I went there &lt;g&gt;)
so you won’t get bitten and end up with rash.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=d73c47ae-b55b-4090-9a26-8087d42ea04f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PicPick, A Great Little Freeware ScreenCapture Tool</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/05/26/PicPickAGreatLittleFreewareScreenCaptureTool.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,a0e12bd3-5453-4317-ba81-1ccc485a9129.aspx</id>
    <published>2010-05-25T21:47:58.2175-05:00</published>
    <updated>2010-05-25T21:47:58.2175-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
At my last job, we used <a href="http://www.techsmith.com/">Snagit</a> exclusively
for screen captures. It’s a great tool, but it’s a tad pricey for doing quick screenshots
on your home machine.
</p>
        <p>
Just today, I was at a new contract gig and needed to do some screenshots. There wasn’t
anything decent already available so I went googling for a bit.
</p>
        <p>
First up. I believe I’ve talked about Faststone Capture before and that’s one of the
first hits I got. But after downloading the latest version, I discovered that they’ve
gone to a paid version with a 30 day eval. Don’t get me wrong, Faststone is a good
screen capture util, and you might want to give it a whirl, but in this case, I was
looking for something small and free.
</p>
        <p>
Next try. Struck Gold!
</p>
        <p>
          <a href="http://picpick.wiziple.net/">PicPick</a> is a little freeware app from wiziple.net.
Odd name, but for free, it’s one amazingly polished screen capture app.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/PicPickAGreatLittleFreewareScreenCapture_13289/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/PicPickAGreatLittleFreewareScreenCapture_13289/image_thumb.png" width="644" height="448" />
          </a>
        </p>
        <p>
Let’s see, what’s to love?
</p>
        <ul>
          <li>
It’s got a built in image editor for quick annotations.</li>
          <li>
It can do full screen caps, region caps, window caps, freehand caps, you name it.</li>
          <li>
It’s fast.</li>
          <li>
It can save to several different image formats</li>
        </ul>
        <p>
and lastly…
</p>
        <p>
It’s got a built in screen protractor! WTH!
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/PicPickAGreatLittleFreewareScreenCapture_13289/image_4.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/PicPickAGreatLittleFreewareScreenCapture_13289/image_thumb_1.png" width="144" height="124" />
          </a>
        </p>
        <p>
If you need to do screencaps on a budget, definitely check this one out!
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=a0e12bd3-5453-4317-ba81-1ccc485a9129" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Visual Studio Styles Made Easy</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/05/15/VisualStudioStylesMadeEasy.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,92e4cf74-f980-4cd3-a65e-ebf05350a54e.aspx</id>
    <published>2010-05-14T21:39:40.603957-05:00</published>
    <updated>2010-05-14T21:39:40.603957-05:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Luke Sampson’s put up a nice little site that’s all about custom color styles for
Visual Studio (looks like most schemes support VS2005/2008 AND 2010!)
</p>
        <p>
For example, the high rated scheme right now is WekeRoad:
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/VisualStudioStylesMadeEasy_130A3/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/VisualStudioStylesMadeEasy_130A3/image_thumb.png" width="692" height="424" />
          </a>
        </p>
        <p>
        </p>
        <p>
Pick one and you can download the scheme right there. Very easy to get a custom scheme
(or a good base for your own scheme) going quickly.
</p>
        <p>
I tend to prefer something with a few less colors (I’m not keen on the circus look,
no matter how muted), but some of these schemes look quite nice.
</p>
        <p>
Finally, check out my post about programming fonts <a href="http://www.darinhiggins.com/2007/08/05/BestProgrammingFont.aspx">here</a> for
a good font comparison.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=92e4cf74-f980-4cd3-a65e-ebf05350a54e" />
      </div>
    </content>
  </entry>
  <entry>
    <title>XPath Testing Tool (XPathMania)</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/05/10/XPathTestingToolXPathMania.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,23c38df0-c4d1-46ff-b014-6cdff76c7054.aspx</id>
    <published>2010-05-09T21:10:08.046-05:00</published>
    <updated>2010-05-09T21:10:08.046-05:00</updated>
    <category term="Utilities" label="Utilities" scheme="http://www.darinhiggins.com/CategoryView,category,Utilities.aspx" />
    <category term="VB Feng Shui" label="VB Feng Shui" scheme="http://www.darinhiggins.com/CategoryView,category,VB%2BFeng%2BShui.aspx" />
    <category term="XML" label="XML" scheme="http://www.darinhiggins.com/CategoryView,category,XML.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I mentioned RAD Software’s RegularExpression Designer a few posts back, but this time,
I’m talking XPath.
</p>
        <p>
If you haven’t already played with XPath, and you do much of anything at all with
XML data, you owe it to yourself to check it out. Basically, it’s a query language
that allows you to query for specific nodes or nodesets from an XML data source very
easily. It’s also got some limited function and expression handling capabilities (typical
math functions, string manipulation functions, etc).
</p>
        <p>
XPath 1.0 is fully supported by the .net framework. Unfortunately, XPath 2.0, while
much more capable, has been dropped by Microsoft in favor of, I believe, XQuery. Trouble
is, I can’t find much in the way of VB.net support for XQuery right off.
</p>
        <p>
But, all that aside, XPath 1.0 is still very much a useful tool to have in your arsenal,
but, like regular expressions, getting an XPath query right can take some experimenting.
That’s where <a href="http://www.PowerVB.com/XPathMania/Mvp.Xml_XPathMania_1.0RC1.1VS2008.zip">XPathMania</a> comes
in.
</p>
        <p>
It’s basically an XPath query tool extension to the VS 2008 IDE.
</p>
        <p>
In the screenshot below, you can see that I’ve got an XML file loaded, and I’ve docked
the XPathMania window just below it.
</p>
        <p>
With that, I can easily enter a query again that XML file and view the results (along
with the matching nodes actually <em>highlighted</em> in the XML file view! Good stuff!
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/XPathTestingToolXPathMania_135F1/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/XPathTestingToolXPathMania_135F1/image_thumb.png" width="642" height="484" />
          </a>
        </p>
        <p>
Finally, you’ll also definitely want to check out <a href="http://msdn.microsoft.com/en-us/library/ms256086.aspx">this
page</a> for lots of good XPath example queries.
</p>
        <p>
In the future, I’ll try to put together a little sample app that illustrates how to
use the XPathNavigator to easily execute these queries against an XML document and
enumerate the resulting nodeset.
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=23c38df0-c4d1-46ff-b014-6cdff76c7054" />
      </div>
    </content>
  </entry>
  <entry>
    <title>FreeCommander Ain&amp;rsquo;t Half Bad</title>
    <link rel="alternate" type="text/html" href="http://www.darinhiggins.com/2010/05/09/FreeCommanderAinrsquotHalfBad.aspx" />
    <id>http://www.darinhiggins.com/PermaLink,guid,6b9fb273-c307-4d18-bc73-ff71ffe04684.aspx</id>
    <published>2010-05-08T23:17:11.557625-05:00</published>
    <updated>2010-05-08T23:17:11.557625-05:00</updated>
    <category term="Utilities" label="Utilities" scheme="http://www.darinhiggins.com/CategoryView,category,Utilities.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The other day, I was needing to quickly view lots of log files in a folder. The Ol’
“Double click/open in notepad/close notepad/arrow down/repeat” process was getting
old quick.
</p>
        <p>
Now, at home, I’ve got Directory Opus, which would make this a breeze. But, it’s a
licensed copy, and unfortunately, their licensing is a tad draconian. Besides, I was
at an office, so I didn’t have my sernum or anything like that handy.
</p>
        <p>
So, I started poking around. I’d looked at a pile of Explorer replacements awhile
back. That’s how I ended up buying DirOpus. But this time, I needed something free
I could download, install and get my job done.
</p>
        <p>
A few minutes of googling pointed my to FreeCommander. I can’t say I even looked at
this package before, because it’s billed as a “Norton Commander Clone”, and I never
really got into Norton Commander.
</p>
        <p>
          <a href="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/FreeCommanderAintHalfBad_14770/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.darinhiggins.com/content/binary/WindowsLiveWriter/FreeCommanderAintHalfBad_14770/image_thumb.png" width="711" height="489" />
          </a>
        </p>
        <p>
That picture viewer you see on the right? It’ll view just about any file type, which
was just what I was needing.
</p>
        <p>
But come to find out, FreeCommander is much more than just a Norton Commander clone.
</p>
        <p>
There’s lots of very cool features here, including:
</p>
        <ul>
          <li>
Tabbed explorers</li>
          <li>
A decent Tree (it doesn’t show the full tree like explorer does, but it comes close
enough to be useful)</li>
          <li>
A decent file viewer that can be “in place”, meaning it doesn’t open a new window
to show the file being viewed.</li>
          <li>
A “Quick Filter” which is very handy.</li>
          <li>
Predefined Filters, for when the quick filter isn’t quite enough.</li>
          <li>
Lots of config options</li>
          <li>
Reasonably fast, even in dirs with lots of files.</li>
        </ul>
        <p>
And finally, so far, it’s been very stable.
</p>
        <p>
In all, a very compelling Explorer replacement, especially considering the price!
</p>
        <img width="0" height="0" src="http://www.darinhiggins.com/aggbug.ashx?id=6b9fb273-c307-4d18-bc73-ff71ffe04684" />
      </div>
    </content>
  </entry>
</feed>