<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Zupancic Perspective (v2.0)</title>
    <link>http://blog.devstone.com/aaron/</link>
    <description>An insight into the world of R. Aaron Zupancic, software development (.NET, et al), muses, and much more...</description>
    <language>en-us</language>
    <copyright>R. Aaron Zupancic</copyright>
    <lastBuildDate>Wed, 19 Oct 2011 06:34:13 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>aaron.zupancic@devstone.com</managingEditor>
    <webMaster>aaron.zupancic@devstone.com</webMaster>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=80739f6a-181d-4385-a7d8-628b51e4c8f1</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,80739f6a-181d-4385-a7d8-628b51e4c8f1.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,80739f6a-181d-4385-a7d8-628b51e4c8f1.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=80739f6a-181d-4385-a7d8-628b51e4c8f1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">Here's a very simple class I whipped up that facilitates invoking
an event on the UI thread. Easily adapted to any delegate. Basically, using this class
alleviates the subscriber of the event from needing to accept the method call and
marshal it to the UI thread itself.</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">
              <font color="#008000">public static class</font> SyncContext
{<br />
   <font color="#008000">public static</font> SynchronizationContext UI
{ <font color="#008000">get</font>; <font color="#008000">set</font>; }<br />
}<br /><br /><font color="#008000">public sealed class</font> SafeEvent&lt;T&gt; <font color="#008000">where</font> T
: EventArgs, <font color="#008000">new</font>() {<br />
   <font color="#008000">public</font> SafeEvent(EventHandler&lt;T&gt; eh, <font color="#008000">object</font> sender,
T e = <font color="#008000">null</font>) {<br />
      _event = eh;<br />
      _sender = sender;<br />
      _eventArgs = e;<br />
   }<br /><br />
   <font color="#008000">private readonly</font> EventHandler&lt;T&gt; _event;<br />
   <font color="#008000">private readonly</font> object _sender;<br />
   <font color="#008000">private readonly</font> T _eventArgs;<br /><br />
   <font color="#008000">public void</font> Invoke() {<br />
      SyncContext.UI.Post(s =&gt; _event(_sender, _eventArgs
?? <font color="#008000">new</font> T()), <font color="#008000">null</font>);<br />
   }<br /><br />
   <font color="#008000">public static void</font> Invoke(EventHandler&lt;T&gt;
eh, <font color="#008000">object</font> sender, T e = <font color="#008000">null</font>)
{<br />
      SyncContext.UI.Post(s =&gt; eh(sender, e ?? <font color="#008000">new</font> T()), <font color="#008000">null</font>);<br />
   }<br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">To use, simply initialize the SyncContext at the start of your
application in the UI thread (e.g., on the main form) thus:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">SyncContext.UI = SynchronizationContext.Current;</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Then, you can invoke your event in one of two ways:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">
              <font color="#008000">new</font> SafeEvent&lt;EventArgs&gt;(Click, <font color="#008000">this</font>).Invoke();</font>
          </p>
          <p>
            <font face="Courier New">SafeEvent&lt;EventArgs&gt;.Invoke(Click, <font color="#008000">this</font>);</font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=80739f6a-181d-4385-a7d8-628b51e4c8f1" />
      </body>
      <title>Invoking an Event on the UI Thread</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,80739f6a-181d-4385-a7d8-628b51e4c8f1.aspx</guid>
      <link>http://blog.devstone.com/aaron/2011/10/19/InvokingAnEventOnTheUIThread.aspx</link>
      <pubDate>Wed, 19 Oct 2011 06:34:13 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;Here's a very simple class I whipped up that facilitates invoking
an event on the UI thread. Easily adapted to any delegate. Basically, using this class
alleviates the subscriber of the event from needing to accept the method call and
marshal it to the UI thread itself.&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#008000&gt;public static class&lt;/font&gt; SyncContext
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public static&lt;/font&gt; SynchronizationContext UI { &lt;font color=#008000&gt;get&lt;/font&gt;; &lt;font color=#008000&gt;set&lt;/font&gt;;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;font color=#008000&gt;public sealed&amp;nbsp;class&lt;/font&gt; SafeEvent&amp;lt;T&amp;gt; &lt;font color=#008000&gt;where&lt;/font&gt; T
: EventArgs, &lt;font color=#008000&gt;new&lt;/font&gt;() {&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; SafeEvent(EventHandler&amp;lt;T&amp;gt; eh, &lt;font color=#008000&gt;object&lt;/font&gt; sender,
T e = &lt;font color=#008000&gt;null&lt;/font&gt;) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _event = eh;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _sender = sender;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _eventArgs = e;&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;private readonly&lt;/font&gt; EventHandler&amp;lt;T&amp;gt; _event;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;private readonly&lt;/font&gt; object _sender;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;private readonly&lt;/font&gt; T _eventArgs;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public void&lt;/font&gt; Invoke() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SyncContext.UI.Post(s =&amp;gt; _event(_sender, _eventArgs
?? &lt;font color=#008000&gt;new&lt;/font&gt; T()), &lt;font color=#008000&gt;null&lt;/font&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public static void&lt;/font&gt; Invoke(EventHandler&amp;lt;T&amp;gt;
eh, &lt;font color=#008000&gt;object&lt;/font&gt; sender, T e = &lt;font color=#008000&gt;null&lt;/font&gt;)
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SyncContext.UI.Post(s =&amp;gt; eh(sender, e ?? &lt;font color=#008000&gt;new&lt;/font&gt; T()), &lt;font color=#008000&gt;null&lt;/font&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;To use, simply initialize the SyncContext at the start of your application
in the UI thread (e.g., on the main form) thus:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;SyncContext.UI = SynchronizationContext.Current;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;Then, you can invoke your event in one of two ways:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#008000&gt;new&lt;/font&gt; SafeEvent&amp;lt;EventArgs&amp;gt;(Click, &lt;font color=#008000&gt;this&lt;/font&gt;).Invoke();&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;SafeEvent&amp;lt;EventArgs&amp;gt;.Invoke(Click, &lt;font color=#008000&gt;this&lt;/font&gt;);&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=80739f6a-181d-4385-a7d8-628b51e4c8f1" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,80739f6a-181d-4385-a7d8-628b51e4c8f1.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>Threading</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=c11b2b1f-821b-496a-86bd-7f6981d98755</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,c11b2b1f-821b-496a-86bd-7f6981d98755.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,c11b2b1f-821b-496a-86bd-7f6981d98755.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=c11b2b1f-821b-496a-86bd-7f6981d98755</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">Wow! I can't believe how much time has elapsed since my last post! I
can honestly claim that life has simply gotten in the way of blogging - and that's
not a bad thing. To be sure, this blog has been a personal resource more than
anything so I don't have to exert the energy needed to remember things. It's
worked out well. :-)</font>
        </p>
        <p>
          <font face="Tahoma">This post holds true to form in that I'm cataloging some information
that I may need to lean on in the future, but it may potentially be useful for others
as well.</font>
        </p>
        <p>
          <font face="Tahoma">I'm currently developing a small WinForms MVVM application
as a support utility for a Windows Phone 7 game.  While I'm not going to go into
the MVVM pattern here (as it is documented online ad nauseum), my application
has the need to have a TreeView with bound elements. That is, I need to take a node
in the tree and bind it to its respective ViewModel. This way, I can effect changes
on the ViewModel in my application and the TreeView will automatically reflect the
changes. The intrinsic TreeNode class doesn't support data binding, but with but a
tiny bit of effort we can create a bindable TreeNode:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">
              <font color="#008000">public class</font> BindableTreeNode
: TreeNode, IBindableComponent {<br />
   <font color="#008000">public</font> BindableTreeNode() : <font color="#008000">base</font>()
{ }<br />
   <font color="#008000">public</font> BindableTreeNode(<font color="#008000">string</font> text)
: <font color="#008000">base</font>(text) { }<br />
   <font color="#008000">public</font> BindableTreeNode(<font color="#008000">string</font> text, <font color="#008000">int</font> imageIndex, <font color="#008000">int</font> selectedImageIndex)
: <font color="#008000">base</font>(text, imageIndex, selectedImageIndex) { }<br />
   <font color="#008000">public</font> BindableTreeNode(<font color="#008000">string</font> text, <font color="#008000">int</font> imageIndex, <font color="#008000">int</font> selectedImageIndex,
TreeNode[] children) : <font color="#008000">base</font>(text, imageIndex, selectedImageIndex,
children) { }</font>
          </p>
          <p>
            <font face="Courier New">   <font color="#008000">private</font> ControlBindingsCollection
_bindings;<br />
   <font color="#008000">private</font> BindingContext _bindingContext;</font>
          </p>
          <p>
            <font face="Courier New">   <font color="#008000">public</font> ControlBindingsCollection
DataBindings {<br />
      <font color="#008000">get</font> { <font color="#008000">return</font> _bindings
?? ( _bindings = <font color="#008000">new</font> ControlBindingsCollection(<font color="#008000">this</font>)
); }<br />
   }</font>
          </p>
          <p>
            <font face="Courier New">   <font color="#008000">public</font> BindingContext
BindingContext {<br />
      <font color="#008000">get</font> { <font color="#008000">return</font> _bindingContext
?? ( _bindingContext = <font color="#008000">new</font> BindingContext() ); }<br />
      <font color="#008000">set</font> { _bindingContext
= <font color="#008000">value</font>; }<br />
   }</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   <font color="#008000">public void</font> Dispose()
{<br />
      _bindings.Clear();<br />
      _bindingContext = <font color="#008000">null</font>;</font>
          </p>
          <p>
            <font face="Courier New">      EventHandler eh = Disposed;<br />
      <font color="#008000">if</font> ( <font color="#008000">null</font> !=
eh ) eh(<font color="#008000">this</font>, EventArgs.Empty);<br />
   }</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   <font color="#008000">public</font> ISite Site
{ <font color="#008000">get</font>; <font color="#008000">set</font>; }<br />
   <font color="#008000">public event</font> EventHandler Disposed;<br />
}<br /></font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=c11b2b1f-821b-496a-86bd-7f6981d98755" />
      </body>
      <title>A Simple Data-Bindable TreeNode for WinForms</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,c11b2b1f-821b-496a-86bd-7f6981d98755.aspx</guid>
      <link>http://blog.devstone.com/aaron/2011/10/19/ASimpleDataBindableTreeNodeForWinForms.aspx</link>
      <pubDate>Wed, 19 Oct 2011 06:01:47 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;Wow! I can't believe how much time has elapsed since my last post!&amp;nbsp;I
can honestly claim that life has simply gotten in the way of blogging - and that's
not a bad thing.&amp;nbsp;To be sure, this blog has been a personal resource more than
anything so I don't have to exert the energy needed to remember things.&amp;nbsp;It's
worked out well. :-)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;This post holds true to form in that I'm cataloging some information
that I may need to lean on in the future, but it may potentially be useful for others
as well.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I'm currently&amp;nbsp;developing a small WinForms MVVM application
as a support utility for a Windows Phone 7 game.&amp;nbsp; While I'm not going to go into
the MVVM pattern here (as it is documented&amp;nbsp;online ad nauseum), my application
has the need to have a TreeView with bound elements. That is, I need to take a node
in the tree and bind it to its respective ViewModel.&amp;nbsp;This way, I can effect changes
on the ViewModel in my application and the TreeView will automatically reflect the
changes. The intrinsic TreeNode class doesn't support data binding, but with but a
tiny bit of effort we can create a bindable TreeNode:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#008000&gt;public class&lt;/font&gt; BindableTreeNode
: TreeNode, IBindableComponent {&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; BindableTreeNode() : &lt;font color=#008000&gt;base&lt;/font&gt;()
{ }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; BindableTreeNode(&lt;font color=#008000&gt;string&lt;/font&gt; text)
: &lt;font color=#008000&gt;base&lt;/font&gt;(text) { }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; BindableTreeNode(&lt;font color=#008000&gt;string&lt;/font&gt; text, &lt;font color=#008000&gt;int&lt;/font&gt; imageIndex, &lt;font color=#008000&gt;int&lt;/font&gt; selectedImageIndex)
: &lt;font color=#008000&gt;base&lt;/font&gt;(text, imageIndex, selectedImageIndex) { }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; BindableTreeNode(&lt;font color=#008000&gt;string&lt;/font&gt; text, &lt;font color=#008000&gt;int&lt;/font&gt; imageIndex, &lt;font color=#008000&gt;int&lt;/font&gt; selectedImageIndex,
TreeNode[] children) : &lt;font color=#008000&gt;base&lt;/font&gt;(text, imageIndex, selectedImageIndex,
children) { }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;private&lt;/font&gt; ControlBindingsCollection
_bindings;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;private&lt;/font&gt; BindingContext _bindingContext;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; ControlBindingsCollection
DataBindings {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;get&lt;/font&gt; { &lt;font color=#008000&gt;return&lt;/font&gt; _bindings
?? ( _bindings = &lt;font color=#008000&gt;new&lt;/font&gt; ControlBindingsCollection(&lt;font color=#008000&gt;this&lt;/font&gt;)
); }&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; BindingContext
BindingContext {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;get&lt;/font&gt; { &lt;font color=#008000&gt;return&lt;/font&gt; _bindingContext
?? ( _bindingContext = &lt;font color=#008000&gt;new&lt;/font&gt; BindingContext() ); }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;set&lt;/font&gt; { _bindingContext = &lt;font color=#008000&gt;value&lt;/font&gt;;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public void&lt;/font&gt; Dispose()
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _bindings.Clear();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _bindingContext = &lt;font color=#008000&gt;null&lt;/font&gt;;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventHandler eh = Disposed;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;if&lt;/font&gt; ( &lt;font color=#008000&gt;null&lt;/font&gt; !=
eh ) eh(&lt;font color=#008000&gt;this&lt;/font&gt;, EventArgs.Empty);&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public&lt;/font&gt; ISite Site
{ &lt;font color=#008000&gt;get&lt;/font&gt;; &lt;font color=#008000&gt;set&lt;/font&gt;; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;public event&lt;/font&gt; EventHandler Disposed;&lt;br&gt;
}&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=c11b2b1f-821b-496a-86bd-7f6981d98755" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,c11b2b1f-821b-496a-86bd-7f6981d98755.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>MVVM</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=2f5c531d-615e-4e6f-b2ba-83fd9407a8b7</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,2f5c531d-615e-4e6f-b2ba-83fd9407a8b7.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,2f5c531d-615e-4e6f-b2ba-83fd9407a8b7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=2f5c531d-615e-4e6f-b2ba-83fd9407a8b7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When setting up my development environment, one of the first steps I take is to configure
a virtual network with my VMs. I do this by setting up a Loopback Adapter in
Windows. In Windows Vista+ this device is automatically setup on a 'Public' network
and, as such, prevents me from performing some routine operations (such as file sharing)
with my VMs through the interface. Unlike most network interfaces, Windows provides
no mechanism for changing the adapter to be on a 'Private' network where a less stringent
set of constraints is in place.
</p>
        <p>
After a bit of spelunking (a.k.a. Binging) I quickly discovered that a simple registry
change and a reset of the adapter fixed the issue.  I found a little <a href="http://spandothers.spaces.live.com/blog/cns!28159FD1410E3D28!583.entry?sa=823207223">PowerShell
script</a> which does the trick, but I took the liberty of modifying it a bit:
</p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New"># Set execution policy for powershell first set-executionpolicy
unrestricted<br />
#<br />
# see </font>
            <a href="http://msdn2.microsoft.com/en-us/library/bb201634.aspx">
              <font face="Courier New">http://msdn2.microsoft.com/en-us/library/bb201634.aspx</font>
            </a>
            <br />
            <font face="Courier New"># 
<br />
# *NdisDeviceType<br />
# 
<br />
# The type of the device. The default value is zero, which indicates a standard<br />
# networking device that connects to a network.<br />
# 
<br />
# Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT (1) if this device is an<br />
# endpoint device and is not a true network interface that connects to a network.<br />
# For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT for devices such as<br />
# smart phones that use a networking infrastructure to communicate to the local<br />
# computer system but do not provide connectivity to an external network.<br />
# 
<br />
# check the executionpolicy<br />
# PS&gt; executionpolicy<br />
# Set run policy to unrestricted<br />
# PS&gt; set-executionpolicy unrestricted<br />
#<br />
# Usage: run in an elevated shell (Vista/Windows 7) or as adminstrator (XP/2003).<br />
# 
<br />
# PS&gt; .\PrivateLoopbackNetwork.ps1</font>
          </p>
          <p>
            <font face="Courier New"># boilerplate elevation check</font>
          </p>
          <p>
            <font face="Courier New">$identity = [Security.Principal.WindowsIdentity]::GetCurrent()<br />
$principal = new-object Security.Principal.WindowsPrincipal $identity<br />
$elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)</font>
          </p>
          <p>
            <font face="Courier New">if ( -not $elevated ) {<br />
    $error = "Sorry, you need to run this script"<br />
    if ( [System.Environment]::OSVersion.Version.Major -gt 5 ) {<br />
        $error += " in an elevated shell."<br />
    } else {<br />
        $error += " as Administrator."<br />
    }<br />
    throw $error<br />
}</font>
          </p>
          <p>
            <font face="Courier New">function confirm {<br />
    $host.ui.PromptForChoice("Process adapter?", "", [Management.Automation.Host.ChoiceDescription[]]@("&amp;No",
"&amp;Yes"), 0) -eq $true<br />
}</font>
          </p>
          <p>
            <font face="Courier New"># adapters key<br />
pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'<br />
$propName = '*NdisDeviceType'</font>
          </p>
          <p>
            <font face="Courier New"># ignore and continue on error<br />
dir -ea 0 | % {<br />
    $node = $_.pspath<br />
    $desc = gp $node -name driverdesc<br />
    if ( ( $desc -like "*vmware*" ) -or ( $desc -like "*Loopback*"
) ) {<br />
        write-host("Found adapter: {0} " -f $desc.driverdesc)<br />
        if ( confirm -eq $true ) {<br />
            if ( ( get-itemproperty
$node -name $propName ) -eq $null ) {<br />
               
new-itemproperty $node -name $propName -propertytype dword -value 1<br />
            } else {<br />
               
set-itemproperty $node -name $propName -value 1<br />
            }<br />
            $updated = $true<br />
        }<br />
    }<br />
}<br />
popd</font>
          </p>
          <p>
            <font face="Courier New">
            </font>
          </p>
          <p>
            <font face="Courier New">if ( $updated ) {<br />
    # disable/enable network adapters<br />
    gwmi win32_networkadapter | ? { ( ( $_.name -like "*vmware*" )
-or ( $_.name -like "*Loopback*" ) ) } | % {<br />
        # disable<br />
        write-host -nonew "Disabling adapter: $($_.name)"<br />
        $result = $_.Disable()<br />
        if ( $result.ReturnValue -eq -0 ) { write-host
" - success." } else { write-host " - failed." }</font>
          </p>
          <p>
            <font face="Courier New">        # enable<br />
        write-host -nonew "Enabling adapter: 
$($_.name)"<br />
        $result = $_.Enable()<br />
        if ( $result.ReturnValue -eq -0 ) { write-host
" - success." } else { write-host " - failed." }<br />
    }<br />
}</font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=2f5c531d-615e-4e6f-b2ba-83fd9407a8b7" />
      </body>
      <title>Loopback Adapter on a Private Network</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,2f5c531d-615e-4e6f-b2ba-83fd9407a8b7.aspx</guid>
      <link>http://blog.devstone.com/aaron/2010/08/30/LoopbackAdapterOnAPrivateNetwork.aspx</link>
      <pubDate>Mon, 30 Aug 2010 14:33:29 GMT</pubDate>
      <description>&lt;p&gt;
When setting up my development environment, one of the first steps I take is to configure
a virtual network with my VMs.&amp;nbsp;I do this by setting up a Loopback Adapter in
Windows.&amp;nbsp;In Windows Vista+ this device is automatically setup on a 'Public' network
and, as such, prevents me from performing some routine operations (such as file sharing)
with my VMs through the interface. Unlike most network interfaces, Windows provides
no mechanism for changing the adapter to be on a 'Private' network where a less stringent
set of constraints is in place.
&lt;/p&gt;
&lt;p&gt;
After a bit of spelunking (a.k.a. Binging) I quickly discovered that a simple registry
change and a reset of the adapter fixed the issue.&amp;nbsp; I found a little &lt;a href="http://spandothers.spaces.live.com/blog/cns!28159FD1410E3D28!583.entry?sa=823207223"&gt;PowerShell
script&lt;/a&gt; which does the trick, but I took the liberty of modifying it a bit:
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;# Set execution policy for powershell first set-executionpolicy
unrestricted&lt;br&gt;
#&lt;br&gt;
# see &lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb201634.aspx"&gt;&lt;font face="Courier New"&gt;http://msdn2.microsoft.com/en-us/library/bb201634.aspx&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;# 
&lt;br&gt;
# *NdisDeviceType&lt;br&gt;
# 
&lt;br&gt;
# The type of the device. The default value is zero, which indicates a standard&lt;br&gt;
# networking device that connects to a network.&lt;br&gt;
# 
&lt;br&gt;
# Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT (1) if this device is an&lt;br&gt;
# endpoint device and is not a true network interface that connects to a network.&lt;br&gt;
# For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT for devices such as&lt;br&gt;
# smart phones that use a networking infrastructure to communicate to the local&lt;br&gt;
# computer system but do not provide connectivity to an external network.&lt;br&gt;
# 
&lt;br&gt;
# check the executionpolicy&lt;br&gt;
# PS&amp;gt; executionpolicy&lt;br&gt;
# Set run policy to unrestricted&lt;br&gt;
# PS&amp;gt; set-executionpolicy unrestricted&lt;br&gt;
#&lt;br&gt;
# Usage: run in an elevated shell (Vista/Windows 7) or as adminstrator (XP/2003).&lt;br&gt;
# 
&lt;br&gt;
# PS&amp;gt; .\PrivateLoopbackNetwork.ps1&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# boilerplate elevation check&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;$identity = [Security.Principal.WindowsIdentity]::GetCurrent()&lt;br&gt;
$principal = new-object Security.Principal.WindowsPrincipal $identity&lt;br&gt;
$elevated = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;if ( -not $elevated ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $error = "Sorry, you need to run this script"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( [System.Environment]::OSVersion.Version.Major -gt 5 ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $error += " in an elevated shell."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $error += " as Administrator."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; throw $error&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;function confirm {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $host.ui.PromptForChoice("Process adapter?", "", [Management.Automation.Host.ChoiceDescription[]]@("&amp;amp;No",
"&amp;amp;Yes"), 0) -eq $true&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# adapters key&lt;br&gt;
pushd 'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'&lt;br&gt;
$propName = '*NdisDeviceType'&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# ignore and continue on error&lt;br&gt;
dir -ea 0 | % {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $node = $_.pspath&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $desc = gp $node -name driverdesc&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( ( $desc -like "*vmware*" ) -or ( $desc -like "*Loopback*"
) ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host("Found adapter: {0} " -f $desc.driverdesc)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( confirm -eq $true ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( ( get-itemproperty
$node -name $propName ) -eq $null ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
new-itemproperty $node -name $propName -propertytype dword -value 1&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
set-itemproperty $node -name $propName -value 1&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $updated = $true&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;br&gt;
popd&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;if ( $updated ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; # disable/enable network adapters&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; gwmi win32_networkadapter | ? { ( ( $_.name -like "*vmware*" )
-or ( $_.name -like "*Loopback*" ) ) } | % {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # disable&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host -nonew "Disabling adapter: $($_.name)"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $result = $_.Disable()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( $result.ReturnValue -eq -0 ) { write-host
" - success." } else { write-host " - failed." }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # enable&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host -nonew "Enabling adapter:&amp;nbsp;
$($_.name)"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $result = $_.Enable()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( $result.ReturnValue -eq -0 ) { write-host
" - success." } else { write-host " - failed." }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=2f5c531d-615e-4e6f-b2ba-83fd9407a8b7" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,2f5c531d-615e-4e6f-b2ba-83fd9407a8b7.aspx</comments>
      <category>PowerShell</category>
      <category>Virtual PC</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=ff01bb8b-7b08-4454-b98d-57da20279df2</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,ff01bb8b-7b08-4454-b98d-57da20279df2.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,ff01bb8b-7b08-4454-b98d-57da20279df2.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=ff01bb8b-7b08-4454-b98d-57da20279df2</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">Developing applications that target multiple version of Office
on a single computer can be difficult, daunting, disturbing, and down-right dirty.</font>
        </p>
        <p>
          <font face="Tahoma">The Microsoft Office team has performed some herculean tasks to
ease our burdens, but there are still some hurdles to overcome.  Having multiple
versions of Office installed on a single development machine is not possible and it
appears that you cannot install the Office PIAs on a machine that doesn't have that
version of Office installed (e.g., you cannot install the </font>
          <a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;displaylang=en">
            <font face="Tahoma">Office
2003 PIA</font>
          </a>
          <font face="Tahoma">s on a box with Office 2007 on it).  Additionally,
having multiple development environments each targeting a specific version of Office
is not always practical.</font>
        </p>
        <p>
          <font face="Tahoma">It is fortunate that add-ins created targeting the Office 2003
PIAs will work seamlessly in Office 2007 (they will not, however, be able to take
advantage of the new features of the 2007 system such as the Ribbon, etc).</font>
        </p>
        <p>
          <font face="Tahoma">If you have a VS project that was built on a box with Office 2003
+ </font>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8315654B-A5AE-4108-B7FC-186402563F2B&amp;displaylang=en">
            <font face="Tahoma">VSTO
2005 SE</font>
          </a>
          <font face="Tahoma"> + </font>
          <a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;displaylang=en">
            <font face="Tahoma">Office
2003 PIA</font>
          </a>
          <font face="Tahoma"> and you open it on a machine with Office
2007 + VSTO 2005 SE + Visual Studio Tools for the Office system 3.0 Runtime, you will
be prompted to upgrade your project to the new office platform.  Upgrading your
project will have the unfortunate side-effect of rendering the project useless on
your other dev environment that doesn't have Office 2007, etc on it.</font>
        </p>
        <p>
          <font face="Tahoma">Fortunately, there is a handy VS setting neatly tucked away in <strong><font face="Courier New"><font color="#a52a2a">Tools</font> -&gt; <font color="#a52a2a">Options</font> -&gt; <font color="#a52a2a">Office
Tools</font> -&gt; <font color="#a52a2a">Project Upgrade</font></font></strong> called <strong><font color="#a52a2a" face="Courier New">Always
upgrade to installed version of Office</font></strong>.  Unchecking this option
will allow you to open the project in Visual Studio without being compelled to upgrade.</font>
        </p>
        <p>
          <font face="Tahoma">I find it somewhat comical that using VS2008 on a machine with
Office 2007 + the two VSTO editions you can create a project targeting Office 2003
but when you reopen it you'll be prompted to upgrade (unless you have the setting
disabled) it.</font>
        </p>
        <p>
          <font face="Tahoma">If you don't have them there, don't forget to add the <font face="Courier New">Office2003PIA</font> and <font face="Courier New">VSTOSERuntime</font> bootstrappers
to <font color="#a52a2a" face="Courier New">%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages</font> in
order to compile your projects.</font>
        </p>
        <p>
          <font face="Tahoma">
          </font> 
</p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=ff01bb8b-7b08-4454-b98d-57da20279df2" />
      </body>
      <title>Preventing an upgrade of an Office 2003 Add-in</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,ff01bb8b-7b08-4454-b98d-57da20279df2.aspx</guid>
      <link>http://blog.devstone.com/aaron/2010/01/25/PreventingAnUpgradeOfAnOffice2003Addin.aspx</link>
      <pubDate>Mon, 25 Jan 2010 23:29:35 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;Developing applications that target multiple version of Office on
a single computer can be difficult, daunting, disturbing, and down-right dirty.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;The Microsoft Office team has performed some herculean tasks to
ease our burdens, but there are still some hurdles to overcome.&amp;nbsp; Having multiple
versions of Office installed on a single development machine is not possible and it
appears that you cannot install the Office PIAs on a machine that doesn't have that
version of Office installed (e.g., you cannot install the &lt;/font&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;amp;displaylang=en"&gt;&lt;font face=Tahoma&gt;Office
2003 PIA&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt;s on a box with Office 2007 on it).&amp;nbsp; Additionally,
having multiple development environments each targeting a specific version of Office
is not always practical.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;It is fortunate that add-ins created targeting the Office 2003 PIAs
will work seamlessly in Office 2007 (they will not, however, be able to take advantage
of the new features of the 2007 system such as the Ribbon, etc).&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;If you have a VS project that was built on a box with Office 2003
+ &lt;/font&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8315654B-A5AE-4108-B7FC-186402563F2B&amp;amp;displaylang=en"&gt;&lt;font face=Tahoma&gt;VSTO
2005 SE&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt; + &lt;/font&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;amp;displaylang=en"&gt;&lt;font face=Tahoma&gt;Office
2003 PIA&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt;&amp;nbsp;and you open it on a machine with Office
2007 + VSTO 2005 SE + Visual Studio Tools for the Office system 3.0 Runtime, you will
be prompted to upgrade your project to the new office platform.&amp;nbsp; Upgrading your
project will have the unfortunate side-effect of rendering the project useless on
your other dev environment that doesn't have Office 2007, etc on it.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;Fortunately, there is a handy VS setting neatly tucked away in &lt;strong&gt;&lt;font face="Courier New"&gt;&lt;font color=#a52a2a&gt;Tools&lt;/font&gt; -&amp;gt; &lt;font color=#a52a2a&gt;Options&lt;/font&gt; -&amp;gt; &lt;font color=#a52a2a&gt;Office
Tools&lt;/font&gt; -&amp;gt; &lt;font color=#a52a2a&gt;Project Upgrade&lt;/font&gt;&lt;/font&gt;&lt;/strong&gt; called &lt;strong&gt;&lt;font color=#a52a2a face="Courier New"&gt;Always
upgrade to installed version of Office&lt;/font&gt;&lt;/strong&gt;.&amp;nbsp; Unchecking this option
will allow you to open the project in Visual Studio without being compelled to upgrade.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I find it somewhat comical that using VS2008 on a machine with Office
2007 + the two VSTO editions you can create a project targeting Office 2003 but when
you reopen it you'll be prompted to upgrade (unless you have the setting disabled)
it.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;If you don't have them there, don't forget to add the &lt;font face="Courier New"&gt;Office2003PIA&lt;/font&gt; and &lt;font face="Courier New"&gt;VSTOSERuntime&lt;/font&gt; bootstrappers
to &lt;font color=#a52a2a face="Courier New"&gt;%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages&lt;/font&gt; in
order to compile your projects.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=ff01bb8b-7b08-4454-b98d-57da20279df2" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,ff01bb8b-7b08-4454-b98d-57da20279df2.aspx</comments>
      <category>Office</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=1a18e011-ea44-459e-84be-55a9046bce7d</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,1a18e011-ea44-459e-84be-55a9046bce7d.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,1a18e011-ea44-459e-84be-55a9046bce7d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=1a18e011-ea44-459e-84be-55a9046bce7d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">I had the need today to create an application must run with administrative
privileges.  Fortunately, this is a pretty straightforward endeavor.</font>
        </p>
        <p>
          <font face="Tahoma">On Windows Vista, Windows 7, or Windows Server 2008 (and beyond)
I wanted to take advange of the Admin Approval Mode (AAM) or Over The Shoulder (OST)
UAC elevation prompt automatically (and as a side-effect have the little shield
icon accompanying my app's icon).  This wouldn't be possible on a previous OS
(such as Windows Server 2003 or XP), so I needed to add an explicit permission check.</font>
        </p>
        <p>
          <font face="Tahoma">To get the UAC prompt all you need to do is embed an application
manifest.  Vista+, when displaying the application icon, will probe the app and,
upon finding the manifest requiring admin rights, will display the icon properly.</font>
        </p>
        <p>
          <font face="Tahoma">Create a manifest file (e.g., app.exe.manifest) in your project. 
This is what mine looked like:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;<br />
&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"&gt;<br />
  &lt;assemblyIdentity version="1.0.0.0" name="<strong>APPLICATION_NAME</strong>"/&gt;<br />
  &lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"&gt;<br />
    &lt;security&gt;<br />
      &lt;requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"&gt;<br />
        &lt;requestedExecutionLevel level="<strong>requireAdministrator</strong>"
uiAccess="false"/&gt;<br />
      &lt;/requestedPrivileges&gt;<br />
    &lt;/security&gt;<br />
  &lt;/trustInfo&gt;<br />
&lt;/assembly&gt;</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">By default (if you don't create a manifest), a .NET application
will have the &lt;requestedExecutionLevel /&gt; set to 'asInvoker' and run the application
as the user invoking it.  You can set this to one of three values: asInvoker,
highestAvailable, and requireAdministrator.  Also, don't forget to set the name
to match your application's name.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">Then, to embed the application you can do a few things.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">One technique is to use the <strong>mt.exe</strong> (ManifestTool)
from the Visual Studio Command Prompt:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p dir="ltr">
            <font face="Courier New">mt.exe -manifest app.exe.manifest -updateresource:app.exe,#1</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">But I don't believe this would work if your application is signed
with a strong name unless you were to delay-sign it.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">The easier (and better) approach is to use the Project Properties
--&gt; Application tab.  Simply select your app.exe.manifest file in the Manifest
dropdown.  It will automatically be embedded.</font>
        </p>
        <p dir="ltr">
          <font color="#0000ff" face="Tahoma">
            <em>NOTE: In order to debug your application that
requires admin rights you'll need to run Visual Studio from an elevated token. 
Otherwise you won't have privileges enough to attach to the process.</em>
          </font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">Next, I wanted to ensure that the user runs the application with
administrative rights.  This check was placed particularly for the pre-Vista
operating systems which didn't have UAC.  To do this I added the following code:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p dir="ltr">
            <font face="Courier New">[STAThread()]<br /><font color="#008000">private static void</font> Main() {<br />
   Application.EnableVisualStyles();<br />
   Application.SetCompatibleTextRenderingDefault(<font color="#008000">false</font>);<br /><br />
   <font color="#a9a9a9"><em>// check to make sure that the user is running
with administrative rights.<br />
   // in Vista/Win7/Svr2008 this is automatically taken care of via the<br />
   // embedded manifest (which ensures administrative rights) via UAC.</em></font><br />
   <font color="#008000">try</font> {<br />
      <font color="#008000">if</font> ( !userHasAdminRights()
) {<br />
         MessageBox.Show(<font color="#a52a2a">"This
application requires administrative privileges."</font>,<br />
                         <font color="#a52a2a">"Unauthorized
Access"</font>,<br />
                        
MessageBoxButtons.OK, MessageBoxIcon.Information);<br />
         <font color="#008000">return</font>;<br />
      }<br />
   }<br />
   <font color="#008000">catch</font> ( Exception er ) {<br />
      MessageBox.Show(er.ToString());  <font color="#a9a9a9"><em>//
Of course you'd handle this differently</em></font><br />
   }<br /><br />
   Application.Run(<font color="#008000">new</font> MainForm());<br />
}<br /><br /><br /><font color="#008000">private static bool</font> userHasAdminRights() {<br />
   WindowsIdentity identity = WindowsIdentity.GetCurrent();<br />
   <font color="#008000">return</font> ( <font color="#008000">null</font> !=
identity &amp;&amp; <font color="#008000">new</font> WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator)
);<br />
}</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">Pretty simple, really.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=1a18e011-ea44-459e-84be-55a9046bce7d" />
      </body>
      <title>Enforcing Administrative Privileges</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,1a18e011-ea44-459e-84be-55a9046bce7d.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/10/23/EnforcingAdministrativePrivileges.aspx</link>
      <pubDate>Fri, 23 Oct 2009 02:28:57 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;I had the need today to create an application must run with administrative
privileges.&amp;nbsp; Fortunately, this is a pretty straightforward endeavor.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;On Windows Vista, Windows 7, or Windows Server 2008 (and beyond)
I wanted to take advange of the Admin Approval Mode (AAM) or Over The Shoulder (OST)
UAC&amp;nbsp;elevation prompt automatically (and as a side-effect have the little shield
icon accompanying my app's icon).&amp;nbsp; This wouldn't be possible on a previous OS
(such as Windows Server 2003 or XP), so I needed to add an explicit permission check.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;To get the UAC prompt all you need to do is embed an application
manifest.&amp;nbsp; Vista+, when displaying the application icon, will probe the app and,
upon finding the manifest requiring admin rights, will display the icon properly.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;Create a manifest file (e.g., app.exe.manifest) in your project.&amp;nbsp;
This is what mine looked like:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;&lt;br&gt;
&amp;lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;assemblyIdentity version="1.0.0.0" name="&lt;strong&gt;APPLICATION_NAME&lt;/strong&gt;"/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;security&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;requestedExecutionLevel level="&lt;strong&gt;requireAdministrator&lt;/strong&gt;"
uiAccess="false"/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/requestedPrivileges&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/security&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/trustInfo&amp;gt;&lt;br&gt;
&amp;lt;/assembly&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;By default (if you don't create a manifest), a .NET application
will have the &amp;lt;requestedExecutionLevel /&amp;gt; set to 'asInvoker' and run the application
as the user invoking it.&amp;nbsp; You can set this to one of three values: asInvoker,
highestAvailable, and requireAdministrator.&amp;nbsp; Also, don't forget to set the name
to match your application's name.&lt;/font&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;Then, to embed the application you can do a few things.&lt;/font&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;One technique is to use the &lt;strong&gt;mt.exe&lt;/strong&gt; (ManifestTool)
from the Visual Studio Command Prompt:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p dir=ltr&gt;
&lt;font face="Courier New"&gt;mt.exe -manifest app.exe.manifest -updateresource:app.exe,#1&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;But I don't believe this would work if your application is signed
with a strong name unless you were to delay-sign it.&lt;/font&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;The easier (and better) approach is to use the Project Properties
--&amp;gt; Application tab.&amp;nbsp; Simply select your app.exe.manifest file in the Manifest
dropdown.&amp;nbsp; It will automatically be embedded.&lt;/font&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;font color=#0000ff face=Tahoma&gt;&lt;em&gt;NOTE: In order to debug your application that
requires admin rights you'll need to run Visual Studio from an elevated token.&amp;nbsp;
Otherwise you won't have privileges enough to attach to the process.&lt;/em&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;Next, I wanted to ensure that the user runs the application with
administrative rights.&amp;nbsp; This check was placed particularly for the pre-Vista
operating systems which didn't have UAC.&amp;nbsp; To do this I added the following code:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p dir=ltr&gt;
&lt;font face="Courier New"&gt;[STAThread()]&lt;br&gt;
&lt;font color=#008000&gt;private static void&lt;/font&gt; Main() {&lt;br&gt;
&amp;nbsp;&amp;nbsp; Application.EnableVisualStyles();&lt;br&gt;
&amp;nbsp;&amp;nbsp; Application.SetCompatibleTextRenderingDefault(&lt;font color=#008000&gt;false&lt;/font&gt;);&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp;&lt;font color=#a9a9a9&gt;&lt;em&gt;// check to make sure that the user is running
with administrative rights.&lt;br&gt;
&amp;nbsp;&amp;nbsp; // in Vista/Win7/Svr2008 this is automatically taken care of via the&lt;br&gt;
&amp;nbsp;&amp;nbsp; // embedded manifest (which ensures administrative rights) via UAC.&lt;/em&gt;&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;try&lt;/font&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;if&lt;/font&gt; ( !userHasAdminRights()
) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(&lt;font color=#a52a2a&gt;"This
application requires administrative privileges."&lt;/font&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#a52a2a&gt;"Unauthorized
Access"&lt;/font&gt;,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
MessageBoxButtons.OK, MessageBoxIcon.Information);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;return&lt;/font&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;catch&lt;/font&gt; ( Exception er ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageBox.Show(er.ToString());&amp;nbsp; &lt;font color=#a9a9a9&gt;&lt;em&gt;//
Of course you'd handle this differently&lt;/em&gt;&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; Application.Run(&lt;font color=#008000&gt;new&lt;/font&gt; MainForm());&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;font color=#008000&gt;private static bool&lt;/font&gt; userHasAdminRights() {&lt;br&gt;
&amp;nbsp;&amp;nbsp; WindowsIdentity identity = WindowsIdentity.GetCurrent();&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;font color=#008000&gt;return&lt;/font&gt; ( &lt;font color=#008000&gt;null&lt;/font&gt; !=
identity &amp;amp;&amp;amp; &lt;font color=#008000&gt;new&lt;/font&gt; WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator)
);&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;Pretty simple, really.&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=1a18e011-ea44-459e-84be-55a9046bce7d" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,1a18e011-ea44-459e-84be-55a9046bce7d.aspx</comments>
      <category>C#</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=bc8582e7-73de-49d7-bb91-c801bf9f71ba</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,bc8582e7-73de-49d7-bb91-c801bf9f71ba.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,bc8582e7-73de-49d7-bb91-c801bf9f71ba.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=bc8582e7-73de-49d7-bb91-c801bf9f71ba</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">Here's something I threw together the other day to help me organize
my ripped audio books.  I have several audio books (Harry Potter, LOTR, Dresden
Files, etc) that I've been ripping to file so that I could gather an entire 10-20
CD set onto a single disc for easy listening while driving without needing to switch
discs.  I like to use WMA files for easy ripping (via Media Player) and the small
footprint.</font>
        </p>
        <p>
          <font face="Tahoma">I've found, much to my chagrin, that the information retrieved
online for these books (via CDDB, FreeDB, or All Music Guide (which WMP uses))
is unreliable, frequently contains typos and misspellings, and is extremely inconsistent
with respect to formatting and convention.</font>
        </p>
        <p>
          <font face="Tahoma">I found that when I inserted a CD I would spend a good amount
of time entering the book name, the genre, the year it was recorded, the author, and
the performer, and I'd take the time to rename the tracks.  After a handful of
CDs this was almost unbearable and extremely tedious.</font>
        </p>
        <p>
          <font face="Tahoma">I therefore set out to write a script that would do this, updating
all of the ID3 tags after the fact.  The only thing I would need to concern myself
with was that the book name (I like the form <em>Book Name - Disc XX</em>) was correct. 
This script belows makes a few assumptions about the folder and file names:</font>
        </p>
        <ul>
          <li>
            <font face="Tahoma">each folder contains a single disk and that they are named according
to the pattern <em>"Book Name - Disc XX"</em></font>
          </li>
          <li>
            <font face="Tahoma">all books will be collected into a single folder with the name
pattern <em>"Book Set - Book Name"</em></font>
          </li>
        </ul>
        <p>
          <font face="Tahoma">For example, I ripped a book by </font>
          <a href="http://www.jim-butcher.com/">
            <font face="Tahoma">Jim
Butcher</font>
          </a>
          <font face="Tahoma"> named Small Favor.  Each disc went into
a folder named "Small Favor - Disc 01", "Small Favor - Disc 02", etc.  I would
then collect all the ripped files into a single directory named "Dresden Files - Book
10 - Small Favor".  This way, when all was said and done, I'd have all the books
in order and grouped.</font>
        </p>
        <p>
          <font face="Tahoma">I decided to use <a href="http://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx">PowerShell</a> as
the language of preference for automating this procedure.  Not only does it provide
a very powerful scripting environment, but I can also leverage the .NET Framework
(which I love dearly).  As such, I was able to take advantage of </font>
          <a href="http://developer.novell.com/wiki/index.php/TagLib_Sharp">
            <font face="Tahoma">TagLib#</font>
          </a>
          <font face="Tahoma">'s
ability to edit the tags within the files.  This script assumes that the taglib-sharp.dll
is in the same directory as the .ps1 script file.</font>
        </p>
        <p>
          <font face="Tahoma">The following PowerShell scripts performs all the collecting,
enumerating, and tagging of my files.  Feel free to adapt it and tweak it according
to your own preferences.  If you have suggestions, I'd welcome them.  Like
I said, I threw it together in a very short time so it's probably weak in many regards
but seems to get the job done.</font>
        </p>
        <p>
          <font face="Tahoma">Taking my example above, my command line would be:</font>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <em>
              <font face="Tahoma">.\collectaudiobook "Small Favor" "Dresden Files - Book 10"
"Jim Butcher" "James Marsters" 2008</font>
            </em>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">Now I don't need to worry about what information was loaded from
the CDDB-esque service, the script updates it all after-the-fact. :)</font>
        </p>
        <p>
          <strong>
            <font size="3" face="Courier New">CollectAudioBook.ps1</font>
          </strong>
        </p>
        <blockquote style="MARGIN-RIGHT: 0px" dir="ltr">
          <p>
            <font face="Courier New">$a = $args.length</font>
          </p>
          <p>
            <font face="Courier New">if ( $a -lt 2 ) {<br />
  write @"</font>
          </p>
          <p>
            <font face="Courier New">USAGE:</font>
          </p>
          <p>
            <font face="Courier New">`t.\CollectAudioBook.ps1 titlePrefix targetFolderPrefix [author]
[artist] [year]</font>
          </p>
          <p>
            <font face="Courier New">REQUIRED PARAMETERS:</font>
          </p>
          <p>
            <font face="Courier New">titlePrefix<br />
`tSpecifies the subfolders to process as a single book.<br />
`t(e.g., 'Small Favor' would locate 'Small Favor - Disc 01', 'Small Favor - Disc 02',
etc)<br />
`tThe folders are processed in order by name, assuming that to be the proper sequencing
of the resulting files.</font>
          </p>
          <p>
            <font face="Courier New">targetFolderPrefix<br />
`tSpecifies the target folder to which all tracks are collected.  If this<br />
`tfolder doesn't exist, it is created.<br />
`tNOTE: The folder's full name will be comprised of the targetFolderPrefix, a hyphen,
and the titlePrefix.<br />
`t(e.g., a titlePrefix of 'Small Favor' and a targetFolderPrefix of 'Dresden Files
- Book 10' becomes<br />
`tDresden Files - Book 10 - Small Favor)</font>
          </p>
          <p>
            <font face="Courier New">author<br />
`tIdentifies the author of the book.</font>
          </p>
          <p>
            <font face="Courier New">artist<br />
`tIdentifies the name of the performer.</font>
          </p>
          <p>
            <font face="Courier New">year<br />
`tIdentifies the year of the recording.</font>
          </p>
          <p>
            <font face="Courier New">"@<br />
  exit<br />
}</font>
          </p>
          <p>
            <font face="Courier New">$bookName = $args[0]<br />
$bookSet = $args[1] + ' - ' + $bookName<br />
$author = $args[2]<br />
$artist = $args[3]<br />
$year = $args[4]</font>
          </p>
          <p>
            <font face="Courier New">$target = '.\' + $bookSet<br />
$partNum = 0</font>
          </p>
          <p>
            <font face="Courier New"># load taglib-sharp.dll which allows for the manipulation
on the media tags in the files<br />
$asm = [Reflection.Assembly]::LoadFrom((Resolve-Path ".\taglib-sharp.dll"))</font>
          </p>
          <p>
            <font face="Courier New"># create the target directory<br />
$dir = New-Item -path "$target" -type directory -force</font>
          </p>
          <p>
            <font face="Courier New"># enumerate all files in each folder that start with the
prefix, copying and renaming each file<br />
foreach ( $folder in ( Get-ChildItem .\$bookName* | Where-Object { $_.Mode.StartsWith('d')
} | Sort Name ) ) {<br />
  foreach ( $file in ( Get-ChildItem $folder | Sort Name ) ) {<br />
    ++$partNum</font>
          </p>
          <p>
            <font face="Courier New">    $targetPrefix = 'Part ' + $partNum.ToString("00")<br />
    $targetFileName = $targetPrefix + '.wma'<br />
    write "Copying $file`t--&gt;`t$targetFileName"<br />
    Copy-Item $folder\$file $target\$targetFileName</font>
          </p>
          <p>
            <font face="Courier New">    # update the media information in the file<br />
    $media = [TagLib.File]::Create((Resolve-Path "$target\$targetFileName"))<br />
    $media.Tag.Title = $bookName + ' - ' + $targetPrefix<br />
    if ( $author -ne $null ) { $media.Tag.AlbumArtists = $author }<br />
    if ( $artist -ne $null ) { $media.Tag.Performers = $artist }<br />
    $media.Tag.Genres = { Audio Book }<br />
    if ( $year -ne $null ) { $media.Tag.Year = $year }<br />
    $media.Save()<br />
  }<br />
}</font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=bc8582e7-73de-49d7-bb91-c801bf9f71ba" />
      </body>
      <title>Simplifying the Ripping of AudioBooks and Tagging with PowerShell</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,bc8582e7-73de-49d7-bb91-c801bf9f71ba.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/08/25/SimplifyingTheRippingOfAudioBooksAndTaggingWithPowerShell.aspx</link>
      <pubDate>Tue, 25 Aug 2009 05:20:53 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;Here's something I threw together the other day to help me organize
my ripped audio books.&amp;nbsp; I have several audio books (Harry Potter, LOTR, Dresden
Files, etc) that I've been ripping to file so that I could gather an entire 10-20
CD set onto a single disc for easy listening while driving without needing to switch
discs.&amp;nbsp; I like to use WMA files for easy ripping (via Media Player) and the small
footprint.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I've found, much to my chagrin, that the information retrieved online
for these books&amp;nbsp;(via CDDB, FreeDB, or All Music Guide (which WMP uses)) is unreliable,
frequently contains typos and misspellings, and is extremely inconsistent with respect
to formatting and convention.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I found that when I inserted a CD I would spend a good amount of
time entering the book name, the genre, the year it was recorded, the author, and
the performer, and I'd take the time to rename the tracks.&amp;nbsp; After a handful of
CDs this was almost unbearable and extremely tedious.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I therefore set out to write a script that would do this, updating
all of the ID3 tags after the fact.&amp;nbsp; The only thing I would need to concern myself
with was that the book name (I like the form &lt;em&gt;Book Name - Disc XX&lt;/em&gt;) was correct.&amp;nbsp;
This script belows makes a few assumptions about the folder and file names:&lt;/font&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face=Tahoma&gt;each folder contains a single disk and that they are named according
to the pattern &lt;em&gt;"Book Name - Disc XX"&lt;/em&gt;&lt;/font&gt; 
&lt;li&gt;
&lt;font face=Tahoma&gt;all books will be collected into a single folder with the name pattern &lt;em&gt;"Book
Set - Book Name"&lt;/em&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;For example, I ripped a book by &lt;/font&gt;&lt;a href="http://www.jim-butcher.com/"&gt;&lt;font face=Tahoma&gt;Jim
Butcher&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt; named Small Favor.&amp;nbsp; Each disc went into
a folder named "Small Favor - Disc 01", "Small Favor - Disc 02", etc.&amp;nbsp; I would
then collect all the ripped files into a single directory named "Dresden Files - Book
10 - Small Favor".&amp;nbsp; This way, when all was said and done, I'd have all the books
in order and grouped.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I decided to use &lt;a href="http://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx"&gt;PowerShell&lt;/a&gt; as
the language of preference for automating this procedure.&amp;nbsp; Not only does it provide
a very powerful scripting environment, but I can also leverage the .NET Framework
(which I love dearly).&amp;nbsp; As such, I was able to take advantage of &lt;/font&gt;&lt;a href="http://developer.novell.com/wiki/index.php/TagLib_Sharp"&gt;&lt;font face=Tahoma&gt;TagLib#&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt;'s
ability to edit the tags within the files.&amp;nbsp; This script assumes that the taglib-sharp.dll
is in the same directory as the .ps1 script file.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;The following PowerShell scripts performs all the collecting, enumerating,
and tagging of my files.&amp;nbsp; Feel free to adapt it and tweak it according to your
own preferences.&amp;nbsp; If you have suggestions, I'd welcome them.&amp;nbsp; Like I said,
I threw it together in a very short time so it's probably weak in many regards but
seems to get the job done.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;Taking my example above, my command line would be:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;em&gt;&lt;font face=Tahoma&gt;.\collectaudiobook "Small Favor" "Dresden Files - Book 10" "Jim
Butcher" "James Marsters" 2008&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;Now I don't need to worry about what information was loaded from
the CDDB-esque service,&amp;nbsp;the script&amp;nbsp;updates it all after-the-fact. :)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=3 face="Courier New"&gt;CollectAudioBook.ps1&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir=ltr&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;$a = $args.length&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;if ( $a -lt 2 ) {&lt;br&gt;
&amp;nbsp; write @"&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;USAGE:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;`t.\CollectAudioBook.ps1 titlePrefix targetFolderPrefix [author]
[artist] [year]&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;REQUIRED PARAMETERS:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;titlePrefix&lt;br&gt;
`tSpecifies the subfolders to process as a single book.&lt;br&gt;
`t(e.g., 'Small Favor' would locate 'Small Favor - Disc 01', 'Small Favor - Disc 02',
etc)&lt;br&gt;
`tThe folders are processed in order by name, assuming that to be the proper sequencing
of the resulting files.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;targetFolderPrefix&lt;br&gt;
`tSpecifies the target folder to which all tracks are collected.&amp;nbsp; If this&lt;br&gt;
`tfolder doesn't exist, it is created.&lt;br&gt;
`tNOTE: The folder's full name will be comprised of the targetFolderPrefix, a hyphen,
and the titlePrefix.&lt;br&gt;
`t(e.g., a titlePrefix of 'Small Favor' and a targetFolderPrefix of 'Dresden Files
- Book 10' becomes&lt;br&gt;
`tDresden Files - Book 10 - Small Favor)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;author&lt;br&gt;
`tIdentifies the author of the book.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;artist&lt;br&gt;
`tIdentifies the name of the performer.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;year&lt;br&gt;
`tIdentifies the year of the recording.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;"@&lt;br&gt;
&amp;nbsp; exit&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;$bookName = $args[0]&lt;br&gt;
$bookSet = $args[1] + ' - ' + $bookName&lt;br&gt;
$author = $args[2]&lt;br&gt;
$artist = $args[3]&lt;br&gt;
$year = $args[4]&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;$target = '.\' + $bookSet&lt;br&gt;
$partNum = 0&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# load taglib-sharp.dll which allows for the manipulation
on the media tags in the files&lt;br&gt;
$asm = [Reflection.Assembly]::LoadFrom((Resolve-Path ".\taglib-sharp.dll"))&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# create the target directory&lt;br&gt;
$dir = New-Item -path "$target" -type directory -force&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;# enumerate all files in each folder that start with the
prefix, copying and renaming each file&lt;br&gt;
foreach ( $folder in ( Get-ChildItem .\$bookName* | Where-Object { $_.Mode.StartsWith('d')
} | Sort Name ) ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;foreach ( $file in ( Get-ChildItem $folder | Sort Name ) ) {&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;++$partNum&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; &amp;nbsp; $targetPrefix = 'Part ' + $partNum.ToString("00")&lt;br&gt;
&amp;nbsp; &amp;nbsp; $targetFileName = $targetPrefix + '.wma'&lt;br&gt;
&amp;nbsp; &amp;nbsp; write "Copying $file`t--&amp;gt;`t$targetFileName"&lt;br&gt;
&amp;nbsp; &amp;nbsp; Copy-Item $folder\$file $target\$targetFileName&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; &amp;nbsp; # update the media information in the file&lt;br&gt;
&amp;nbsp; &amp;nbsp; $media = [TagLib.File]::Create((Resolve-Path "$target\$targetFileName"))&lt;br&gt;
&amp;nbsp; &amp;nbsp; $media.Tag.Title = $bookName + ' - ' + $targetPrefix&lt;br&gt;
&amp;nbsp; &amp;nbsp; if ( $author -ne $null ) { $media.Tag.AlbumArtists = $author }&lt;br&gt;
&amp;nbsp; &amp;nbsp; if ( $artist -ne $null ) { $media.Tag.Performers = $artist }&lt;br&gt;
&amp;nbsp; &amp;nbsp; $media.Tag.Genres = { Audio Book }&lt;br&gt;
&amp;nbsp; &amp;nbsp; if ( $year -ne $null ) { $media.Tag.Year = $year }&lt;br&gt;
&amp;nbsp; &amp;nbsp; $media.Save()&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=bc8582e7-73de-49d7-bb91-c801bf9f71ba" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,bc8582e7-73de-49d7-bb91-c801bf9f71ba.aspx</comments>
      <category>.NET</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=9cf329d9-8865-4722-ba21-25e308a28325</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,9cf329d9-8865-4722-ba21-25e308a28325.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,9cf329d9-8865-4722-ba21-25e308a28325.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=9cf329d9-8865-4722-ba21-25e308a28325</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font size="2" face="Tahoma">
            <a href="http://windowsteamblog.com/blogs/windows7/archive/2009/07/21/when-will-you-get-windows-7-rtm.aspx" target="_blank">http://windowsteamblog.com/blogs/windows7/archive/2009/07/21/when-will-you-get-windows-7-rtm.aspx</a>
          </font>
        </p>
        <p>
          <font size="2" face="Tahoma">Can't wait! I've been using Windows 7 in the Beta and
RC (Release Candidate) builds for some time now and I LOVE it! It's been rock solid
(particularly for it's pre-release form) and very fast. It's been my primary OS now
on 3 separate computers so I'm really excited about being able to get my hands on
the RTM version in the next few weeks.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=9cf329d9-8865-4722-ba21-25e308a28325" />
      </body>
      <title>Get your hands on the Windows 7 RTM...soon!</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,9cf329d9-8865-4722-ba21-25e308a28325.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/07/22/GetYourHandsOnTheWindows7RTMsoon.aspx</link>
      <pubDate>Wed, 22 Jul 2009 19:11:47 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font size="2" face="Tahoma"&gt;&lt;a href="http://windowsteamblog.com/blogs/windows7/archive/2009/07/21/when-will-you-get-windows-7-rtm.aspx" target="_blank"&gt;http://windowsteamblog.com/blogs/windows7/archive/2009/07/21/when-will-you-get-windows-7-rtm.aspx&lt;/a&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="2" face="Tahoma"&gt;Can't wait! I've been using Windows 7 in the Beta and
RC (Release Candidate) builds for some time now and I LOVE it! It's been rock solid
(particularly for it's pre-release form) and very fast. It's been my primary OS now
on 3 separate computers so I'm really excited about being able to get my hands on
the RTM version in the next few weeks.&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=9cf329d9-8865-4722-ba21-25e308a28325" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,9cf329d9-8865-4722-ba21-25e308a28325.aspx</comments>
      <category>Windows</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=41af86d0-e4cf-47b5-abd8-8f048a3cff61</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,41af86d0-e4cf-47b5-abd8-8f048a3cff61.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,41af86d0-e4cf-47b5-abd8-8f048a3cff61.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=41af86d0-e4cf-47b5-abd8-8f048a3cff61</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <font size="2" face="Tahoma">Well, I've
always <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;261186">loved
classical music</a>...too bad I'm not on Windows 95 anymore.<br /></font>
        <p>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=41af86d0-e4cf-47b5-abd8-8f048a3cff61" />
      </body>
      <title>Windows Classical Music</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,41af86d0-e4cf-47b5-abd8-8f048a3cff61.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/06/17/WindowsClassicalMusic.aspx</link>
      <pubDate>Wed, 17 Jun 2009 19:20:03 GMT</pubDate>
      <description>&lt;font size="2" face="Tahoma"&gt;Well, I've always &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;261186"&gt;loved
classical music&lt;/a&gt;...too bad I'm not on Windows 95 anymore.&lt;br&gt;
&lt;/font&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=41af86d0-e4cf-47b5-abd8-8f048a3cff61" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,41af86d0-e4cf-47b5-abd8-8f048a3cff61.aspx</comments>
      <category>Humor</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=21a5f7e2-3cb4-4092-a438-11015b78f657</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,21a5f7e2-3cb4-4092-a438-11015b78f657.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,21a5f7e2-3cb4-4092-a438-11015b78f657.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=21a5f7e2-3cb4-4092-a438-11015b78f657</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <font face="Tahoma">
          <font size="2">This
is definitely not news, but I wanted to blog it anyway.<br /><br />
Having recently just reset a development server to use Windows Server 2008, I needed
to open the firewall to allow ICMP packets through.  Essentially, I wanted to
have the server respond to PING requests.  On a fresh Windows Vista or Windows
Server 2008 install (and I imagine Windows 7, though I've not checked), the ICMP protocol
is blocked by default; the server won't respond to PINGs.  When you ping an IP
address and don't get a reply that doesn't mean that there isn't a computer on the
other end, but it sure is a handy way to check.<br /><br />
In Windows Vista/2008 enabling ICMP through the firewall isn't difficult, but if you
want to use a GUI, you have to do it through an inbound rule in the <b>Windows Firewall
with Advanced Security</b> option.<br /><br />
Personally, I prefer to do it via the command-line through this simple operation: <b>netsh
firewall set icmpsetting 8</b></font>
          <br />
        </font>
        <p>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=21a5f7e2-3cb4-4092-a438-11015b78f657" />
      </body>
      <title>Enabling PING in Windows Server 2008 and Vista</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,21a5f7e2-3cb4-4092-a438-11015b78f657.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/06/12/EnablingPINGInWindowsServer2008AndVista.aspx</link>
      <pubDate>Fri, 12 Jun 2009 22:41:21 GMT</pubDate>
      <description>&lt;font face="Tahoma"&gt;&lt;font size="2"&gt;This is definitely not news, but I wanted to blog
it anyway.&lt;br&gt;
&lt;br&gt;
Having recently just reset a development server to use Windows Server 2008, I needed
to open the firewall to allow ICMP packets through.&amp;nbsp; Essentially, I wanted to
have the server respond to PING requests.&amp;nbsp; On a fresh Windows Vista or Windows
Server 2008 install (and I imagine Windows 7, though I've not checked), the ICMP protocol
is blocked by default; the server won't respond to PINGs.&amp;nbsp; When you ping an IP
address and don't get a reply that doesn't mean that there isn't a computer on the
other end, but it sure is a handy way to check.&lt;br&gt;
&lt;br&gt;
In Windows Vista/2008 enabling ICMP through the firewall isn't difficult, but if you
want to use a GUI, you have to do it through an inbound rule in the &lt;b&gt;Windows Firewall
with Advanced Security&lt;/b&gt; option.&lt;br&gt;
&lt;br&gt;
Personally, I prefer to do it via the command-line through this simple operation: &lt;b&gt;netsh
firewall set icmpsetting 8&lt;/b&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=21a5f7e2-3cb4-4092-a438-11015b78f657" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,21a5f7e2-3cb4-4092-a438-11015b78f657.aspx</comments>
      <category>Windows Vista</category>
      <category>Windows Server 2008</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=b1532b74-f32c-4bfb-9943-294340251147</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,b1532b74-f32c-4bfb-9943-294340251147.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,b1532b74-f32c-4bfb-9943-294340251147.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=b1532b74-f32c-4bfb-9943-294340251147</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">As you may or may not be aware IE 7+ (and other browsers) support
using CSS 2.1 </font>
          <a href="http://www.w3.org/TR/CSS21/selector.html">
            <font face="Tahoma">attribute
selectors</font>
          </a>
          <font face="Tahoma">.  Attribute selectors allow you to specify
a style on an element whose element matches a particular pattern.  For instance:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">td[x] { font-weight:bold; }</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">This selector will bold the text of any TD element on the page
that has an attribute "x" (regardless of value).  Other attribute selector styles
include:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Tahoma">
              <font face="Courier New">...[x="value"]</font> matches where x
is exactly 'value'<br /><font face="Courier New">...[x~="value"]</font> matches where x contains a space-separated list
of values, one of which is exactly 'value'<br /><font face="Courier New">...[x^="value"]</font> matches where the attribute x begins
with 'value'<br /><font face="Courier New">...[x$="value"]</font> matches where the attribute x ends
with 'value'<br /><font face="Courier New">...[x*="value"]</font> matches where the attribute x contains
'value'<br /><font face="Courier New">...[x|="value"]</font> matches where the attribute x begins
with either 'value' or 'value-'</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">In and of themselves, these are pretty darn cool.  You can
do some neat things with CSS and HTML.</font>
        </p>
        <p>
          <font face="Tahoma">I ran into an interested scenario this past week that I'd like
to share.  I have some JavaScript that alters the value of attributes at runtime. 
I found that the page doesn't automatically update according to the stylesheet specification. 
Curiously, it would update when I moused-over the element in question.</font>
        </p>
        <p>
          <font face="Tahoma">I found, however, that I could force the issue by assigning the
CSS classname to the element that it already has.  This is enough to trigger
the change and have the element update according to its attribute values.</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;<br />
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;<br />
&lt;head&gt;<br />
   &lt;style type="text/css"&gt;<br />
      td[req] { font-weight:bold; }<br />
      td[err="1"] { color:red !important; }<br />
   &lt;/style&gt;<br />
   &lt;script type="text/javascript"&gt;<br />
      function fn() {<br />
         var td = document.getElementById("t");<br />
         td.err = "0";<br />
         td.className = td.className; 
// trigger the change by reassigning the CSS class<br />
      }<br />
   &lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
   &lt;table&gt;<br />
      &lt;tr&gt;&lt;td class="test" err="1" req="1" id="t"&gt;Cell&lt;/td&gt;&lt;/tr&gt;<br />
   &lt;/table&gt;<br />
   &lt;button onclick="javascript:fn();"&gt;Remove Error&lt;/button&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Interestingly, for this to work properly in a non-IE browser (such
as Firefox), I found I could not use the object.property=value syntax.  Instead,
I had to use the SetAttribute() function.  Also, with Firefox, reassigning the
className was unnecessary.</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">td.setAttribute("err", "0");</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">That's probably the best way to handle it then, for cross-browser
compliance.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=b1532b74-f32c-4bfb-9943-294340251147" />
      </body>
      <title>CSS Attribute Selector Magic</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,b1532b74-f32c-4bfb-9943-294340251147.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/05/04/CSSAttributeSelectorMagic.aspx</link>
      <pubDate>Mon, 04 May 2009 04:28:44 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;As you may or may not be aware IE 7+ (and other browsers) support
using CSS 2.1 &lt;/font&gt;&lt;a href="http://www.w3.org/TR/CSS21/selector.html"&gt;&lt;font face=Tahoma&gt;attribute
selectors&lt;/font&gt;&lt;/a&gt;&lt;font face=Tahoma&gt;.&amp;nbsp; Attribute selectors allow you to specify
a style on an element whose element matches a particular pattern.&amp;nbsp; For instance:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;td[x] { font-weight:bold; }&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;This selector will bold the text of any TD element on the page that
has an attribute "x" (regardless of value).&amp;nbsp; Other attribute selector styles
include:&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;&lt;font face="Courier New"&gt;...[x="value"]&lt;/font&gt; matches where x is
exactly 'value'&lt;br&gt;
&lt;font face="Courier New"&gt;...[x~="value"]&lt;/font&gt; matches where x contains a space-separated&amp;nbsp;list
of values, one of which is exactly 'value'&lt;br&gt;
&lt;font face="Courier New"&gt;...[x^="value"]&lt;/font&gt; matches where the attribute x begins
with 'value'&lt;br&gt;
&lt;font face="Courier New"&gt;...[x$="value"]&lt;/font&gt; matches where the attribute x ends
with 'value'&lt;br&gt;
&lt;font face="Courier New"&gt;...[x*="value"]&lt;/font&gt; matches where the attribute x contains
'value'&lt;br&gt;
&lt;font face="Courier New"&gt;...[x|="value"]&lt;/font&gt; matches where the attribute x begins
with either 'value' or 'value-'&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;In and of themselves, these are pretty darn cool.&amp;nbsp; You can
do some neat things with CSS and HTML.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I ran into an interested scenario this past week that I'd like to
share.&amp;nbsp; I have some JavaScript that alters the value of attributes at runtime.&amp;nbsp;
I found that the page doesn't automatically update according to the stylesheet specification.&amp;nbsp;
Curiously, it would update when I moused-over the element in question.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;I found, however, that I could force the issue by assigning the
CSS classname to the element that it already has.&amp;nbsp; This is enough to trigger
the change and have the element update according to its attribute values.&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&amp;gt;&lt;br&gt;
&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br&gt;
&amp;lt;head&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;style type="text/css"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; td[req] { font-weight:bold; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; td[err="1"] { color:red !important; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;/style&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; function fn() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; var td = document.getElementById("t");&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; td.err = "0";&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;td.className = td.className;&amp;nbsp;
// trigger the change by reassigning the CSS class&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br&gt;
&amp;lt;/head&amp;gt;&lt;br&gt;
&amp;lt;body&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;table&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&amp;lt;td class="test" err="1" req="1" id="t"&amp;gt;Cell&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;lt;button onclick="javascript:fn();"&amp;gt;Remove Error&amp;lt;/button&amp;gt;&lt;br&gt;
&amp;lt;/body&amp;gt;&lt;br&gt;
&amp;lt;/html&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face=Tahoma&gt;Interestingly, for this to work properly in a non-IE browser (such
as Firefox), I found I could not use the object.property=value syntax.&amp;nbsp; Instead,
I had to use the SetAttribute() function.&amp;nbsp; Also, with Firefox, reassigning the
className was unnecessary.&lt;/font&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;td.setAttribute("err", "0");&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
&lt;font face=Tahoma&gt;That's probably the best way to handle it then, for cross-browser
compliance.&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=b1532b74-f32c-4bfb-9943-294340251147" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,b1532b74-f32c-4bfb-9943-294340251147.aspx</comments>
      <category>CSS</category>
      <category>Web</category>
    </item>
    <item>
      <trackback:ping>http://blog.devstone.com/aaron/Trackback.aspx?guid=eb7b0741-d973-4dda-9325-1a4cf5f3fdfc</trackback:ping>
      <pingback:server>http://blog.devstone.com/aaron/pingback.aspx</pingback:server>
      <pingback:target>http://blog.devstone.com/aaron/PermaLink,guid,eb7b0741-d973-4dda-9325-1a4cf5f3fdfc.aspx</pingback:target>
      <dc:creator>R. Aaron Zupancic (Administrator)</dc:creator>
      <wfw:comment>http://blog.devstone.com/aaron/CommentView,guid,eb7b0741-d973-4dda-9325-1a4cf5f3fdfc.aspx</wfw:comment>
      <wfw:commentRss>http://blog.devstone.com/aaron/SyndicationService.asmx/GetEntryCommentsRss?guid=eb7b0741-d973-4dda-9325-1a4cf5f3fdfc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">My buddy Rob Bagby has announced this exciting event called <strong>XamlFest</strong> which
will be in Salt Lake City on May 1st.  If you have the chance, I'd encourage
you to sign up and attend.</font>
        </p>
        <p>
          <font face="Tahoma">Here's the info: </font>
          <a href="http://blogs.msdn.com/bags/archive/2009/03/31/xamlfest-in-salt-lake-city-on-may-1.aspx">
            <font face="Tahoma">http://blogs.msdn.com/bags/archive/2009/03/31/xamlfest-in-salt-lake-city-on-may-1.aspx</font>
          </a>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=eb7b0741-d973-4dda-9325-1a4cf5f3fdfc" />
      </body>
      <title>XamlFest in SLC on May 1st</title>
      <guid isPermaLink="false">http://blog.devstone.com/aaron/PermaLink,guid,eb7b0741-d973-4dda-9325-1a4cf5f3fdfc.aspx</guid>
      <link>http://blog.devstone.com/aaron/2009/04/23/XamlFestInSLCOnMay1st.aspx</link>
      <pubDate>Thu, 23 Apr 2009 19:35:44 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face=Tahoma&gt;My buddy Rob Bagby has announced this exciting event called &lt;strong&gt;XamlFest&lt;/strong&gt; which
will be in Salt Lake City on May 1st.&amp;nbsp; If you have the chance, I'd encourage
you to sign up and attend.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Tahoma&gt;Here's the info: &lt;/font&gt;&lt;a href="http://blogs.msdn.com/bags/archive/2009/03/31/xamlfest-in-salt-lake-city-on-may-1.aspx"&gt;&lt;font face=Tahoma&gt;http://blogs.msdn.com/bags/archive/2009/03/31/xamlfest-in-salt-lake-city-on-may-1.aspx&lt;/font&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=eb7b0741-d973-4dda-9325-1a4cf5f3fdfc" /&gt;</description>
      <comments>http://blog.devstone.com/aaron/CommentView,guid,eb7b0741-d973-4dda-9325-1a4cf5f3fdfc.aspx</comments>
      <category>Events</category>
    </item>
  </channel>
</rss>