<?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>Jesper Niedermann's .NET Blog - Tips &amp; Tricks</title>
    <link>http://www.niedermann.dk/</link>
    <description>about .NET and related technologies</description>
    <language>en-us</language>
    <copyright>Jesper Niedermann</copyright>
    <lastBuildDate>Tue, 31 Aug 2010 16:31:11 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>jesper@niedermann.dk</managingEditor>
    <webMaster>jesper@niedermann.dk</webMaster>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=85830aad-38de-4edb-9c1c-da24a00a7fb9</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,85830aad-38de-4edb-9c1c-da24a00a7fb9.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,85830aad-38de-4edb-9c1c-da24a00a7fb9.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=85830aad-38de-4edb-9c1c-da24a00a7fb9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The new Guidance Automation Framework GAX 2010 and GAT 2010 which is installed through
the Extension Manager in Visual Studio 2010, provides a nicer usability experience
compared to the Visual Studio 2008 predecessor. It is installed using the new vsix
installer. A vsix install is much nicer than the old msi install since it integrates
into Visual Studio. You can uninstall using the Extension Manager and if a new version
comes out it should appear on the Updates tab of the extension manager.
</p>
        <p>
Another nice thing is that a generated factory template solution now only consists
of one project which itself results in a vsix file. So the installer of your own generated
factories will also be vsix files. Nice…
</p>
        <p>
But nicest of all is the fact that it is automatically integrated with the Visual
Studio 2010 Experimental Instance (formerly known as Experimental Hive). Before you
had to manually edit your recipes to get them to register in the Experimental Hive.
But know you just press Ctrl+F5 and the Experimental Instance is automatically launched
with your factory installed. It is now almost easy to debug your recipes. :)
</p>
        <p>
But apparently there are few weird bugs in GAX/GAT 2010. One I run into all the time
is this error:
</p>
        <p>
Unable to read the project file 'Something.csproj'. 
</p>
        <p>
C:\Something\Something\Something.csproj(354,3): The imported project "C:\Microsoft.Practices.RecipeFramework.Build.targets"
was not found. Confirm that the path in the &lt;Import&gt; declaration is correct,
and that the file exists on disk.
</p>
        <p>
Which happens when I try to open a Guidance Automation solution. 
</p>
        <p>
For some reason the declaration of the variable RecipeFramework in the project file
is not provided. This I deal with by editing the Project file by hand and adding a
declaration to the end of the first PropertyGroup like this: 
</p>
        <p>
  
</p>
        <pre class="xml" name="code">  &lt;RecipeFrameworkPath&gt;$(DevEnvDir)Extensions\Microsoft patterns and practices\GAX 2010\2.0.20406.0&lt;/RecipeFrameworkPath&gt;</pre>
        <p>
After applying this fix I can open the solution.
</p>
        <p>
I have read somewhere that it is important to adhere to the following install order:
</p>
        <ol>
        </ol>
        <ol>
          <li>
Visual Studio 2010 Ultimate or Professional (obviously) 
</li>
          <li>
The Visual Studio 2010 SDK 
</li>
          <li>
GAX 2010 
</li>
          <li>
GAT 2010</li>
        </ol>
        <p>
And this might be what I have screwed up on the particular machine where I get the
error. 
</p>
        <p>
Anyway the above mentioned fix works. And overall I am very satisfied with the new
improvements in GAX/GAT.
</p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=85830aad-38de-4edb-9c1c-da24a00a7fb9" />
      </body>
      <title>Guidance Automation 2010 Bug: The imported project "C:\Microsoft.Practices.RecipeFramework.Build.targets" was not found</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,85830aad-38de-4edb-9c1c-da24a00a7fb9.aspx</guid>
      <link>http://www.niedermann.dk/2010/08/31/GuidanceAutomation2010BugTheImportedProjectCMicrosoftPracticesRecipeFrameworkBuildtargetsWasNotFound.aspx</link>
      <pubDate>Tue, 31 Aug 2010 16:31:11 GMT</pubDate>
      <description>&lt;p&gt;
The new Guidance Automation Framework GAX 2010 and GAT 2010 which is installed through
the Extension Manager in Visual Studio 2010, provides a nicer usability experience
compared to the Visual Studio 2008 predecessor. It is installed using the new vsix
installer. A vsix install is much nicer than the old msi install since it integrates
into Visual Studio. You can uninstall using the Extension Manager and if a new version
comes out it should appear on the Updates tab of the extension manager.
&lt;/p&gt;
&lt;p&gt;
Another nice thing is that a generated factory template solution now only consists
of one project which itself results in a vsix file. So the installer of your own generated
factories will also be vsix files. Nice…
&lt;/p&gt;
&lt;p&gt;
But nicest of all is the fact that it is automatically integrated with the Visual
Studio 2010 Experimental Instance (formerly known as Experimental Hive). Before you
had to manually edit your recipes to get them to register in the Experimental Hive.
But know you just press Ctrl+F5 and the Experimental Instance is automatically launched
with your factory installed. It is now almost easy to debug your recipes. :)
&lt;/p&gt;
&lt;p&gt;
But apparently there are few weird bugs in GAX/GAT 2010. One I run into all the time
is this error:
&lt;/p&gt;
&lt;p&gt;
Unable to read the project file 'Something.csproj'. 
&lt;p&gt;
C:\Something\Something\Something.csproj(354,3): The imported project "C:\Microsoft.Practices.RecipeFramework.Build.targets"
was not found. Confirm that the path in the &amp;lt;Import&amp;gt; declaration is correct,
and that the file exists on disk.
&lt;/p&gt;
&lt;p&gt;
Which happens when I try to open a Guidance Automation solution. 
&lt;/p&gt;
&lt;p&gt;
For some reason the declaration of the variable RecipeFramework in the project file
is not provided. This I deal with by editing the Project file by hand and adding a
declaration to the end of the first PropertyGroup like this: 
&lt;p&gt;
&amp;nbsp; &lt;pre class="xml" name="code"&gt;  &amp;lt;RecipeFrameworkPath&amp;gt;$(DevEnvDir)Extensions\Microsoft patterns and practices\GAX 2010\2.0.20406.0&amp;lt;/RecipeFrameworkPath&amp;gt;&lt;/pre&gt;
&lt;p&gt;
After applying this fix I can open the solution.
&lt;/p&gt;
&lt;p&gt;
I have read somewhere that it is important to adhere to the following install order:
&lt;/p&gt;
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;
Visual Studio 2010 Ultimate or Professional (obviously) 
&lt;li&gt;
The Visual Studio 2010 SDK 
&lt;li&gt;
GAX 2010 
&lt;li&gt;
GAT 2010&lt;/li&gt;
&lt;/ol&gt;
&gt;
&lt;p&gt;
And this might be what I have screwed up on the particular machine where I get the
error. 
&lt;/p&gt;
&lt;p&gt;
Anyway the above mentioned fix works. And overall I am very satisfied with the new
improvements in GAX/GAT.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=85830aad-38de-4edb-9c1c-da24a00a7fb9" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,85830aad-38de-4edb-9c1c-da24a00a7fb9.aspx</comments>
      <category>.NET</category>
      <category>GAX</category>
      <category>Tips &amp; Tricks</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=91776158-a7f1-490d-a36f-dd9def7cf9ee</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=91776158-a7f1-490d-a36f-dd9def7cf9ee</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Windows developers who are used to click events in WinForms, WPF or Silverlight might
miss click and double click events, but because of the game loop where everything
is drawn and updated every few milliseconds an event based approach is probably not
a good idea in most cases. Not so much because of the performance of an event based
approach, but more because the complexity is overwhelming. If several users clicks
and double clicks several keys on the keyboard simultaneously, how would you decide
which of these are clicked and in which order, and further more it is not obvious
to subscribers of the events that they are in the game loop, so they might do code
which performs inadequately.
</p>
        <p>
I have made a few generic classes that expands the MouseState, GamePadState and KeyboardState
in order to make click “events” available. But of course I utilize the standard polling
mechanism in XNA which is to call GetState() on each device.
</p>
        <p>
The approach is that I call my own version of GetState() in the main game loop. My
GetState() method first enqueues the state in a Queue, and then dequeues all states
older than 500 ms, before the state is returned. In this way a historical map of user
interactions is maintained at all times.
</p>
        <p>
Now I can simply check if a key or button was clicked by checking if the key was pressed
and then released “historically”. Similarly I can check for double click by checking
if the key or button was pressed, then released, then pressed again and then released
again.
</p>
        <p>
Now you probably realize why I go back 500 ms. It is because this is the standard
time in which a double click should be executed.
</p>
        <p>
I have used this approach in the game Protect the Carrot at <a href="http://ptc.codeplex.com">http://ptc.codeplex.com</a> and
it works like a charm (The url for the game does not work today, since the game will
only be published in a few weeks).
</p>
        <p>
Here is the implementation of the MouseExtended class which uses this approach:
</p>
        <pre class="c#" name="code">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Text;<br />
using Microsoft.Xna.Framework.Input;<br />
using Microsoft.Xna.Framework;<br /><br />
namespace PTC.Input<br />
{<br />
public class MouseExtended : InputDeviceExtended&lt;MouseState&gt;<br />
{<br />
private static MouseExtended m_Current;<br />
public static MouseExtended Current<br />
{<br />
get<br />
{<br />
if (m_Current == null)<br />
{<br />
m_Current = new MouseExtended();<br />
}<br />
return m_Current;<br />
}<br />
}<br /><br />
public MouseState GetState(GameTime currentTime)<br />
{<br />
DequeueOldStates(currentTime);<br />
MouseState state = Mouse.GetState();<br />
EnqueueNewState(currentTime, state);<br />
return state;<br />
}<br /><br />
private bool ClickCount(MouseButton checkButton, int requiredCount)<br />
{<br />
ButtonState found = ButtonState.Released;<br />
int count = 0;<br />
foreach (InputStateExtended&lt;MouseState&gt; stateExt in RecordedStates)<br />
{<br />
if (found == ButtonState.Pressed &amp;&amp; 
<br />
ButtonStateToCheck(stateExt.State, checkButton) == ButtonState.Released)<br />
{<br />
count++;<br />
if (count &gt;= requiredCount)<br />
return true;<br />
}<br />
found = ButtonStateToCheck(stateExt.State, checkButton);<br />
}<br />
return false;<br />
}<br /><br />
private ButtonState ButtonStateToCheck(MouseState state, MouseButton checkButton)<br />
{<br />
switch (checkButton)<br />
{<br />
case MouseButton.Left:<br />
return state.LeftButton;<br />
case MouseButton.Middle:<br />
return state.MiddleButton;<br />
case MouseButton.Right:<br />
return state.RightButton;<br />
case MouseButton.XButton1:<br />
return state.XButton1;<br />
case MouseButton.XButton2:<br />
return state.XButton2;<br />
default:<br />
return state.LeftButton;<br />
}<br />
}<br /><br />
public bool WasSingleClick(MouseButton checkButton)<br />
{<br />
return(ClickCount(checkButton, 1));<br />
}<br /><br />
public bool WasDoubleClick(MouseButton checkButton)<br />
{<br />
return (ClickCount(checkButton, 2));<br />
}<br /><br />
}<br />
}</pre>
        <p>
And here is the generic InputDeviceExtended class which MouseExtended inherits:
</p>
        <pre class="c#" name="code">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using Microsoft.Xna.Framework;<br />
using Microsoft.Xna.Framework.Audio;<br />
using Microsoft.Xna.Framework.Content;<br />
using Microsoft.Xna.Framework.GamerServices;<br />
using Microsoft.Xna.Framework.Graphics;<br />
using Microsoft.Xna.Framework.Input;<br />
using Microsoft.Xna.Framework.Media;<br />
using Microsoft.Xna.Framework.Net;<br />
using Microsoft.Xna.Framework.Storage;<br /><br />
namespace PTC.Input<br />
{<br />
public class InputDeviceExtended&lt;S&gt; where S : struct<br />
{<br />
private Queue&lt;InputStateExtended&lt;S&gt;&gt; m_RecordedStates = new Queue&lt;InputStateExtended&lt;S&gt;&gt;();<br /><br />
public Queue&lt;InputStateExtended&lt;S&gt;&gt; RecordedStates<br />
{<br />
get { return m_RecordedStates; }<br />
}<br /><br />
private Stack&lt;InputStateExtended&lt;S&gt;&gt; m_StatesForReuse = new Stack&lt;InputStateExtended&lt;S&gt;&gt;();<br /><br />
protected void EnqueueNewState(GameTime time, S state)<br />
{<br />
if (!state.Equals(m_CurrentState))<br />
{<br />
m_CurrentState = state;<br />
m_RecordedStates.Enqueue(CreateState(time, state));<br />
}<br />
}<br /><br />
private S m_CurrentState;<br />
public S CurrentState<br />
{<br />
get { return m_CurrentState; }<br />
}<br /><br />
protected void DequeueOldStates(GameTime currentTime)<br />
{<br />
InputStateExtended&lt;S&gt; state = null;<br />
if (m_RecordedStates.Count &gt; 0)<br />
{<br />
state = m_RecordedStates.Peek();<br />
}<br />
if (state != null &amp;&amp; state.StateTime &lt; currentTime.TotalRealTime.Subtract(new
TimeSpan(0, 0, 0, 0, InputDeviceConstants.ClickCountTimeMS)))<br />
{<br />
m_StatesForReuse.Push(m_RecordedStates.Dequeue());<br />
DequeueOldStates(currentTime);<br />
}<br />
}<br /><br />
private InputStateExtended&lt;S&gt; CreateState(GameTime time, S state)<br />
{<br />
if (m_StatesForReuse.Count &gt; 0)<br />
{<br />
//Reuses the object to fight of the GC<br />
InputStateExtended&lt;S&gt; stateExt = m_StatesForReuse.Pop();<br />
stateExt.StateTime = time.TotalRealTime;<br />
stateExt.State = state;<br />
return stateExt;<br />
}<br />
else<br />
{<br />
return new InputStateExtended&lt;S&gt;(time, state);<br />
}<br />
}<br />
}<br />
}</pre>
        <p>
Notice that the Recorded States are reused. When dequeued from the queue the are added
to a reuse stack. This is a standard trick to fight of the Garbage Collector, by always
keeping a reference to objects on the heap they never become garbage + they are reused
so the memory use will not explode.
</p>
        <p>
I have also implemented the necessary extended classes for the Keyboard and the gamepad.
I have included them in the attachment to this post. I have not tested the GamepadExtended
class since I do not own a Gamepad, but it is implemented exactly as the keyboard
and mouse classes and ought to work. 
</p>
        <p>
To wire up the new classes you just add the relevant Getstate() calls to the Update
game loop like so:
</p>
        <pre class="c#" name="code">protected override void Update(GameTime gameTime)<br />
{<br />
KeyboardExtended.Current.GetState(gameTime);<br />
MouseExtended.Current.GetState(gameTime);<br />
base.Update(gameTime);<br />
}</pre>
        <p>
And then you can check for click and double click “events”. For instance you check
for double click of the left mouse button like this:
</p>
        <pre class="c#" name="code">if(MouseExtended.Current.WasDoubleClick(MouseButton.Left)))<br />
{<br />
//Do double click reaction<br />
}</pre>
        <p>
Hope you like the stuff.And look out for the amazing “Protect The Carrot” game within
the next month or so, at <a href="http://ptc.codeplex.com">http://ptc.codeplex.com</a></p>
        <p>
In InputDeviceExtended.zip I have included the code for all the InputDevice classes.
</p>
        <p>
        </p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f7cf6f0f-1ed3-4885-8873-f8eaf969cb75" class="wlWriterEditableSmartContent">
          <p>
            <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ClickanddoubleclickinXNAGames_EF42/InputDeviceExtended.zip" target="_blank">InputDeviceExtended.zip</a>
          </p>
        </div>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=91776158-a7f1-490d-a36f-dd9def7cf9ee" />
      </body>
      <title>Click and double click in XNA Games</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</guid>
      <link>http://www.niedermann.dk/2010/05/12/ClickAndDoubleClickInXNAGames.aspx</link>
      <pubDate>Wed, 12 May 2010 20:38:51 GMT</pubDate>
      <description>&lt;p&gt;
Windows developers who are used to click events in WinForms, WPF or Silverlight might
miss click and double click events, but because of the game loop where everything
is drawn and updated every few milliseconds an event based approach is probably not
a good idea in most cases. Not so much because of the performance of an event based
approach, but more because the complexity is overwhelming. If several users clicks
and double clicks several keys on the keyboard simultaneously, how would you decide
which of these are clicked and in which order, and further more it is not obvious
to subscribers of the events that they are in the game loop, so they might do code
which performs inadequately.
&lt;/p&gt;
&lt;p&gt;
I have made a few generic classes that expands the MouseState, GamePadState and KeyboardState
in order to make click “events” available. But of course I utilize the standard polling
mechanism in XNA which is to call GetState() on each device.
&lt;/p&gt;
&lt;p&gt;
The approach is that I call my own version of GetState() in the main game loop. My
GetState() method first enqueues the state in a Queue, and then dequeues all states
older than 500 ms, before the state is returned. In this way a historical map of user
interactions is maintained at all times.
&lt;/p&gt;
&lt;p&gt;
Now I can simply check if a key or button was clicked by checking if the key was pressed
and then released “historically”. Similarly I can check for double click by checking
if the key or button was pressed, then released, then pressed again and then released
again.
&lt;/p&gt;
&lt;p&gt;
Now you probably realize why I go back 500 ms. It is because this is the standard
time in which a double click should be executed.
&lt;/p&gt;
&lt;p&gt;
I have used this approach in the game Protect the Carrot at &lt;a href="http://ptc.codeplex.com"&gt;http://ptc.codeplex.com&lt;/a&gt; and
it works like a charm (The url for the game does not work today, since the game will
only be published in a few weeks).
&lt;/p&gt;
&lt;p&gt;
Here is the implementation of the MouseExtended class which uses this approach:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;&lt;br&gt;
using System.Collections.Generic;&lt;br&gt;
using System.Linq;&lt;br&gt;
using System.Text;&lt;br&gt;
using Microsoft.Xna.Framework.Input;&lt;br&gt;
using Microsoft.Xna.Framework;&lt;br&gt;
&lt;br&gt;
namespace PTC.Input&lt;br&gt;
{&lt;br&gt;
public class MouseExtended : InputDeviceExtended&amp;lt;MouseState&amp;gt;&lt;br&gt;
{&lt;br&gt;
private static MouseExtended m_Current;&lt;br&gt;
public static MouseExtended Current&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
if (m_Current == null)&lt;br&gt;
{&lt;br&gt;
m_Current = new MouseExtended();&lt;br&gt;
}&lt;br&gt;
return m_Current;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public MouseState GetState(GameTime currentTime)&lt;br&gt;
{&lt;br&gt;
DequeueOldStates(currentTime);&lt;br&gt;
MouseState state = Mouse.GetState();&lt;br&gt;
EnqueueNewState(currentTime, state);&lt;br&gt;
return state;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private bool ClickCount(MouseButton checkButton, int requiredCount)&lt;br&gt;
{&lt;br&gt;
ButtonState found = ButtonState.Released;&lt;br&gt;
int count = 0;&lt;br&gt;
foreach (InputStateExtended&amp;lt;MouseState&amp;gt; stateExt in RecordedStates)&lt;br&gt;
{&lt;br&gt;
if (found == ButtonState.Pressed &amp;amp;&amp;amp; 
&lt;br&gt;
ButtonStateToCheck(stateExt.State, checkButton) == ButtonState.Released)&lt;br&gt;
{&lt;br&gt;
count++;&lt;br&gt;
if (count &amp;gt;= requiredCount)&lt;br&gt;
return true;&lt;br&gt;
}&lt;br&gt;
found = ButtonStateToCheck(stateExt.State, checkButton);&lt;br&gt;
}&lt;br&gt;
return false;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private ButtonState ButtonStateToCheck(MouseState state, MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
switch (checkButton)&lt;br&gt;
{&lt;br&gt;
case MouseButton.Left:&lt;br&gt;
return state.LeftButton;&lt;br&gt;
case MouseButton.Middle:&lt;br&gt;
return state.MiddleButton;&lt;br&gt;
case MouseButton.Right:&lt;br&gt;
return state.RightButton;&lt;br&gt;
case MouseButton.XButton1:&lt;br&gt;
return state.XButton1;&lt;br&gt;
case MouseButton.XButton2:&lt;br&gt;
return state.XButton2;&lt;br&gt;
default:&lt;br&gt;
return state.LeftButton;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public bool WasSingleClick(MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
return(ClickCount(checkButton, 1));&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public bool WasDoubleClick(MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
return (ClickCount(checkButton, 2));&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
And here is the generic InputDeviceExtended class which MouseExtended inherits:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;&lt;br&gt;
using System.Collections.Generic;&lt;br&gt;
using System.Linq;&lt;br&gt;
using Microsoft.Xna.Framework;&lt;br&gt;
using Microsoft.Xna.Framework.Audio;&lt;br&gt;
using Microsoft.Xna.Framework.Content;&lt;br&gt;
using Microsoft.Xna.Framework.GamerServices;&lt;br&gt;
using Microsoft.Xna.Framework.Graphics;&lt;br&gt;
using Microsoft.Xna.Framework.Input;&lt;br&gt;
using Microsoft.Xna.Framework.Media;&lt;br&gt;
using Microsoft.Xna.Framework.Net;&lt;br&gt;
using Microsoft.Xna.Framework.Storage;&lt;br&gt;
&lt;br&gt;
namespace PTC.Input&lt;br&gt;
{&lt;br&gt;
public class InputDeviceExtended&amp;lt;S&amp;gt; where S : struct&lt;br&gt;
{&lt;br&gt;
private Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; m_RecordedStates = new Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
public Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; RecordedStates&lt;br&gt;
{&lt;br&gt;
get { return m_RecordedStates; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private Stack&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; m_StatesForReuse = new Stack&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
protected void EnqueueNewState(GameTime time, S state)&lt;br&gt;
{&lt;br&gt;
if (!state.Equals(m_CurrentState))&lt;br&gt;
{&lt;br&gt;
m_CurrentState = state;&lt;br&gt;
m_RecordedStates.Enqueue(CreateState(time, state));&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private S m_CurrentState;&lt;br&gt;
public S CurrentState&lt;br&gt;
{&lt;br&gt;
get { return m_CurrentState; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
protected void DequeueOldStates(GameTime currentTime)&lt;br&gt;
{&lt;br&gt;
InputStateExtended&amp;lt;S&amp;gt; state = null;&lt;br&gt;
if (m_RecordedStates.Count &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
state = m_RecordedStates.Peek();&lt;br&gt;
}&lt;br&gt;
if (state != null &amp;amp;&amp;amp; state.StateTime &amp;lt; currentTime.TotalRealTime.Subtract(new
TimeSpan(0, 0, 0, 0, InputDeviceConstants.ClickCountTimeMS)))&lt;br&gt;
{&lt;br&gt;
m_StatesForReuse.Push(m_RecordedStates.Dequeue());&lt;br&gt;
DequeueOldStates(currentTime);&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private InputStateExtended&amp;lt;S&amp;gt; CreateState(GameTime time, S state)&lt;br&gt;
{&lt;br&gt;
if (m_StatesForReuse.Count &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
//Reuses the object to fight of the GC&lt;br&gt;
InputStateExtended&amp;lt;S&amp;gt; stateExt = m_StatesForReuse.Pop();&lt;br&gt;
stateExt.StateTime = time.TotalRealTime;&lt;br&gt;
stateExt.State = state;&lt;br&gt;
return stateExt;&lt;br&gt;
}&lt;br&gt;
else&lt;br&gt;
{&lt;br&gt;
return new InputStateExtended&amp;lt;S&amp;gt;(time, state);&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Notice that the Recorded States are reused. When dequeued from the queue the are added
to a reuse stack. This is a standard trick to fight of the Garbage Collector, by always
keeping a reference to objects on the heap they never become garbage + they are reused
so the memory use will not explode.
&lt;/p&gt;
&lt;p&gt;
I have also implemented the necessary extended classes for the Keyboard and the gamepad.
I have included them in the attachment to this post. I have not tested the GamepadExtended
class since I do not own a Gamepad, but it is implemented exactly as the keyboard
and mouse classes and ought to work. 
&lt;/p&gt;
&lt;p&gt;
To wire up the new classes you just add the relevant Getstate() calls to the Update
game loop like so:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;protected override void Update(GameTime gameTime)&lt;br&gt;
{&lt;br&gt;
KeyboardExtended.Current.GetState(gameTime);&lt;br&gt;
MouseExtended.Current.GetState(gameTime);&lt;br&gt;
base.Update(gameTime);&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
And then you can check for click and double click “events”. For instance you check
for double click of the left mouse button like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;if(MouseExtended.Current.WasDoubleClick(MouseButton.Left)))&lt;br&gt;
{&lt;br&gt;
//Do double click reaction&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Hope you like the stuff.And look out for the amazing “Protect The Carrot” game within
the next month or so, at &lt;a href="http://ptc.codeplex.com"&gt;http://ptc.codeplex.com&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In InputDeviceExtended.zip I have included the code for all the InputDevice classes.
&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f7cf6f0f-1ed3-4885-8873-f8eaf969cb75" class="wlWriterEditableSmartContent"&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ClickanddoubleclickinXNAGames_EF42/InputDeviceExtended.zip" target="_blank"&gt;InputDeviceExtended.zip&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=91776158-a7f1-490d-a36f-dd9def7cf9ee" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</comments>
      <category>.NET</category>
      <category>Tips &amp; Tricks</category>
      <category>XNA</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=0a44a9f8-67aa-45a8-aea4-d644321cd0f7</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,0a44a9f8-67aa-45a8-aea4-d644321cd0f7.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,0a44a9f8-67aa-45a8-aea4-d644321cd0f7.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=0a44a9f8-67aa-45a8-aea4-d644321cd0f7</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the <a href="http://www.niedermann.dk/2009/10/20/Windows7ContestFinished.aspx" target="_blank">Day
View</a> project I needed to open a Windows 7 Sticky Note programmatically and write
to it. Unfortunately I found out that there is not an API for the Sticky Notes application.
At least not a managed one.
</p>
        <p>
So I had to fake it and make my own API. I have made a small class that basicly uses
Process.Start to open the program, and SendKeys to write to the Note.
</p>
        <p>
Here it is:
</p>
        <pre class="c#" name="code">using System;<br />
using System.Diagnostics;<br />
using System.IO;<br />
using System.Runtime.InteropServices;<br />
using System.Threading;<br />
using System.Windows.Forms;<br /><br />
namespace DayView<br />
{<br />
public class StickyNote<br />
{<br />
private const string m_ProcessName = "StikyNot";<br />
private readonly string m_ProcessFileName = Path.Combine(Environment.SystemDirectory,
"StikyNot.exe");<br />
private event EventHandler m_Activated = delegate { };<br />
[DllImport("user32.dll")]<br />
[return: MarshalAs(UnmanagedType.Bool)]<br />
static extern bool SetForegroundWindow(IntPtr hWnd);<br /><br />
public void Activate()<br />
{<br />
bool makeNewNote = true;<br />
Process p = FindProcess();<br />
if (p == null)<br />
{<br />
p = StartProcess();<br />
if (!NoteContainsText(p.MainWindowHandle))<br />
{<br />
makeNewNote = false;<br />
}<br />
}<br />
var state = new StickyNoteState();<br />
state.MakeNewNote = makeNewNote;<br />
state.StickyNoteProcess = p;<br />
ThreadPool.QueueUserWorkItem(Activate, state);<br />
}<br /><br />
private void Activate(object state)<br />
{<br />
var stickyNoteState = state as StickyNoteState;<br />
if (stickyNoteState.MakeNewNote)<br />
{<br />
NewNote(stickyNoteState.StickyNoteProcess);<br />
}<br />
OnActivated();<br />
}<br /><br />
private Process StartProcess()<br />
{<br />
var startInfo = new ProcessStartInfo(m_ProcessFileName);<br />
Process p = Process.Start(startInfo);<br />
Thread.Sleep(200); //This is an annoying hack. I haven't been able to find another
way to be sure the process is started.<br />
return p;<br />
}<br /><br />
private void NewNote(Process p)<br />
{<br />
SetForegroundWindow(p.MainWindowHandle);<br />
Signal("^n"); 
<br />
}<br /><br />
/// &lt;summary&gt;<br />
/// Weird hack to find out if note contains text.<br />
/// &lt;/summary&gt;<br />
/// &lt;returns&gt;&lt;/returns&gt;<br />
private bool NoteContainsText(IntPtr handle)<br />
{<br />
string textOfClipboard = Clipboard.GetText();<br />
Signal("^a");<br />
Signal("^c");<br />
Signal("{RIGHT}");<br />
string noteText = Clipboard.GetText().Trim();<br />
if (textOfClipboard == null)<br />
{<br />
Clipboard.SetText(textOfClipboard);<br />
}<br />
return !string.IsNullOrEmpty(noteText);<br />
}<br /><br />
private Process FindProcess()<br />
{<br />
Process[] processes = Process.GetProcessesByName(m_ProcessName);<br />
if(processes != null &amp;&amp; processes.Length &gt; 0)<br />
{<br />
return processes[0];<br />
}<br />
return null;<br />
}<br /><br />
internal void OnActivated()<br />
{<br />
m_Activated(this, new EventArgs());<br />
}<br /><br />
public event EventHandler Activated<br />
{<br />
add { m_Activated += value; }<br />
remove { m_Activated -= value; }<br />
}<br /><br />
public void Signal(string message)<br />
{<br />
SendKeys.SendWait(message);<br />
SendKeys.Flush();<br />
}<br />
}<br /><br />
public class StickyNoteState<br />
{<br />
public bool MakeNewNote { get; set; }<br />
public Process StickyNoteProcess { get; set; }<br /><br />
}<br />
}</pre>
        <p>
It works OK. The only really buggy thing in the code is in line 47, where I have to
use a Thread.Sleep in order to make sure the note is loaded before I write to it.
Unfortunately this is necessary because the Process class does not provide an event
to signal when it has finished loading. I arbitrarily chose 200 milliseconds for the
Sleep. Larger values might be necessary on slower computers.
</p>
        <p>
In order to use the class you have to configure SendKeys in your app.config like this:
</p>
        <pre class="xml" name="code">&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;configuration&gt;<br />
&lt;appSettings&gt;<br />
&lt;add key="SendKeys" value="SendInput"/&gt;<br />
&lt;/appSettings&gt;<br />
&lt;/configuration&gt;</pre>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=0a44a9f8-67aa-45a8-aea4-d644321cd0f7" />
      </body>
      <title>API for Sticky Notes in Windows 7</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,0a44a9f8-67aa-45a8-aea4-d644321cd0f7.aspx</guid>
      <link>http://www.niedermann.dk/2009/11/13/APIForStickyNotesInWindows7.aspx</link>
      <pubDate>Fri, 13 Nov 2009 23:28:10 GMT</pubDate>
      <description>&lt;p&gt;
In the &lt;a href="http://www.niedermann.dk/2009/10/20/Windows7ContestFinished.aspx" target="_blank"&gt;Day
View&lt;/a&gt; project I needed to open a Windows 7 Sticky Note programmatically and write
to it. Unfortunately I found out that there is not an API for the Sticky Notes application.
At least not a managed one.
&lt;/p&gt;
&lt;p&gt;
So I had to fake it and make my own API. I have made a small class that basicly uses
Process.Start to open the program, and SendKeys to write to the Note.
&lt;/p&gt;
&lt;p&gt;
Here it is:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;&lt;br&gt;
using System.Diagnostics;&lt;br&gt;
using System.IO;&lt;br&gt;
using System.Runtime.InteropServices;&lt;br&gt;
using System.Threading;&lt;br&gt;
using System.Windows.Forms;&lt;br&gt;
&lt;br&gt;
namespace DayView&lt;br&gt;
{&lt;br&gt;
public class StickyNote&lt;br&gt;
{&lt;br&gt;
private const string m_ProcessName = "StikyNot";&lt;br&gt;
private readonly string m_ProcessFileName = Path.Combine(Environment.SystemDirectory,
"StikyNot.exe");&lt;br&gt;
private event EventHandler m_Activated = delegate { };&lt;br&gt;
[DllImport("user32.dll")]&lt;br&gt;
[return: MarshalAs(UnmanagedType.Bool)]&lt;br&gt;
static extern bool SetForegroundWindow(IntPtr hWnd);&lt;br&gt;
&lt;br&gt;
public void Activate()&lt;br&gt;
{&lt;br&gt;
bool makeNewNote = true;&lt;br&gt;
Process p = FindProcess();&lt;br&gt;
if (p == null)&lt;br&gt;
{&lt;br&gt;
p = StartProcess();&lt;br&gt;
if (!NoteContainsText(p.MainWindowHandle))&lt;br&gt;
{&lt;br&gt;
makeNewNote = false;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
var state = new StickyNoteState();&lt;br&gt;
state.MakeNewNote = makeNewNote;&lt;br&gt;
state.StickyNoteProcess = p;&lt;br&gt;
ThreadPool.QueueUserWorkItem(Activate, state);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void Activate(object state)&lt;br&gt;
{&lt;br&gt;
var stickyNoteState = state as StickyNoteState;&lt;br&gt;
if (stickyNoteState.MakeNewNote)&lt;br&gt;
{&lt;br&gt;
NewNote(stickyNoteState.StickyNoteProcess);&lt;br&gt;
}&lt;br&gt;
OnActivated();&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private Process StartProcess()&lt;br&gt;
{&lt;br&gt;
var startInfo = new ProcessStartInfo(m_ProcessFileName);&lt;br&gt;
Process p = Process.Start(startInfo);&lt;br&gt;
Thread.Sleep(200); //This is an annoying hack. I haven't been able to find another
way to be sure the process is started.&lt;br&gt;
return p;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private void NewNote(Process p)&lt;br&gt;
{&lt;br&gt;
SetForegroundWindow(p.MainWindowHandle);&lt;br&gt;
Signal("^n"); 
&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
/// &amp;lt;summary&amp;gt;&lt;br&gt;
/// Weird hack to find out if note contains text.&lt;br&gt;
/// &amp;lt;/summary&amp;gt;&lt;br&gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br&gt;
private bool NoteContainsText(IntPtr handle)&lt;br&gt;
{&lt;br&gt;
string textOfClipboard = Clipboard.GetText();&lt;br&gt;
Signal("^a");&lt;br&gt;
Signal("^c");&lt;br&gt;
Signal("{RIGHT}");&lt;br&gt;
string noteText = Clipboard.GetText().Trim();&lt;br&gt;
if (textOfClipboard == null)&lt;br&gt;
{&lt;br&gt;
Clipboard.SetText(textOfClipboard);&lt;br&gt;
}&lt;br&gt;
return !string.IsNullOrEmpty(noteText);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private Process FindProcess()&lt;br&gt;
{&lt;br&gt;
Process[] processes = Process.GetProcessesByName(m_ProcessName);&lt;br&gt;
if(processes != null &amp;amp;&amp;amp; processes.Length &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
return processes[0];&lt;br&gt;
}&lt;br&gt;
return null;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
internal void OnActivated()&lt;br&gt;
{&lt;br&gt;
m_Activated(this, new EventArgs());&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public event EventHandler Activated&lt;br&gt;
{&lt;br&gt;
add { m_Activated += value; }&lt;br&gt;
remove { m_Activated -= value; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public void Signal(string message)&lt;br&gt;
{&lt;br&gt;
SendKeys.SendWait(message);&lt;br&gt;
SendKeys.Flush();&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public class StickyNoteState&lt;br&gt;
{&lt;br&gt;
public bool MakeNewNote { get; set; }&lt;br&gt;
public Process StickyNoteProcess { get; set; }&lt;br&gt;
&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
It works OK. The only really buggy thing in the code is in line 47, where I have to
use a Thread.Sleep in order to make sure the note is loaded before I write to it.
Unfortunately this is necessary because the Process class does not provide an event
to signal when it has finished loading. I arbitrarily chose 200 milliseconds for the
Sleep. Larger values might be necessary on slower computers.
&lt;/p&gt;
&lt;p&gt;
In order to use the class you have to configure SendKeys in your app.config like this:
&lt;/p&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;br&gt;
&amp;lt;configuration&amp;gt;&lt;br&gt;
&amp;lt;appSettings&amp;gt;&lt;br&gt;
&amp;lt;add key="SendKeys" value="SendInput"/&amp;gt;&lt;br&gt;
&amp;lt;/appSettings&amp;gt;&lt;br&gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=0a44a9f8-67aa-45a8-aea4-d644321cd0f7" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,0a44a9f8-67aa-45a8-aea4-d644321cd0f7.aspx</comments>
      <category>.NET</category>
      <category>Tips &amp; Tricks</category>
      <category>Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=10be7325-8b71-41a0-ba08-658b3a16b70e</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,10be7325-8b71-41a0-ba08-658b3a16b70e.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,10be7325-8b71-41a0-ba08-658b3a16b70e.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=10be7325-8b71-41a0-ba08-658b3a16b70e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was using my codeplex project <a href="http://managedmenuextension.codeplex.com/" target="_blank">ManagedMenuExtensions</a> recently
when I realized that it threw an Exception, when clicking on a menu attached to a
C# project under a solution folder. The reason was that the object which normally
contained an EnvDTE.Project when a project was clicked contained null, when this project
was contained in a solution folder.
</p>
        <p>
I normally use this code to get at the selected project (m_VSStudio is the DTE object
of the current solution):
</p>
        <pre class="c#" name="code">private UIHierarchyItem SelectedItem<br />
{<br />
get<br />
{<br />
UIHierarchy uiHierarchy = m_VSStudio.ToolWindows.SolutionExplorer;<br />
if(uiHierarchy == null)<br />
return null;<br /><br />
object[] items = uiHierarchy.SelectedItems as object[];<br />
if(items == null || items.Length == 0)<br />
return null;<br /><br />
return items[0] as UIHierarchyItem;<br />
}<br />
}</pre>
        <p>
The SelectedItem.Object of type object now contains a EnvDTE.Solution object if the
solution is selected in the solution explorer, and guess what :O) it contains an EnvDTE.Project
if a project is selected. It is this SelectedItem.Object that contains null, if the
project is contained in a solution folder.
</p>
        <p>
I googled this problem and found others who had the same problem, but none with a
solution, so I had to come up with my own. I don't know if this behaviour is by design
from Microsoft, or if it is a bug.
</p>
        <h3>My Solution
</h3>
        <p>
Normally I would test if a project is selected with this code:
</p>
        <pre class="c#" name="code">var project = SelectedItem.Object as Project;<br />
if (project != null)<br />
{<br />
//Do something with the project<br />
}</pre>
        <p>
Now I use this code instead:
</p>
        <pre class="c#" name="code">Project project = GetProject(SelectedItem.Object);<br />
if (project != null)<br />
{<br />
//Do something with the project<br />
}</pre>
        <p>
Where I implemented GetProject(...) as:
</p>
        <pre class="c#" name="code">private Project GetProject(object selectedItemObject)<br />
{<br />
var project = selectedItemObject as Project;<br />
if (project != null)<br />
return project; 
<br /><br />
var item = selectedItemObject as ProjectItem;<br />
if (item == null)<br />
return null; 
<br /><br />
return item.SubProject;<br />
}</pre>
        <p>
Not exactly beautiful, but that is to be expected when playing with Visual Studios
AddIn model, and the kind of thing I try to hide in <a href="http://managedmenuextension.codeplex.com/" target="_blank">ManagedMenuExtensions</a>.
I haven't had a chance to look at Visual Studio 2010 yet, one could hope that they
have done a better job of hiding the ugly underlying COM stuff. 
</p>
        <p>
  
</p>
        <p>
Anyway, I hope this helps the next person who tries to search for a workaround for
this rather weird behaviour.
</p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=10be7325-8b71-41a0-ba08-658b3a16b70e" />
      </body>
      <title>How to get EnvDTE.Project information when the project is contained in a Solution Folder in Visual Studio</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,10be7325-8b71-41a0-ba08-658b3a16b70e.aspx</guid>
      <link>http://www.niedermann.dk/2009/06/14/HowToGetEnvDTEProjectInformationWhenTheProjectIsContainedInASolutionFolderInVisualStudio.aspx</link>
      <pubDate>Sun, 14 Jun 2009 17:33:04 GMT</pubDate>
      <description>&lt;p&gt;
I was using my codeplex project &lt;a href="http://managedmenuextension.codeplex.com/" target="_blank"&gt;ManagedMenuExtensions&lt;/a&gt; recently
when I realized that it threw an Exception, when clicking on a menu attached to a
C# project under a solution folder. The reason was that the object which normally
contained an EnvDTE.Project when a project was clicked contained null, when this project
was contained in a solution folder.
&lt;/p&gt;
&lt;p&gt;
I normally use this code to get at the selected project (m_VSStudio is the DTE object
of the current solution):
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private UIHierarchyItem SelectedItem&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
UIHierarchy uiHierarchy = m_VSStudio.ToolWindows.SolutionExplorer;&lt;br&gt;
if(uiHierarchy == null)&lt;br&gt;
return null;&lt;br&gt;
&lt;br&gt;
object[] items = uiHierarchy.SelectedItems as object[];&lt;br&gt;
if(items == null || items.Length == 0)&lt;br&gt;
return null;&lt;br&gt;
&lt;br&gt;
return items[0] as UIHierarchyItem;&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
The SelectedItem.Object of type object now contains a EnvDTE.Solution object if the
solution is selected in the solution explorer, and guess what :O) it contains an EnvDTE.Project
if a project is selected. It is this SelectedItem.Object that contains null, if the
project is contained in a solution folder.
&lt;/p&gt;
&lt;p&gt;
I googled this problem and found others who had the same problem, but none with a
solution, so I had to come up with my own. I don't know if this behaviour is by design
from Microsoft, or if it is a bug.
&lt;/p&gt;
&lt;h3&gt;My Solution
&lt;/h3&gt;
&lt;p&gt;
Normally I would test if a project is selected with this code:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;var project = SelectedItem.Object as Project;&lt;br&gt;
if (project != null)&lt;br&gt;
{&lt;br&gt;
//Do something with the project&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Now I use this code instead:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;Project project = GetProject(SelectedItem.Object);&lt;br&gt;
if (project != null)&lt;br&gt;
{&lt;br&gt;
//Do something with the project&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Where I implemented GetProject(...) as:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;private Project GetProject(object selectedItemObject)&lt;br&gt;
{&lt;br&gt;
var project = selectedItemObject as Project;&lt;br&gt;
if (project != null)&lt;br&gt;
return project; 
&lt;br&gt;
&lt;br&gt;
var item = selectedItemObject as ProjectItem;&lt;br&gt;
if (item == null)&lt;br&gt;
return null; 
&lt;br&gt;
&lt;br&gt;
return item.SubProject;&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Not exactly beautiful, but that is to be expected when playing with Visual Studios
AddIn model, and the kind of thing I try to hide in &lt;a href="http://managedmenuextension.codeplex.com/" target="_blank"&gt;ManagedMenuExtensions&lt;/a&gt;.
I haven't had a chance to look at Visual Studio 2010 yet, one could hope that they
have done a better job of hiding the ugly underlying COM stuff. 
&lt;p&gt;
&amp;nbsp; 
&lt;p&gt;
Anyway, I hope this helps the next person who tries to search for a workaround for
this rather weird behaviour.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=10be7325-8b71-41a0-ba08-658b3a16b70e" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,10be7325-8b71-41a0-ba08-658b3a16b70e.aspx</comments>
      <category>.NET</category>
      <category>Tips &amp; Tricks</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=1fff8b9b-614c-4c56-9d0f-89355aa80997</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,1fff8b9b-614c-4c56-9d0f-89355aa80997.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,1fff8b9b-614c-4c56-9d0f-89355aa80997.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=1fff8b9b-614c-4c56-9d0f-89355aa80997</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
My favourite RSS reader is <a href="http://www.curiostudio.com/">GreatNews</a>. First
of all it is a standalone application, and secondly it is portable, which means I
can install it on a USB key or better yet in my <a href="http://www.getdropbox.com/">Dropbox</a> which
is what I do. 
</p>
        <p>
Well to be fair it is not portable in the purist way because it caches some stuff
on the computers harddrive, but that is only for performance, so functionally <a href="http://www.curiostudio.com/">GreatNews</a> IS
portable.
</p>
        <p>
And <a href="http://www.curiostudio.com/">GreatNews</a> is very fast, which is just
one more reason to love it.
</p>
        <p>
In fact it has only one drawback, the database tends to get corrupt every 2-3 months,
and there is no obvious way to repair it. I guess it will be corrected at some point
in time (?) but for now it nearly made me give up on this otherwise great product.
</p>
        <p>
After some googling I found that <a href="http://www.curiostudio.com/">GreatNews</a> uses
an sqlite database called newsfeed.db. I couldn't really find a repair tool for it,
even though I found a page which lots of <a href="http://www.sqlite.org/cvstrac/wiki?p=ManagementTools">tools
for sqlite</a>.
</p>
        <p>
So I had to repair it in a more indirect way.
</p>
        <p>
I downloaded one called <a href="http://sqliteman.com/">sqliteman</a> and with this
I was able to make a new database called newsfeed.db and export all content from the
old database and import it to the new one.
</p>
        <p>
One nice sideeffect was that the database was only 1/10 in size after the import.
Apparently either <a href="http://www.curiostudio.com/">GreatNews</a> or Sqllite tends
to bloat the database. 
</p>
        <p>
After the import I replaced the old database with the new one (you should make a backup
of course !), and viola it worked perfectly. So once more I am a happy user of <a href="http://www.curiostudio.com/">GreatNews</a> :O).
</p>
        <p>
I cannot guarantee that this method will work for you too, perhaps I was just lucky.
I advice you to keep your backup of the old newsfeed.db just in case.
</p>
        <p>
P.S: To export the database you just choose "Dump database..." as shown below in a
screenshot from <a href="http://sqliteman.com/">sqliteman</a>, which generates an
SQL script that can be opened and run in the new database:
</p>
        <p>
          <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/HowtorepairGreatnewsdatabase_14EF1/newsfeed1.jpg">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="198" alt="newsfeed1" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/HowtorepairGreatnewsdatabase_14EF1/newsfeed1_thumb.jpg" width="244" border="0" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=1fff8b9b-614c-4c56-9d0f-89355aa80997" />
      </body>
      <title>How to repair GreatNews database</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,1fff8b9b-614c-4c56-9d0f-89355aa80997.aspx</guid>
      <link>http://www.niedermann.dk/2009/05/06/HowToRepairGreatNewsDatabase.aspx</link>
      <pubDate>Wed, 06 May 2009 20:34:53 GMT</pubDate>
      <description>&lt;p&gt;
My favourite RSS reader is &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt;. First
of all it is a standalone application, and secondly it is portable, which means I
can install it on a USB key or better yet in my &lt;a href="http://www.getdropbox.com/"&gt;Dropbox&lt;/a&gt; which
is what I do. 
&lt;/p&gt;
&lt;p&gt;
Well to be fair it is not portable in the purist way because it caches some stuff
on the computers harddrive, but that is only for performance, so functionally &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt; IS
portable.
&lt;/p&gt;
&lt;p&gt;
And &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt; is very fast, which is just
one more reason to love it.
&lt;/p&gt;
&lt;p&gt;
In fact it has only one drawback, the database tends to get corrupt every 2-3 months,
and there is no obvious way to repair it. I guess it will be corrected at some point
in time (?) but for now it nearly made me give up on this otherwise great product.
&lt;/p&gt;
&lt;p&gt;
After some googling I found that &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt; uses
an sqlite database called newsfeed.db. I couldn't really find a repair tool for it,
even though I found a page which lots of &lt;a href="http://www.sqlite.org/cvstrac/wiki?p=ManagementTools"&gt;tools
for sqlite&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So I had to repair it in a more indirect way.
&lt;/p&gt;
&lt;p&gt;
I downloaded one called &lt;a href="http://sqliteman.com/"&gt;sqliteman&lt;/a&gt; and with this
I was able to make a new database called newsfeed.db and export all content from the
old database and import it to the new one.
&lt;/p&gt;
&lt;p&gt;
One nice sideeffect was that the database was only 1/10 in size after the import.
Apparently either &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt; or Sqllite tends
to bloat the database. 
&lt;/p&gt;
&lt;p&gt;
After the import I replaced the old database with the new one (you should make a backup
of course !), and viola it worked perfectly. So once more I am a happy user of &lt;a href="http://www.curiostudio.com/"&gt;GreatNews&lt;/a&gt; :O).
&lt;/p&gt;
&lt;p&gt;
I cannot guarantee that this method will work for you too, perhaps I was just lucky.
I advice you to keep your backup of the old newsfeed.db just in case.
&lt;/p&gt;
&lt;p&gt;
P.S: To export the database you just choose "Dump database..." as shown below in a
screenshot from &lt;a href="http://sqliteman.com/"&gt;sqliteman&lt;/a&gt;, which generates an
SQL script that can be opened and run in the new database:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/HowtorepairGreatnewsdatabase_14EF1/newsfeed1.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="198" alt="newsfeed1" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/HowtorepairGreatnewsdatabase_14EF1/newsfeed1_thumb.jpg" width="244" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=1fff8b9b-614c-4c56-9d0f-89355aa80997" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,1fff8b9b-614c-4c56-9d0f-89355aa80997.aspx</comments>
      <category>Tips &amp; Tricks</category>
      <category>Tools</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=ca551b37-7872-4ea6-9db9-f3c400cc3854</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,ca551b37-7872-4ea6-9db9-f3c400cc3854.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,ca551b37-7872-4ea6-9db9-f3c400cc3854.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=ca551b37-7872-4ea6-9db9-f3c400cc3854</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you want to Execute something on each element of the result of a Linq expression.
You can either loop over the result using foreach(...) or turn the result into a List
using .ToList(), and then use .Foreach(...) on the resulting list. Like this:
</p>
        <pre class="c#" name="code">(from excep in ErrorList<br />
where excep is ArgumentException select excep)<br />
.ToList().ForEach(e =&gt; Console.WriteLine(e.Message));</pre>
        <p>
This is ugly, and I prefer to make my own Extension method for IEnumerable&lt;T&gt;
called Execute(...):
</p>
        <pre class="c#" name="code">public static void Execute&lt;T&gt;(this IEnumerable&lt;T&gt; list, Action&lt;T&gt; action)<br />
{<br />
foreach(T element in list)<br />
{<br />
action(element);<br />
}<br />
}</pre>
        <p>
This means you can do this instead:
</p>
        <pre class="c#" name="code">(from excep in ErrorList<br />
where excep is ArgumentException select excep)<br />
.Execute(e =&gt; Console.WriteLine(e.Message));</pre>
        <p>
Back in the days when I used Linq in a program for the first time, I wondered why
there was no way to execute an action on each element of a list, so I implemented
the Execute method. 
</p>
        <p>
It was only later that I discovered that the default way was .ToList().Foreach(...) 
</p>
        <p>
I must say I still prefer my original approach.
</p>
        <p>
BTW: In a small none scientific test I have tested the two approaches. 
</p>
        <p>
With Linq To Objects iterating over 100000 integers and printing them to the Console
takes about 21 seconds with the Foreach method and about 20 seconds with the Execute
method, so it is even faster at least for this particular example. Though nothing
to get excited about. :O) 
</p>
        <p>
The test was done in a Vista VPC with VS2008, 
</p>
        <div class="wlWriterSmartContent" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:11f4e80d-be65-4afd-81f7-669eb0b45764" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <p>
Small performance test: <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ExecuteMethodforLinq_1420F/LinqPerfTest.zip" target="_blank">LinqPerfTest.zip</a></p>
        </div>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=ca551b37-7872-4ea6-9db9-f3c400cc3854" />
      </body>
      <title>Execute Method for Linq</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,ca551b37-7872-4ea6-9db9-f3c400cc3854.aspx</guid>
      <link>http://www.niedermann.dk/2009/05/01/ExecuteMethodForLinq.aspx</link>
      <pubDate>Fri, 01 May 2009 20:12:40 GMT</pubDate>
      <description>&lt;p&gt;
If you want to Execute something on each element of the result of a Linq expression.
You can either loop over the result using foreach(...) or turn the result into a List
using .ToList(), and then use .Foreach(...) on the resulting list. Like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;(from excep in ErrorList&lt;br&gt;
where excep is ArgumentException select excep)&lt;br&gt;
.ToList().ForEach(e =&amp;gt; Console.WriteLine(e.Message));&lt;/pre&gt;
&lt;p&gt;
This is ugly, and I prefer to make my own Extension method for IEnumerable&amp;lt;T&amp;gt;
called Execute(...):
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;public static void Execute&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Action&amp;lt;T&amp;gt; action)&lt;br&gt;
{&lt;br&gt;
foreach(T element in list)&lt;br&gt;
{&lt;br&gt;
action(element);&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
This means you can do this instead:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;(from excep in ErrorList&lt;br&gt;
where excep is ArgumentException select excep)&lt;br&gt;
.Execute(e =&amp;gt; Console.WriteLine(e.Message));&lt;/pre&gt;
&lt;p&gt;
Back in the days when I used Linq in a program for the first time, I wondered why
there was no way to execute an action on each element of a list, so I implemented
the Execute method. 
&lt;/p&gt;
&lt;p&gt;
It was only later that I discovered that the default way was .ToList().Foreach(...) 
&lt;/p&gt;
&lt;p&gt;
I must say I still prefer my original approach.
&lt;/p&gt;
&lt;p&gt;
BTW: In a small none scientific test I have tested the two approaches. 
&lt;/p&gt;
&lt;p&gt;
With Linq To Objects iterating over 100000 integers and printing them to the Console
takes about 21 seconds with the Foreach method and about 20 seconds with the Execute
method, so it is even faster at least for this particular example. Though nothing
to get excited about. :O) 
&lt;/p&gt;
&lt;p&gt;
The test was done in a Vista VPC with VS2008, 
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:11f4e80d-be65-4afd-81f7-669eb0b45764" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
&lt;p&gt;
Small performance test: &lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ExecuteMethodforLinq_1420F/LinqPerfTest.zip" target="_blank"&gt;LinqPerfTest.zip&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=ca551b37-7872-4ea6-9db9-f3c400cc3854" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,ca551b37-7872-4ea6-9db9-f3c400cc3854.aspx</comments>
      <category>.NET</category>
      <category>Linq</category>
      <category>Tips &amp; Tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=39a1f913-6d3b-4334-8352-7f122c2134b2</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,39a1f913-6d3b-4334-8352-7f122c2134b2.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,39a1f913-6d3b-4334-8352-7f122c2134b2.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=39a1f913-6d3b-4334-8352-7f122c2134b2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Any windows user is familiar with Windows Explorer but were you aware that one can
access an ftp site or WebDAV enabled site using the Windows Explorer ? I myself haven't
really been looking in to this, since I have been using Filezilla to upload files
to my website, but why not use Windows Explorer ? It is always at hand with the Windows+E
keystroke.
</p>
        <p>
As an example I will show you have to access the <a href="http://live.sysinternals.com">http://live.sysinternals.com</a> site
via the Windows Explorer since it is a WebDAV enabled site with anonymous access.
The site contains all the famous tools from Sysinternals a company which was purchased
by Microsoft.
</p>
        <p>
In order to connect you just have to click on the good old "Map Network Drive ..."
</p>
        <p>
          <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp1.jpg">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="63" alt="Temp1" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp1_thumb.jpg" width="202" border="0" />
          </a>
        </p>
        <p>
Since I know the name of the subdirectory 'tools', the easiest way seems to be to
map to a drive letter directly by typing the name <a href="file://\\live.sysinternals.com\tools">\\live.sysinternals.com\tools</a> in
the folder textbox:
</p>
        <p>
          <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp2.jpg">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="Temp2" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp2_thumb.jpg" width="244" border="0" />
          </a>
        </p>
        <p>
If you are trying to connect to an ftp server the right way seems to be to click on
"sign up for online storage..." After pressing "Next" twice you get this screen:
</p>
        <p>
          <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp3.jpg">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="203" alt="Temp3" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp3_thumb.jpg" width="244" border="0" />
          </a>
        </p>
        <p>
Here you can write the name of the ftp server or website if using WebDAV, so here
I could have written 'http://live.sysinternals.com'. The next screen makes you enter
username/password or Anonymous access. Pretty self explanatory. 
</p>
        <p>
The end result is that the site appears under 'My Network Places.'
</p>
        <h2>
        </h2>
        <h2>
        </h2>
        <p>
After adding the sysinternals site to your explorer you get all the usual advantages,
easy copying and pasting etc.
</p>
        <p>
BTW there are still reasons for using a "proper" ftp client like Filezilla, e.g. you
can specify an alternative port number, which doesn't seem to be an option in the
Windows Explorer.
</p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=39a1f913-6d3b-4334-8352-7f122c2134b2" />
      </body>
      <title>Windows Explorer, WebDav and Sysinternals</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,39a1f913-6d3b-4334-8352-7f122c2134b2.aspx</guid>
      <link>http://www.niedermann.dk/2009/03/13/WindowsExplorerWebDavAndSysinternals.aspx</link>
      <pubDate>Fri, 13 Mar 2009 20:58:42 GMT</pubDate>
      <description>&lt;p&gt;
Any windows user is familiar with Windows Explorer but were you aware that one can
access an ftp site or WebDAV enabled site using the Windows Explorer ? I myself haven't
really been looking in to this, since I have been using Filezilla to upload files
to my website, but why not use Windows Explorer ? It is always at hand with the Windows+E
keystroke.
&lt;/p&gt;
&lt;p&gt;
As an example I will show you have to access the &lt;a href="http://live.sysinternals.com"&gt;http://live.sysinternals.com&lt;/a&gt; site
via the Windows Explorer since it is a WebDAV enabled site with anonymous access.
The site contains all the famous tools from Sysinternals a company which was purchased
by Microsoft.
&lt;/p&gt;
&lt;p&gt;
In order to connect you just have to click on the good old "Map Network Drive ..."
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp1.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="63" alt="Temp1" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp1_thumb.jpg" width="202" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Since I know the name of the subdirectory 'tools', the easiest way seems to be to
map to a drive letter directly by typing the name &lt;a href="file://\\live.sysinternals.com\tools"&gt;\\live.sysinternals.com\tools&lt;/a&gt; in
the folder textbox:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="Temp2" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp2_thumb.jpg" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
If you are trying to connect to an ftp server the right way seems to be to click on
"sign up for online storage..." After pressing "Next" twice you get this screen:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp3.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="203" alt="Temp3" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/WindowsExplorerWebDavandSysinternals_13322/Temp3_thumb.jpg" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here you can write the name of the ftp server or website if using WebDAV, so here
I could have written 'http://live.sysinternals.com'. The next screen makes you enter
username/password or Anonymous access. Pretty self explanatory. 
&lt;/p&gt;
&lt;p&gt;
The end result is that the site appears under 'My Network Places.'
&lt;/p&gt;
&lt;h2&gt;
&lt;/h2&gt;
&lt;h2&gt;
&lt;/h2&gt;
&lt;p&gt;
After adding the sysinternals site to your explorer you get all the usual advantages,
easy copying and pasting etc.
&lt;/p&gt;
&lt;p&gt;
BTW there are still reasons for using a "proper" ftp client like Filezilla, e.g. you
can specify an alternative port number, which doesn't seem to be an option in the
Windows Explorer.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=39a1f913-6d3b-4334-8352-7f122c2134b2" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,39a1f913-6d3b-4334-8352-7f122c2134b2.aspx</comments>
      <category>Tips &amp; Tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=4dccf03c-058c-48c4-b534-8857a2cb09c2</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,4dccf03c-058c-48c4-b534-8857a2cb09c2.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,4dccf03c-058c-48c4-b534-8857a2cb09c2.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=4dccf03c-058c-48c4-b534-8857a2cb09c2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Currently I am looking into taking over a huge enterprise legacy system written mostly
in C#, but also some C++. The numbers are staggering several million lines of code,
1200 GUI screen, mostly WinForms, about 750 C# projects, 150 solution files, just
to mention a few. In all about 4 times larger than the largest enterprise system I
have previously been working on.
</p>
        <p>
Just building and deploying the system is a pretty big task since due to events beyond
my control I basicly only have the sourcecode and nothing else. Not quite true because
there are some documentation, but buried in the thousands of files.
</p>
        <p>
When I managed to modify a build file and build the entire monster with it, it took
2½ hours to complete.
</p>
        <p>
I won't even try to include all projects in a single Visual Studio file. I wonder
if it would load ? This gives me a problem though. How about debugging ? I cannot
press F5 for any of the visual studio projects because the build process using the
build file set up a ton of config files with IP adresses, connection strings and the
like. So it doesn't make sense to run the thing from Visual Studio.
</p>
        <p>
But if I start up the exe assembly how do I attach a debugger ? Well, I decided to
use a simple trick. I added a line of code in the top of the main() method:
</p>
        <pre class="c#" name="code">static void Main(string[] args) 
<br />
{<br />
Debugger.Break();<br />
...</pre>
        <p>
Debugger.Break() is basicly a programmatic breakpoint, but it is more than that. If
no debugger is attached it asks the user for a debugger. Smart! And for the process
to debug I can just choose the Visual Studio process with the project containing the
exe assembly. Henceforth the control is mine.
</p>
        <p>
I could even consider writing this method and using it instead:
</p>
        <pre class="c#" name="code">[Conditional("DEBUG")]<br />
private static void DebuggerBreak()<br />
{<br />
if(!Debugger.IsAttached)<br />
Debugger.Break();<br />
}</pre>
        <p>
This gives me the advantage that the IL code is only build in DEBUG mode and that
the Debugger is only attached if one is not attached already.
</p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=4dccf03c-058c-48c4-b534-8857a2cb09c2" />
      </body>
      <title>Debugging huge legacy systems</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,4dccf03c-058c-48c4-b534-8857a2cb09c2.aspx</guid>
      <link>http://www.niedermann.dk/2009/03/11/DebuggingHugeLegacySystems.aspx</link>
      <pubDate>Wed, 11 Mar 2009 06:23:39 GMT</pubDate>
      <description>&lt;p&gt;
Currently I am looking into taking over a huge enterprise legacy system written mostly
in C#, but also some C++. The numbers are staggering several million lines of code,
1200 GUI screen, mostly WinForms, about 750 C# projects, 150 solution files, just
to mention a few. In all about 4 times larger than the largest enterprise system I
have previously been working on.
&lt;/p&gt;
&lt;p&gt;
Just building and deploying the system is a pretty big task since due to events beyond
my control I basicly only have the sourcecode and nothing else. Not quite true because
there are some documentation, but buried in the thousands of files.
&lt;/p&gt;
&lt;p&gt;
When I managed to modify a build file and build the entire monster with it, it took
2½ hours to complete.
&lt;/p&gt;
&lt;p&gt;
I won't even try to include all projects in a single Visual Studio file. I wonder
if it would load ? This gives me a problem though. How about debugging ? I cannot
press F5 for any of the visual studio projects because the build process using the
build file set up a ton of config files with IP adresses, connection strings and the
like. So it doesn't make sense to run the thing from Visual Studio.
&lt;/p&gt;
&lt;p&gt;
But if I start up the exe assembly how do I attach a debugger ? Well, I decided to
use a simple trick. I added a line of code in the top of the main() method:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;static void Main(string[] args) 
&lt;br&gt;
{&lt;br&gt;
Debugger.Break();&lt;br&gt;
...&lt;/pre&gt;
&lt;p&gt;
Debugger.Break() is basicly a programmatic breakpoint, but it is more than that. If
no debugger is attached it asks the user for a debugger. Smart! And for the process
to debug I can just choose the Visual Studio process with the project containing the
exe assembly. Henceforth the control is mine.
&lt;/p&gt;
&lt;p&gt;
I could even consider writing this method and using it instead:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;[Conditional("DEBUG")]&lt;br&gt;
private static void DebuggerBreak()&lt;br&gt;
{&lt;br&gt;
if(!Debugger.IsAttached)&lt;br&gt;
Debugger.Break();&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
This gives me the advantage that the IL code is only build in DEBUG mode and that
the Debugger is only attached if one is not attached already.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=4dccf03c-058c-48c4-b534-8857a2cb09c2" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,4dccf03c-058c-48c4-b534-8857a2cb09c2.aspx</comments>
      <category>.NET</category>
      <category>Tips &amp; Tricks</category>
    </item>
  </channel>
</rss>