<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>A code monkey in Research</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/gsmyth/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/gsmyth/feed.xml</link>
    <description>One developer&amp;#039;s view of (a little bit of) Microsoft Research, Cambridge</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:10:17 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>More easy IPC</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/more-easy-ipc</link>
      <pubDate>Mon, 07 Apr 2014 00:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2014/04/07/more-easy-ipc/</guid>
      <description><![CDATA[Last time I talked about .NET Remoting and concluded that it was very nice for .NET to .NET...]]></description>
      <content:encoded><![CDATA[<p>Last time I talked about .NET Remoting and concluded that it was very nice for .NET to .NET communication, but not much&nbsp;use for anything else - and it's deprecated too. How's a lazy programmer like me meant to get other sorts of applications talking to each other with minimal effort? I still think that WCF is far too heavyweight for most things I want to do, and raw sockets are far too fiddly (but necessary if performance requires that level of control), so what else lives in the space in between?</p>
<p><a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx">HttpListener</a> is a pretty cool class hiding in the depths of the .NET Framework: as the name suggests, it provides an HTTP listener (the core of a mini web server) and can decode web requests sent to it. There's nothing special about these web requests - they can come from any application you want and, in fact, a web browser or the <a title="GnuWin32 page" href="http://gnuwin32.sourceforge.net/packages/wget.htm">wget</a> utility are quite useful when testing an application hosting this sort of service. And did I mention that it's very easy to use.</p>
<p>Here's how to create one and start listening:</p>
<pre><span>this</span>.listener&nbsp;=&nbsp;<span>new</span>&nbsp;<span>HttpListener</span>();
<span>this</span>.listener.Prefixes.Add(<span>string</span>.Format(<span>"http://localhost:17765/"</span>));
<span>this</span>.listener.Start();
<span>this</span>.listener.BeginGetContext(ListenerCallback,&nbsp;<span>null</span>);
</pre>
<p>The "prefixes" are what addresses the listener pays attention to - the significant thing here is the port number, and just pick something that doesn't collide with other services. (Since I do in fact&nbsp;have IIS on my development PC, I want to avoid port 80.) The last line above starts the listener waiting for and processing an incoming request, the completion of which will occur in the ListenerCallback method. Note that this isn't registering a handler for any incoming message, but initiating processing of a single received message, <em>i.e.</em>, you have to keep calling this to keep receiving messages.</p>
<p>Before talking about the callback, here's how to shut the thing down when you're done with it:</p>
<pre><span>this</span>.listener.Stop();
<span>this</span>.listener.Close();
</pre>
<p>The callback function is where everything happens, in this case, a trivial bit of code that reacts to /key?k=&lt;something&gt; requests (the beginning of a key injection application, if you must know):</p>
<pre><span>private</span>&nbsp;<span>void</span>&nbsp;ListenerCallback(<span>IAsyncResult</span>&nbsp;result)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(!<span>this</span>.listener.IsListening)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return</span>;
 
&nbsp;&nbsp;&nbsp;&nbsp;<span>try</span>
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;context&nbsp;=&nbsp;<span>this</span>.listener.EndGetContext(result);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;request&nbsp;=&nbsp;context.Request;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>HttpStatusCode</span>&nbsp;responseCode;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(!request.IsLocal)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseCode&nbsp;=&nbsp;<span>HttpStatusCode</span>.Forbidden;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>else</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>switch</span>&nbsp;(request.Url.AbsolutePath)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>case</span>&nbsp;<span>"/key"</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>var</span>&nbsp;key&nbsp;=&nbsp;request.QueryString[<span>"k"</span>];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(key&nbsp;==&nbsp;<span>null</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseCode&nbsp;=&nbsp;<span>HttpStatusCode</span>.BadRequest;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>else</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>Debug</span>.Print(<span>"Received&nbsp;key&nbsp;"</span>&nbsp;+&nbsp;key);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>bool</span>&nbsp;success&nbsp;=&nbsp;<span>true</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseCode&nbsp;=&nbsp;success&nbsp;?&nbsp;<span>HttpStatusCode</span>.OK&nbsp;:&nbsp;<span>HttpStatusCode</span>.ServiceUnavailable;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>default</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseCode&nbsp;=&nbsp;<span>HttpStatusCode</span>.NotFound;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.Response.StatusCode&nbsp;=&nbsp;(<span>int</span>)responseCode;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.Response.Close();
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//&nbsp;Wait&nbsp;for&nbsp;the&nbsp;next&nbsp;request</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.listener.BeginGetContext(ListenerCallback,&nbsp;<span>null</span>);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;<span>catch</span>(<span>IOException</span>)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</pre>
<p>Let's examine this in detail. First, a check that the listener is still active - when stopped, IsListening will be false. (Note that if the listener is torn down while the callback is running, an IO exception is thrown - I really ought to avoid this instead of wrapping the handler in a try...catch block.) Having determined that the listener is running, EndGetContext completes the reception of an HTTP request. Since, as I said above, I want to handle only communications within the PC, I reject any incoming requests where IsLocal is false (the HttpListener can be used across machines too, of course, though configuration is a bit of a chore).</p>
<p>Next, I "parse" the URL in the request, looking for path "/key" and the "k" query parameter. All I do here is print out the received message.</p>
<p>I close the request's response to let the client clean up correctly - there's just an error status and no content (though I could send something back - an HTML help page, for example, when given an unrecognised request URL).</p>
<p>Finally, as mentioned above, the callback is not registered as a continuous handler, but as the completion function for a single request, so I need to initiate another request-to-receive before returning.</p>
<p>That's all there is to a simple mini web server. To test it, run and then fire up a web browser and navigate to "http://localhost:17765/key?k=F" and the debug console will show the expected message.</p>
<p>Here's a mindtaxingly complex .NET client which does the same thing:</p>
<pre><span>var</span>&nbsp;req&nbsp;=&nbsp;<a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/ff382788.aspx"><span>WebRequest</span>.CreateHttp</a>(<span>"http://localhost:17765/key?k=F"</span>);
<span>var</span>&nbsp;resp&nbsp;=&nbsp;req.GetResponse();
</pre>
<p>I could examine the response for the error code (or any content passed back) but I lazily don't care here.</p>
<p>Since this was all so simple, here's the same thing in native C++:</p>
<pre><span>auto</span>&nbsp;inet&nbsp;=&nbsp;<span><a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa385096.aspx">InternetOpen</a></span>(L<span>"MyAppClientId"</span>,&nbsp;<span>INTERNET_OPEN_TYPE_PRECONFIG</span>,&nbsp;<span>nullptr</span>,&nbsp;<span>nullptr</span>,&nbsp;0);
<span>auto</span>&nbsp;conn&nbsp;=&nbsp;<span>InternetOpenUrl</span>(inet,&nbsp;L"http://localhost:17765/key?k=F",&nbsp;<span>nullptr</span>,&nbsp;0,&nbsp;0,&nbsp;0);
InternetCloseHandle(conn);
InternetCloseHandle(inet);
</pre>
<p>I was brought up on raw sockets many years ago, and it still feels kinda astonishing that a web request can require so little C++.</p>
<p>So there you have it. Not as clever as .NET Remoting, in that you have to pack and unpack message arguments, but still very simple and quite performant.</p>]]></content:encoded>
    </item>
    <item>
      <title>Easy peasy IPC-sy</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/easy-peasy-ipc-sy</link>
      <pubDate>Sat, 22 Feb 2014 12:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2014/02/22/easy-peasy-ipc-sy/</guid>
      <description><![CDATA[Windows provides a wide range of inter process communication mechanisms, from very low level...]]></description>
      <content:encoded><![CDATA[<p>Windows provides a wide range of inter process communication mechanisms, from very low level <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms740673.aspx">sockets</a>&nbsp;(which can easily be used from <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/b6xa24z5.aspx">managed applications</a> too) to much more sophisticated <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/ms731082.aspx">WCF</a>. However, the lighter weight ones tend to require a lot of fiddling with message structures and processing, and the heavier ones are, well, rather costly for simple messaging between applications on the same machine. One extremely simple mechanism introduced early in .NET's history is <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/kwdt6w2k.aspx">.NET Remoting</a>. Alas it's now deprecated, which is a shame and I can't really recommend it for any future work - it does have limitations but it's so easy to use that it's still my first choice in almost any research prototype (but definitely <em>not</em>&nbsp;for production code) which requires one-way communications between cooperating .NET processes, even though it is "old" and frowned upon technology.</p>
<p>There are three components in a typical remoting setup: a class definition for whatever it is I need to communicate between the two processes, a client library and a server mechanism at the other end.</p>
<p>The following is a (much simplified) version of the library I use to communicate between <a title="Project page" href="http://research.microsoft.com/en-us/projects/projectcolletta/">Project Colletta</a> add-ins and the main process:</p>
<pre>public interface IToolbarManager<br />{<br />    Guid CreateToolbar(IntPtr hwnd, string path, string title);<br /><br />    [System.Runtime.Remoting.Messaging.OneWay]<br />    void Move(IntPtr hwnd, Guid docId);<br />}</pre>
<p>The first method requests that the main process create a tool bar associated with the window (HWND) and document (path and title) specified. The second method is used for the add-in to notify the main process that the window has moved, and thus the tool bar needs to be moved too - this can be marked as OneWay, to gain a slight efficiency improvement, because the client doesn't need to wait for the server to do anything before it can move on (as also indicated by the method's void return). This is built into a separate assembly that can be shared between client and server.</p>
<p>The server provides a concrete implementation of this interface:</p>
<pre>internal class ToolbarManager : MarshalByRefObject, IToolbarManager<br />{<br />    public Guid CreateToolbar(IntPtr hwnd, string path, string title)<br />    {<br />        // Create the tool bar<br />    }<br /><br />    public void Move(IntPtr hwnd, Guid docId)<br />    {<br />        // Move the tool bar<br />    }<br />}</pre>
<p>Note that it derives from <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx">MarshalByRefObject</a>, a signal that this is exposed for remote access. The only other thing the server has to do is expose this to the outside world - there are several ways to do this, but I tend to use the following:</p>
<pre>var provider = new BinaryServerFormatterSinkProvider();<br />provider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;<br />var props = new System.Collections.Hashtable();<br />props["port"] = <em>SOME_PORT_NUMBER</em>;<br />props["bindsTo"] = "localhost";<br />props["rejectRemoteRequests"] = "true";<br />ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Tcp.TcpServerChannel(props, provider), false);<br />RemotingConfiguration.RegisterWellKnownServiceType(typeof(ToolbarManager), "<em>SOME_UNIQUE_NAME</em>", WellKnownObjectMode.Singleton);</pre>
<p>Only the last&nbsp;pair of&nbsp;calls is actually essential since the system accepts defaults for most of the communication properties, but I&nbsp;tend to take the opportunity&nbsp;to define some non-default values. First, I explicitly request binary serialization (XML is an alternative). Second, by setting "rejectRemoteRequests" I ensure that only processes on the same machine can invoke functions on the server process. The last line means that any process asking for the IToolbarManager interface on the specified port will create or reuse an instance of the ToolbarManager concrete class - and that's all that is required on the server. Do note that requests can come in on arbitrary threads, and I usually end up having methods such as those in ToolbarManager marshal across to the main thread or provide some other means of thread synchronization.</p>
<p>On the client side, I make sure that the TCP channel is available:</p>
<pre>ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Tcp.TcpClientChannel(), false);</pre>
<p>and specify the connection with:</p>
<pre>var manager = (IToolbarManager)Activator.GetObject(typeof(IToolbarManager),<br />                 "tcp://localhost:" + <em>SOME_PORT_NUMBER</em> + "/" + <em>SOME_PORT_NAME</em>);</pre>
<p>Now I can invoke manager.CreateToolbar and manager.Move to perform those operations.</p>
<p>And that's all there is to it - it really is so simple that, even though this is deprecated technology, it's still my favourite way to get a couple of processes to talk to each other. If you want to know more about .NET Remoting, I can recommend a <a title="Apress book" href="http://www.apress.com/9781590594179">couple</a> of <a title="MS Press book" href="http://www.microsoft.com/learning/en-us/book.aspx?id=6172">really</a> good books - you can tell from their publication dates (2005 and 2002, respectively) that this is old technology!</p>]]></content:encoded>
    </item>
    <item>
      <title>Phone magic</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/phone-magic</link>
      <pubDate>Sun, 19 Jan 2014 04:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2014/01/19/phone-magic/</guid>
      <description><![CDATA[If you've never come across Scam School before, do take a look at it - it normally offers a bit of...]]></description>
      <content:encoded><![CDATA[<p>If you've never come across <a title="Scam School home" href="http://testtube.com/scamschool">Scam School</a> before, do take a look at it - it normally offers a bit of entertainment on a Thursday. <a title="Scam School episode" href="http://testtube.com/scamschool/greg-rostami-smartphone-trick">One in particular</a> caught my eye recently: there have been a few episodes using smart phones as props in magic tricks, but in this one <a title="Greg Rostami's site" href="http://www.rostamimagic.com/">Greg Rostami</a> does something clever with the accelerometer. He's got a bunch of cunning apps there but, alas, not for Windows Phone - so I thought I's create a vastly simplified and minimalist version of his <a title="iForce page" href="http://www.rostamimagic.com/apps/iforce/index.html">iForce</a> for WP. I'm deliberately making it very minimal to not step on his toes, and because I'm primarily interested in the core of the app, handling the accelerometer data.</p>
<p>The basis of the trick is to get someone to think of a number from 1 to 8; you run a drawing app on the phone and doodle a prediction, then place the phone face down; ask the person for their prediction and you turn the phone face up to show the same number. The way it works is that the drawing app is much more than that: when the phone is rotated from face down to up, the direction and speed of rotation causes the app to choose one of 8 images to show. I do feel a bit guilty at giving away the secret of the magic trick but Greg and <a title="Brian Brushwood's site" href="http://shwood.squarespace.com/">Brian Brushwood</a> pretty much completely did that in the Scam School episode anyway!</p>
<p>The root of the app, as mentioned, is the <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.devices.sensors.accelerometer.aspx">accelerometer</a>&nbsp;and the easiest way to see how it works is to grab the <a title="MSDN sample" href="http://code.msdn.microsoft.com/wpapps/Accelerometer-e5fcbbd3">demo code</a> from the MSDN samples site. If you run that app, you'll see that it reads X=0, Y=0, Z=1 when you hold the phone face down, as shown below:</p>
<p style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/84/7827.facedown.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-84/7827.facedown.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/84/7827.facedown.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/400x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-84/7827.facedown.png" alt="" border="0" /></a></p>
<p>Actually, you'll see values <em>close</em>&nbsp;to 1 and 0 - there will be some noise. If you tilt the phone along the long axis, you'll get X=1 (or -1 depending on which direction you tilt) and Y=0, Z=0, as shown below:</p>
<p style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/84/1682.side.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-84/1682.side.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/84/1682.side.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/400x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-84/1682.side.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>As you might expect, while transitioning from horizontal to vertical, Z will decrease and X (or Y, if tilting along the short axis) will get further from 0. All I need to do in this app is note which axis is increasing and in which direction as Z changes from close to 1 to a little bit from 0 - I want to make sure I've made my choice well before Z reaches 0, so that the victim can't see an incorrect screen. If you've been paying attention, you'll note that this gives only four values (positive X, positive Y and the two negatives): I also look at the speed of the transition - fast or slow - to give an additional four. Incidentally, I've no idea how the details here match up with iForce - I've not seen the source for that, nor have I looked any more closely at the app than what appeared in the video mentioned above. I've just thrown together something that kinda does the same job.</p>
<p>The accelerometer is started with:</p>
<pre><span>this</span>.accelerometer.CurrentValueChanged&nbsp;+=&nbsp;Accelerometer_CurrentValueChanged;
<span>this</span>.accelerometer.Start();
</pre>
<p>The callback is where the, er, magic happens:</p>
<pre>        void Accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs&lt;AccelerometerReading&gt; e)<br />        {<br />            this.accumulator = this.accumulator * 0.8f + e.SensorReading.Acceleration * 0.2f;<br />            if (accumulator.Z &gt; 0.9f)<br />            {<br />                this.startToMove = DateTime.Now;<br />                this.started = true;<br />            }<br />            else if (accumulator.Z &lt; 0.2f &amp;&amp; this.started)<br />            {<br />                done = true;<br />                bool isLong = (DateTime.Now - this.startToMove).TotalSeconds &gt; 1.0;<br />                var scores = new double[] { -accumulator.Y, accumulator.Y, accumulator.X, -accumulator.X };<br />                var best = 0;<br />                for (int i = 1; i &lt; scores.Length; ++i)<br />                    if (scores[i] &gt; scores[best])<br />                        best = i;<br />                if (isLong) best += 4;<br />                this.started = false;<br />                this.Dispatcher.BeginInvoke(() =&gt;<br />                {<br />                    // SET DISPLAY TO &lt;best&gt;<br />                });<br />            }<br />        }</pre>
<p>After applying a simple bit of smoothing to reduce the effect of noise, there are two phases: if the Z value is close to 1, assume the phone is face down and store the current time (as startToMove); if the Z value is close-ish to 0, work out which of the 4 directions of rotation happened, simply by looking for the maximum magnitude of the X and Y readings, and look at the time taken to get from face down to almost vertical. While I could pre-can 8 images and select one at the end of that callback, the rest of this short application deals with collecting 8 doodles from the user and persisting them across runs of the application.</p>
<p>The obvious mechanism to use is the <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.controls.inkpresenter(v=vs.105).aspx">InkPresenter</a>. I capture "mouse" down (i.e., finger touching the screen) and moves to capture drawing actions, and then convert those to stroke data to store on the ink presenter:</p>
<pre><span>private</span>&nbsp;<span>void</span>&nbsp;Ink_MouseLeftButtonDown(<span>object</span>&nbsp;sender,&nbsp;System.Windows.Input.<span>MouseButtonEventArgs</span>&nbsp;e)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.Ink.CaptureMouse();
 
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke&nbsp;=&nbsp;<span>new</span>&nbsp;<span>Stroke</span>();
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(<span>this</span>.Ink));
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke.DrawingAttributes.Color&nbsp;=&nbsp;System.Windows.Media.<span>Colors</span>.White;
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke.DrawingAttributes.Width&nbsp;=&nbsp;3.0;
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.Ink.Strokes.Add(<span>this</span>.stroke);
}
 
<span>private</span>&nbsp;<span>void</span>&nbsp;Ink_MouseMove(<span>object</span>&nbsp;sender,&nbsp;System.Windows.Input.<span>MouseEventArgs</span>&nbsp;e)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(<span>this</span>.stroke&nbsp;!=&nbsp;<span>null</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(<span>this</span>.Ink));
}
 
<span>private</span>&nbsp;<span>void</span>&nbsp;Ink_MouseLeftButtonUp(<span>object</span>&nbsp;sender,&nbsp;System.Windows.Input.<span>MouseButtonEventArgs</span>&nbsp;e)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.stroke&nbsp;=&nbsp;<span>null</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span>this</span>.Ink.ReleaseMouseCapture();
}
</pre>
<p>(Ink is the InkPresenter, stroke is a Stroke object which is added to the StrokeCollection rendered on the presenter.)</p>
<p>The app has an edit page which iterates over 8 drawings, thus giving me a collection of the 8 stroke collections to be displayed. The final lines of the accelerometer change routine above select the appropriate set of strokes and loads them into the ink presenter.</p>
<p>The final bit of polish on the app is to persist the stroke data, instead of requiring the user to do the 8 drawings every time. Alas the stroke collection class is not itself serializable, so I need to convert to some string format to persist in phone storage. Being lazy, I let the XmlSerializer handle the final conversion, and just convert the 8 stroke collections into a multi dimensional array of points (an array of stroke collections, each of which is an array of strokes, each of which is an array of points - I'm ignoring stroke attributes such as colour and thickness here).</p>
<pre>        internal void Save()<br />        {<br />            var pts = new Point[this.strokes.Length][][];<br />            for (int i = 0; i &lt; this.strokes.Length; ++i)<br />            {<br />                var sc = this.strokes[i];<br />                pts[i] = new Point[sc.Count][];<br />                for (int j = 0; j &lt; sc.Count; ++j)<br />                    pts[i][j] = sc[j].StylusPoints.Select(p =&gt; new Point(p.X, p.Y)).ToArray();<br />            }<br />            var ser = new XmlSerializer(pts.GetType());<br />            using (var s = IsolatedStorageFile.GetUserStoreForApplication().CreateFile("Strokes"))<br />            {<br />                ser.Serialize(s, pts);<br />            }<br />        }<br /><br />        internal void Load()<br />        {<br />            try<br />            {<br />                using (var s = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("Strokes", FileMode.Open))<br />                {<br />                    var ser = new XmlSerializer(typeof(Point[][][]));<br />                    var pts = (Point[][][])ser.Deserialize(s);<br />                    this.strokes = new StrokeCollection[pts.GetLength(0)];<br />                    for(int i = 0; i &lt; strokes.Length; ++i)<br />                    {<br />                        var sc = new StrokeCollection();<br />                        foreach(var s in pts[i])<br />                        {<br />                           var stroke = new Stroke();<br />                            stroke.DrawingAttributes.Color = System.Windows.Media.Colors.White;<br />                            stroke.DrawingAttributes.Width = 3.0;<br />                            foreach (var p in s)<br />                                stroke.StylusPoints.Add(new StylusPoint(p.X, p.Y));<br />                            sc.Add(stroke);<br />                        }<br />                        this.strokes[i] = sc;<br />                    }<br />                }<br /><br />            }<br />            catch<br />            {<br />                this.strokes = new StrokeCollection[8];<br />                for (int i = 0; i &lt; 8; ++i)<br />                    this.strokes[i] = new StrokeCollection();<br />            }<br />        }</pre>
<p>If loading fails (as it will the first time the app is run, for example), an empty set of stroke data is created.</p>
<p>So there you have it - a very poor sibling to Greg's iForce, but functional. (I'll put it in the store soon, and will update this article with a pointer.)</p>]]></content:encoded>
    </item>
    <item>
      <title>What's in a window?</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/whats-in-a-window</link>
      <pubDate>Sat, 21 Dec 2013 04:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/12/21/whats-in-a-window/</guid>
      <description><![CDATA[It's probably not too surprising that one of the important bits of functionality in Project Colletta...]]></description>
      <content:encoded><![CDATA[<p>It's probably not too surprising that one of the important bits of functionality in <a title="Project page" href="http://research.microsoft.com/en-us/projects/projectcolletta/">Project Colletta</a> is relating a window on the screen (a HWND to be precise) to a document, in particular, to the file path of the document appearing in that window. The <a title="MSDN page" href="http://msdn.microsoft.com/en-US/office/hh133430">VSTO</a> APIs provide access to document details for all of the Office applications (what I'll refer to as the "insider" view), but do not offer any way to get hold of the window handle (the "outsider" view) and, in early (and very unreliable) prototypes I would, roughly speaking, have a global list of documents opened in Word, Excel, etc. and a separate global list of window handles, and attempt to match entries in the first list with those in the second based on window title strings. I do still end up doing this for Outlook (which goes some way towards explaining why that is the most troublesome of the Office applications Project Colletta deals with). However, <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd317978.aspx">AccessibleObjectFromWindow</a> makes things an awful lot easier for Word, Excel, PowerPoint and, as it happens, Acrobat Reader. This function exists to provide accessibility clients (such as screen readers) a way to get at the object model of whatever a window happens to be displaying, <em>i.e.</em>, a direct link from the outsider view to the insider, which is precisely what I wanted in Project Colletta. The basic pattern in Project Colletta is to watch for windows coming and going, grab ones which are of a window class of interest, and then get hold of their object model via AccessibleObjectFromWindow, and extract the file path from there.</p>
<p>For the first step, I use Windows Events (see <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd373640.aspx">SetWinEventHook</a> for details) to get a callback when windows are created or come to the foreground or move, <em>etc</em>. Only the first of those is really relevant to the current discussion, but I track movement to update the location of the docbars at the bottom of the document windows. (The docbars are implemented as separate windows, owned by the main Project Colletta application, positioned to line up with the related application window - if you drag application windows around very quickly, you can detect a lag before the docbar catches up - but that is a small price to pay compared to the complexity in incorporating the docbar code into each and every supported application process!) Here's a stripped down code fragment showing the basics.</p>
<pre>[<span>DllImport</span>(<span>"user32.dll"</span>,&nbsp;SetLastError=<span>true</span>)]
<span>internal</span>&nbsp;<span>extern</span>&nbsp;<span>static</span>&nbsp;IntPtr&nbsp;SetWinEventHook(&nbsp;<span>uint</span>&nbsp;eventMin,&nbsp;<span>uint</span>&nbsp;eventMax,&nbsp;IntPtr&nbsp;hmodWinEventProc,&nbsp;<span>WinEventProc</span>&nbsp;lpfnWinEventProc,&nbsp;<span>uint</span>&nbsp;idProcess,&nbsp;<span>uint</span>&nbsp;idThread,&nbsp;<span>uint</span>&nbsp;dwFlags&nbsp;);</pre>
<pre>private&nbsp;Win32.WinEventProc&nbsp;winEventProc;&nbsp;//&nbsp;Keep&nbsp;as&nbsp;class&nbsp;member&nbsp;to&nbsp;prevent&nbsp;premature&nbsp;GC
</pre>
<pre>private void WinEventHandler(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)</pre>
<pre>{<br />    // Only look at top level windows<br />    if (idObject != OBJID_WINDOW || idChild != CHILDID_SELF || Win32.GetParent(hwnd) != IntPtr.Zero)<br />        return;<br /><br />    switch (eventType)<br />    {<br />        case EVENT_OBJECT_CREATE:<br />            RegisterWindow(hwnd);<br />            break;<br /><br />        ...<br />    }<br />}</pre>
<pre>&nbsp;</pre>
<pre>...</pre>
<pre>&nbsp;&nbsp;&nbsp;&nbsp;this.winEventProc&nbsp;=&nbsp;this.WinEventHandler;
&nbsp;&nbsp;&nbsp;&nbsp;this.winEventHook&nbsp;=&nbsp;Win32.SetWinEventHook(EVENT_First,&nbsp;EVENT_Last,&nbsp;IntPtr.Zero,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.winEventProc,&nbsp;0,&nbsp;0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;/*WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS*/&nbsp;);
</pre>
<pre>...</pre>
<p>When I have a new window to examine, I need to determine if it's one I'm interested in. I could look at its process name but that's a bit cumbersome and, since I need to look at its window class anyway, I can use that. A tool like <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/vstudio/dd460756.aspx">Spy++</a> can show you the complete window hierarchy of a running application, something we'll look at in a moment, but all I need now is the class name for the top level window. <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633582.aspx">GetClassName</a> shows us that Word's main window is of class "OpusApp," Excel is "XLMAIN," PowerPoint is "PPTFrameClass" and Acrobat Reader is "AcrobatSDIWindow" - now these are not documented and guaranteed, so I do need to check them every time a new version of the application turns up.</p>
<p>The documentation for AccessibleObjectFromWindow has a table at the end showing what type of object we can get from a number of application's windoww - for example, a reference to a <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.window.aspx">Microsoft.Office.Interop.Word.Window</a> can be extracted from a window of class "_WwG" - but, hang on, we've got an "OpusApp" window, not a "_WwG" - what gives? This really is where Spy++ comes into its own: you can start at the "OpusApp" window and expand all the child windows until you find a "_WwG" a couple of levels down: one of the children of the top level window is of class "_WwF" which has one child of class "_WwB" and amongst the children of that is a single "_WwG" - it is fortunate that there only one child of the required type at each level since that makes the window search very easy. Again, this is undocumented and can change between versions (and in fact, has changed for PowerPoint - the chain for PowerPoint 2013 is "PPTFrameClass" "MDIClient" "mdiClass" but is&nbsp;"PPTFrameClass" "MDIClient" "mdiClass" "paneClassDC" for PowerPoint 2010, and something else again for PowerPoint 2007).</p>
<p>Given that, once the code above detects a top level window and I confirm it is of class "OpusApp" I can run the following to get hold of the Word object model Document displayed in it:</p>
<pre>private Word.Document GetWordDocument(IntPtr hwnd)<br />{<br />    string[] classes = new string[] { "_WwF", "_WwB", "_WwG" };<br />    var docHwnd = SetDocumentWindowByClass(hwnd, classes);<br />    if (docHwnd != IntPtr.Zero)<br />    {<br />        object o = GetDocumentObject(docHwnd, typeof(Word.Window));<br />        var window = o as Word.Window;<br />        if (window != null)<br />            return window.Document;<br />    }<br /><br />    return null;<br />}<br /><br />private static IntPtr GetDocumentWindowByClass(IntPtr topHwnd, string[] classes)<br />{<br />        IntPtr docHwnd = topHwnd;<br />        for (int i = 0; i &lt; classes.Length &amp;&amp; docHwnd != IntPtr.Zero; ++i)<br />            docHwnd = Win32.FindWindowEx(docHwnd, IntPtr.Zero, classes[i], null);<br />        return docHwnd;<br />}</pre>
<pre><span>private</span>&nbsp;<span>static</span>&nbsp;GetDocumentObject(IntPtr docHwnd, <span>Type</span>&nbsp;documentObjectType)
{
&nbsp;&nbsp;&nbsp;&nbsp;Guid&nbsp;guid&nbsp;=&nbsp;documentObjectType.GUID;
&nbsp;&nbsp;&nbsp;&nbsp;<span>object</span>&nbsp;o;
&nbsp;&nbsp;&nbsp;&nbsp;<span>if</span>&nbsp;(AccessibleObjectFromWindow(docHwnd,&nbsp;OBJID_NATIVEOM,&nbsp;<span>ref</span>&nbsp;guid,&nbsp;<span>out</span>&nbsp;o)&nbsp;!=&nbsp;0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;=&nbsp;<span>null</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span>return</span>&nbsp;o;
}
 
[<span>DllImport</span>(<span>"oleacc.dll"</span>)]
<span>private</span>&nbsp;<span>static</span>&nbsp;<span>extern</span>&nbsp;<span>int</span>&nbsp;AccessibleObjectFromWindow(IntPtr&nbsp;hwnd,&nbsp;<span>uint</span>&nbsp;id,&nbsp;<span>ref</span>&nbsp;Guid&nbsp;iid,&nbsp;[<span>MarshalAs</span>(<span>UnmanagedType</span>.IDispatch)]&nbsp;<span>out</span>&nbsp;<span>object</span>&nbsp;ppv);
<span>private</span>&nbsp;<span>const</span>&nbsp;<span>uint</span>&nbsp;OBJID_NATIVEOM&nbsp;=&nbsp;0xFFFFFFF0;
</pre>
<p>A bit of web spelunking and playing with Spy++ showed a pleasant surprise with Acrobat Reader. It exposes a (rather limited) document model too. Underneath top level window of class "AcrobatSDIWindow" can be found a chain of &nbsp;"AVSplitterView",&nbsp;"AVSplitationPageView",&nbsp;"AVSplitterView",&nbsp;"AVScrolledPageView",&nbsp;"AVScrollView",&nbsp;"AVPageView" (earlier versions of Acrobat Reader have different window hierarchies) and from the last of those we can get an IPDDomDocument, defined in the AcrobatAccessLib COM library (which you can easily get hold of via Add Reference, COM libraries), and this exposes a path value. Unfortunately, in protected mode (which is the default in later versions of the Acrobat Reader), the path is to a temporary copy rather than to the file the user opened, so it's not so useful after all.</p>
<p>So, to conclude, VSTO gives you a good insider view of an application, and AccessibleObjectFromWindow can link that to the outsider view, so that you can make something associated with the window on the screen react to the contents of the document shown in that window.</p>]]></content:encoded>
    </item>
    <item>
      <title>I've only ever written one application</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/ive-only-ever-written-one-application</link>
      <pubDate>Sun, 17 Nov 2013 10:53:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/11/17/ive-only-ever-written-one-application/</guid>
      <description><![CDATA[Actually, I mean, I've only ever written one application startup - in the same way I've only ever...]]></description>
      <content:encoded><![CDATA[<p>Actually, I mean, I've only ever written one application <em>startup</em> - in the same way I've only ever written two <a title="Wikipedia page" href="http://en.wikipedia.org/wiki/Make_(Unix)">make</a> files, one for applications and one for libraries, I just keep changing the words... OK, that's obviously a facetious statement, but it is true that almost all my .NET desktop applications have a very standard startup sequence just to make things a bit tidier: I include the following class in most applications;</p>
<pre>internal class Program<br />{<br />    [STAThread()]<br />    public static void Main()<br />    {<br />        string name = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Name;<br />        bool mutexCreated;<br />        using (var mutex = new Mutex(false, name, out mutexCreated))<br />        {<br />            if (mutexCreated)<br />            {<br />                WerExclusion(true);<br /><br />                App.Main();<br /><br />                WerExclusion(false);<br />            }<br />            else<br />                MessageBox.Show("This app already running");<br />        }<br />    }<br />}</pre>
<p>I create a <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx">mutex</a> to be able to make sure only one copy of the application is running at a time - quite useful when debugging, in case I don't notice that a copy is already running and grabbing some shared resource. The assembly name is a convenient vaguely unique name for me to use, but I do sometimes make use of an explicit name, for example, when I have multiple co-operating processes, and I want one to be able to check if another is running. (I use this in <a title="Project home page" href="http://research.microsoft.com/en-us/um/cambridge/projects/ResearchDesktop/ProjectColletta/default.htm">Project Colletta</a> for application add-ins to check if the main executable is running, to avoid messaging timeouts and errors.)</p>
<p>Unless you're a programming demigod, the first few versions of your application probably crash every so often. And this typically results in that dialog box asking you if you want to report errors to Microsoft, which is fairly pointless for a self-developed application, certainly in its early days. Since Windows Vista, a couple of functions have been available to mark (and unmark) applications as being excluded from this automatic error reporting - see the <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb513617.aspx">WerAddExcludedApplication</a>&nbsp;documentation for details. I tend to mark my applications in this way, if nothing else, to remove the delay before I can dismiss the crash dialog and close the faulting application. For tidiness, though I don't think it's necessary, I get rid of the entry in the exclusion list when my app exits (ideally this should be later than shown here, but this suffices). The following is a simple wrapper on this native mechanism:</p>
<pre>private static void WerExclusion(bool add)<br />{<br />    var exe = Assembly.GetExecutingAssembly().Location;<br />    try<br />    {<br />        int hr = add ? Win32.WerAddExcludedApplication(exe, false) :<br />                       Win32.WerRemoveExcludedApplication(exe, false);<br />        Debug.Assert(hr == 0);<br />    }<br />    catch<br />    {<br />        Debug.WriteLine("WER functions not available");<br />    }<br />}<br /><br />[DllImport("wer.dll", CharSet=CharSet.Unicode)]<br />internal static extern int WerAddExcludedApplication(string exeName, [MarshalAs(UnmanagedType.Bool)] bool allUsers);<br /><br />[DllImport("wer.dll", CharSet=CharSet.Unicode)]<br />internal static extern int WerRemoveExcludedApplication(string exeName, [MarshalAs(UnmanagedType.Bool)] bool allUsers);</pre>
<p>(Yes, I know, I'm being far too sloppy in terms of error handling here - my feeble excuse is that this is a mere nice-to-have and not essential.)</p>
<p>Of course, an alternative to the Windows error report exclusion list manipulations would be to implement an unhandled exception handler (<a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx">AppDomain.UnhandledException</a>) but I tend not to do that for a couple of reasons: first, it needs to be done for each application domain and I often forget; second, it interferes (though only slightly) with debugging, in that by default Visual Studio traps unhandled exceptions itself, unless there's an handler for them (an easy default to change via the exception settings page). I'm in two minds about whether "proper" production applications should have unhandled exception handlers - yes, it's rather unprofessional to show your end users a crash dialog box, but then so is crashing in the first place... Besides, there's not really a huge amount such a handler can do apart from perhaps log some small amount of data and then exit the application.</p>
<p>Finally, deep within my Program.Main is a call to App.Main. In Windows Forms applications, the Visual Studio Wizard provides a Program class with a Main method, and I add my extras to that, around the call to Application.Run. In WPF applications, the normal entry point is App.Main, which is autogenerated by the build process. An executable can have as many Main methods as you want, but you do need to tell Windows which one is the real entry point - and that's pretty easy to do via the Application page of the project options - the Startup object dropdown lists all available entry points and I make sure I pick mine. App.Main can, of course, just be called like any other function too.</p>
<p>And that's it, my one and only application startup. Well, for desktop .NET applications anyway.</p>]]></content:encoded>
    </item>
    <item>
      <title>NoReplyAll Lite</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/noreplyall-lite</link>
      <pubDate>Sun, 13 Oct 2013 07:59:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/10/13/noreplyall-lite/</guid>
      <description><![CDATA[So far, all of the Office add-in work I've been talking about here has been based on VSTO, but some...]]></description>
      <content:encoded><![CDATA[<p>So far, all of the Office add-in work I've been talking about <a title="Previous blog post" href="http://blogs.msdn.com/b/gsmyth/archive/2011/09/18/noreply-vsto-add-in-wrap-up.aspx">here</a> has been based on VSTO, but some users of NoReplyAll have complained about having to install the .NET Framework (or, in some cases, install whatever version I'd chosen to use, because they've standardised on an earlier one, and don't want to, or can't, upgrade to newer). Additionally, there have been a couple of occasions where the difference between .NET's (garbage collected) way of managing resources and COM's deterministic mechanism has caused problems - for example, Outlook windows that won't go away, or an <a title="Forum post" href="http://social.microsoft.com/Forums/en-US/6c931e06-e348-41ae-bbbd-f9e5bea910bd/noreplyall-2410-save-attachment-on-network-locking-file">inability to delete .msg files</a>&nbsp;- my solution has been to add <a title="Previous blog post" href="http://blogs.msdn.com/b/gsmyth/archive/2011/08/06/outlook-object-model.aspx">a bunch of ugly Marshal.ReleaseComObject calls</a>, or even to force a garbage collection, which really takes me away from the convenience and elegance of VSTO. Because of these, it's been at the back of my mind to try writing a native C++ add-in, just to see how difficult it actually is - and I've finally got round to it.</p>
<p>Now, there are examples of native add-ins for Outlook out there - here are a <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/ee941475.aspx">couple</a> of <a title="Blog post" href="http://blogs.msdn.com/b/jensenh/archive/2006/12/08/using-ribbonx-with-c-and-atl.aspx">articles</a> worth reading &nbsp;- the examples I've come across have, like these, used <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/t9adwcde.aspx">ATL</a>. I find that ATL is very useful for creating COM objects of any complexity but feel that it's overkill for simple COM objects that have no Windows UI of their own: I don't like dragging in extra code to initialise things I don't need and it is a pain trying to debug through layers of wrappers (wrappers that were very convenient when writing the code, it must be said). Years ago, I user to work with DirectShow, and the COM framework that appeared in <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd389096.aspx">associated samples</a> used was much simpler than ATL - through reading those and some of the <a title="MSDN code sample" href="http://code.msdn.microsoft.com/CppShellExtThumbnailHandler-32399b35">shell integration samples</a>, I've ended up writing a lot of COM material without using any support framework.</p>
<p>Given all that, there are two parts to the add-in: "boilerplate" COM registration, and talking to Outlook. A very good summary of the first can be found in <a title="Blog post" href="http://blogs.msdn.com/b/oldnewthing/archive/2010/03/12/9977246.aspx">Raymond Chen's blog</a> and I won't repeat it here but will focus on the second. My Outlook add-in needs to implement three COM interfaces: IDTExtensibility2 (for an Office application to be able to load it), IRibbonExtensibility (as the name suggests, to be able to interact with the ribbon), and IDispatch (to handle ribbon callbacks); and the first of those is pretty straightforward:</p>
<pre>	STDMETHOD(OnConnection)(LPDISPATCH /*application*/, AddinDesign::ext_ConnectMode /*connectMode*/, LPDISPATCH /*addInInst*/, SAFEARRAY** /*custom*/)<br />	{<br />		return S_OK;<br />	}<br />	STDMETHOD(OnDisconnection)(AddinDesign::ext_DisconnectMode /*removeMode*/, SAFEARRAY** /*custom*/)<br />	{<br />		return S_OK;<br />	}<br />	STDMETHOD(OnAddInsUpdate)(SAFEARRAY** /*custom*/)<br />	{<br />		return S_OK;<br />	}<br />	STDMETHOD(OnStartupComplete)(SAFEARRAY** /*custom*/)<br />	{<br />		return S_OK;<br />	}<br />	STDMETHOD(OnBeginShutdown)(SAFEARRAY** /*custom*/)<br />	{<br />		return S_OK;<br />	}</pre>
<p>In my case, no need to do anything in response to the extensibility callbacks apart from to say, yup, OK, continue on your way. IRibbonExtensibility has only one methid, GetCustomUI, which is pretty much the same as the managed one I've shown before - the details are slightly different, this being C++, so it's not as convenient as simply returning a string:</p>
<pre>STDMETHODIMP CNoReplyAllLite::GetCustomUI(BSTR ribbonID, BSTR* ribbonXml)</pre>
<pre>{<br />	wchar_t* xml;<br />	if (     lstrcmpW(ribbonID, L"Microsoft.Outlook.Mail.Compose") == 0 ||<br />		     lstrcmpW(ribbonID, L"Microsoft.Outlook.MeetingRequest.Send") == 0 ||<br />		     lstrcmpW(ribbonID, L"Microsoft.Outlook.Post.Compose") == 0)<br />		xml = composeRobbomXml<br />L"&lt;?xml version='1.0' encoding='UTF-8'?&gt;"<br />L"&lt;customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui' loadImage='Ribbon_LoadImage'&gt;"<br />L" &lt;ribbon&gt;"<br />L"  &lt;tabs&gt;"<br />L"   &lt;tab idMso='TabNewMailMessage'&gt;"<br />L"    &lt;group id='grpCReply' label='Disable'&gt;"<br />L"     &lt;toggleButton id='btnCNoReplyAll' tag='2'"<br />L"                   size='large' image='2'"<br />L"                   getPressed='ItemButton_IsPressed' onAction='ItemButton_Click'"<br />L"                   screentip='No Reply All' supertip='Prevent recipients within the same organisation from replying to all'"<br />L"                   label='Reply All' /&gt;"<br />L"     &lt;toggleButton id='btnCNoReply' tag='1'"<br />L"                   size='normal' image='1'"<br />L"                   getPressed='ItemButton_IsPressed' onAction='ItemButton_Click'"<br />L"                   screentip='No Reply' supertip='Prevent recipients within the same organisation from replying'"<br />L"                   label='Reply' /&gt;"<br />L"     &lt;toggleButton id='btnCNoForward' tag='3'"<br />L"                   size='normal' image='3'"<br />L"                   getPressed='ItemButton_IsPressed' onAction='ItemButton_Click'"<br />L"                   screentip='No Forward' supertip='Prevent recipients within the same organisation from forwarding the message'"<br />L"                   label='Forward' /&gt;"<br />L"    &lt;/group&gt;"<br />L"   &lt;/tab&gt;"<br />L"  &lt;/tabs&gt;"<br />L" &lt;/ribbon&gt;"<br />L"&lt;/customUI&gt;";<br />	else<br />		xml = nullptr;<br /><br />	*ribbonXml = xml ? SysAllocString(xml) : nullptr;<br />	return S_OK;<br />}</pre>
<p>My IDispatch implementation takes care of matching the callbacks in that, such as ItemButton_IsPressed, to a C++ method:</p>
<pre>STDMETHODIMP CNoReplyAllLite::GetIDsOfNames( REFIID, OLECHAR** names, UINT num, LCID lcid, DISPID* dispids )</pre>
<pre>{<br />	HRESULT hr = S_OK;<br />	for( UINT i = 0; i &lt; num; ++i )<br />		if( CompareStringW( lcid, 0, names[ i ], -1, L"ItemButton_Click", -1 ) == CSTR_EQUAL )<br />			dispids[i] = DISPID_ITEMBUTTON_ONACTION;<br />		else if( CompareStringW( lcid, 0, names[ i ], -1, L"ItemButton_IsPressed", -1 ) == CSTR_EQUAL )<br />			dispids[i] = DISPID_ITEMBUTTON_GETPRESSED;<br />		else if( CompareStringW( lcid, 0, names[ i ], -1, L"Ribbon_LoadImage", -1 ) == CSTR_EQUAL )<br />			dispids[i] = DISPID_RIBBON_LOADIMAGE;<br />		else<br />		{<br />			dispids[i] = DISPID_UNKNOWN;<br />			hr = DISP_E_UNKNOWNNAME;<br />		}<br />	return hr;<br />}<br /><br />STDMETHODIMP CNoReplyAllLite::Invoke( DISPID dispid, REFIID, LCID, WORD /*flags*/, DISPPARAMS* params, VARIANT* result, EXCEPINFO*, UINT* )<br />{<br />	switch( dispid )<br />	{<br />		case DISPID_ITEMBUTTON_ONACTION:<br />			{<br />				// Remember: rgvarg array in *reverse* order<br />				Office::IRibbonControlPtr control = params-&gt;rgvarg[1].pdispVal;<br />				ItemButton_Click(control, params-&gt;rgvarg[0].boolVal);<br />			}<br />			break;<br /><br />		case DISPID_ITEMBUTTON_GETPRESSED:<br />			{<br />				Office::IRibbonControlPtr control = params-&gt;rgvarg[0].pdispVal;<br />				variant_t b = ItemButton_IsPressed(control);<br />				*result = b.Detach();<br />			}<br />			break;<br /><br />		case DISPID_RIBBON_LOADIMAGE:<br />			{<br />				IDispatchPtr pic = Ribbon_LoadImage(params-&gt;rgvarg[0].bstrVal);<br />				variant_t disp = pic.Detach();<br />				*result = disp.Detach();<br />			}<br />			break;<br />	}<br /><br />	return S_OK;<br />}</pre>
<p>Notice that rather than "raw" VARIANTs and COM pointers, I favour variant_t and the _com_ptr_t types: these wrap and hide the details of cleanup and, in the case of the latter, QueryInterface too. (Without these, I'd almost certainly make more use of ATL, because it provides similar wrappers.)</p>
<p>Taking a small step back: in order to be able to access the extensibility and Office interfaces, I need to import their type libraries, which requires the following -</p>
<pre>// IDTExtensibility2<br />#import "libid:AC0714F2-3D04-11D1-AE7D-00A0C90F26F4" auto_rename auto_search raw_interfaces_only rename_namespace("AddinDesign")</pre>
<pre>// Office type library (i.e. mso.dll)<br />#import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" auto_rename auto_search raw_interfaces_only rename_namespace("Office")<br /><br />// Outlook type library (i.e. msoutl.olb)<br />#import "libid:00062FFF-0000-0000-C000-000000000046" auto_rename auto_search rename_namespace("Outlook") rename("GetOrganizer", "GetOrganizerAddressEntry")</pre>
<p>There are two ways to #import a library - by filename or by registered library id. The latter is more useful in that it doesn't require a fixed absolute path (which will change for different versions of Office, or non default installations). Unfortunately, using the libid versions confuses IntelliSense, and the Visual Studio editor doesn't recognise any of the type names, but that is only a problem in that erroneous red squigglies appear. #import can also make use of the helper classes mentioned above, but that's only useful when calling into the library as opposed to implementing interfaces defined there - here, that means that raw makes sense for the Office and extensibility libraries. The "cooked" definitions are useful for the Outlook object model library, but notice the rename at the end - without that the imported file ends up with two instances of GetOrganizer which differ only in return type, a C++ error.</p>
<p>Here are the handlers for the click and is-pressed callbacks (error checking omitted for brevity):</p>
<pre>void CNoReplyAllLite::ItemButton_Click(Office::IRibbonControl* control, VARIANT_BOOL pressed)<br />{<br />	IDispatchPtr item = GetItemFromButton(control);<br />	Outlook::ActionPtr action = GetActionFromButton(control, item);<br />	VARIANT_BOOL enabled = pressed ? VARIANT_FALSE : VARIANT_TRUE;<br />	HRESULT hr = action-&gt;put_Enabled(enabled);<br />}<br /><br />VARIANT_BOOL CNoReplyAllLite::ItemButton_IsPressed(Office::IRibbonControl* control)<br />{<br />	IDispatchPtr item = GetItemFromButton(control);<br />	Outlook::ActionPtr action = GetActionFromButton(control, item);<br />	VARIANT_BOOL enabled;<br />	HRESULT hr = action-&gt;get_Enabled(&amp;enabled);<br />	return (SUCCEEDED(hr) &amp;&amp; enabled) ? VARIANT_FALSE : VARIANT_TRUE;<br />}</pre>
<p>There are definitely too many forms of boolean in Windows C++ - bool, BOOL and VARIANT_BOOL, all of which are different base types and have different values for true, hence the (perhaps overly pedantic) conversions between bool and VARIANT_BOOL above.</p>
<p>As with the VSTO implementation, I follow a short route from the ribbon control to get hold of the item it's associated with:</p>
<pre>static IDispatchPtr GetItemFromButton(Office::IRibbonControl* control)<br />{<br />	HRESULT hr;<br />	IDispatchPtr context;<br />	hr = control-&gt;get_Context(&amp;context);<br />	Outlook::_InspectorPtr inspector = context;<br />	IDispatchPtr item;<br />	hr = inspector-&gt;get_CurrentItem(&amp;item);<br />	return item;<br />}</pre>
<p>This is where things get a bit tricky... As mentioned before, the various Outlook items which appear in inspector windows do not share a common base class. I don't want to try QueryInterface for all of them, and then use almost identical code (but for the type) to access the Action associated with each. In the managed case, I used reflection instead and, here, I do more or less the same, via the item's IDispatch interface:</p>
<pre>static Outlook::ActionPtr GetActionFromButton(Office::IRibbonControl* control, IDispatch* item)<br />{<br />	HRESULT hr;<br />	BSTR bstr = nullptr;<br />	hr = control-&gt;get_Tag(&amp;bstr);<br />	_bstr_t tag(bstr, false);<br />	int index = bstr[0] - L'0';<br />	wchar_t* actionsName = L"Actions";<br />	DISPID id;<br />	hr = disp-&gt;GetIDsOfNames(IID_NULL, &amp;actionsName, 1, LOCALE_SYSTEM_DEFAULT, &amp;id);<br />	if (FAILED(hr))<br />		return nullptr;<br />	DISPPARAMS params = {0};<br />	variant_t result;<br />	hr = disp-&gt;Invoke(id, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &amp;params, &amp;result, nullptr, nullptr);<br />	Outlook::ActionsPtr actions = result;<br />	Outlook::ActionPtr action;<br />	variant_t actionIndex = index;<br />	hr = actions-&gt;Item(actionIndex, &amp;action);<br />	return action;<br />}</pre>
<p>Quite a lot uglier than the C# code I've shown before, but it's doing the same thing.</p>
<p>The final task for the code is button images. Again, the C++ world is similar to the C# one, just a few more hoops to jump through. I've embedded icons for the three buttons, with resource ids 101-103, and the ribbon's loadImage callback grabs the resource and converts to an IPictureDisp to be displayed - although OleCreatePictureIndirect does indeed create one of those, I only actually need the IDispatch pointer here.</p>
<pre>IDispatchPtr CNoReplyAllLite::Ribbon_LoadImage(BSTR imageName)<br />{<br />	int resourceId = 100 + imageName[0] - L'0';<br /><br />	PICTDESC desc = {sizeof(PICTDESC)};<br />	desc.picType = PICTYPE_ICON;<br />	desc.icon.hicon = LoadIcon(g_hInst, MAKEINTRESOURCE(resourceId));<br />	assert(desc.icon.hicon);<br /><br />	IDispatchPtr pic;<br />	HRESULT hr = OleCreatePictureIndirect(&amp;desc, __uuidof(IDispatch), TRUE, (void**)&amp;pic);<br /><br />	DestroyIcon(desc.icon.hicon);<br /><br />	return pic;<br />}</pre>
<p>With all that in place, I have a native NoReplyAll implementation. It was more work than the VSTO one, up until the time I realised I had COM object locking problems in the managed version, which then became more complex and messier! Would I write any future add-ins in C++ or C#? I guess it depends: for something as teeny as this, especially if I wanted it to work across multiple Office applications, then native C++ could be a good idea. However, for anything of any complexity, the convenience of managed code really wins. One other benefit of the managed route is that the same assembly can be used in 32 and 64 bit Office: with native code, I do need to build separate DLLs for each.</p>
<p>And the final question is: is anyone sufficiently interested in this that I ought to make it a release alongside the managed download?</p>]]></content:encoded>
    </item>
    <item>
      <title>Collecting URLs part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/collecting-urls-part-2</link>
      <pubDate>Sat, 14 Sep 2013 07:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/09/14/collecting-urls-part-2/</guid>
      <description><![CDATA[Using Ctrl-Shift-C is quick and convenient, but only if you remember it; and moving the mouse...]]></description>
      <content:encoded><![CDATA[<p>Using Ctrl-Shift-C is quick and convenient, but only if you remember it; and moving the mouse pointer all the way down to the Notification Area really is far too much like hard work. How about adding a control to the browser itself? Well, it's pretty easy to add something to Internet Explorer's <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/aa753591.aspx">menu</a> or <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/aa753588.aspx">toolbar</a>, but neither of those is visible in IE9 and above by default. A marginally more complex alternative is to add something to IE's context menu, which is what I'll describe here.</p>
<p>First of all, I need to adapt the program from last time so that it operates in two modes: as a resident application, as before, and a single shot "capture URLs and exit" mode. (There are other ways to support invoking from an external source such as the browser, but this is definitely the simplest.) I've replaced <a title="Previous post" href="http://blogs.msdn.com/b/gsmyth/archive/2013/08/17/collecting-urls.aspx">last time's</a> Main with:</p>
<pre>[STAThread]<br />static void Main()<br />{<br />    var args = Environment.GetCommandLineArgs();<br />    if (args.Length &gt; 1)<br />        switch (args[1][0]) // Just look at first letter and ignore the rest<br />        {<br />            case 'c':<br />            case 'C':<br />                CopyInternetExplorerTabsToClipboard();<br />                break;<br />        }<br />    else<br />    {<br />        bool mutexCreated;<br />        using (var mutex = new Mutex(false, "BrowserClip.Started", out mutexCreated))<br />        {<br />            if (mutexCreated)<br />            {<br />                &lt;Body of the previous version&gt;<br />            }<br />            else<br />                MessageBox.Show("The URL clipper is already running");<br />        }<br />    }<br />}</pre>
<p>The first modification is to check for command line arguments: if something starting with an upper or lowercase 'c' is given, perform the URL clip immediately, otherwise run as before. The second is a small bit of tidiness, to ensure that at most only a single resident instance of the application is running at any given time: the way this works is for the program to attempt to create a kernel object, a Mutex in this case; if this succeeds, then this is the first instance of the program, whereas if the Mutex already exists, another copy is already running.</p>
<p>Adding something to <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/aa753589.aspx">IE's context menu</a> is a two stage operation: a bit of registry manipulation to install the menu item and, because that can point only to an HTML file, such a file to invoke the clipping application. According to the MSDN page, you add the following to the registry to define a context menu item:</p>
<pre>[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\Clip all URLs]<br />"Contexts"=dword:00000001<br />@="<em>&lt;SOMEPATH&gt;</em>\RunBrowserClip.htm"</pre>
<p>I.e., add a key under HKCR\Software\Microsoft\Internet Explorer\MenuExt with the name of the menu item, giving its default value the absolute path to the HTML file to "run." The context defines when the menu item appears, 1 being the default - see the MSDN page for more details.</p>
<p>The HTML file contains nothing more than some JavaScript to run the application (with 'c' as the argument):</p>
<pre>&lt;html&gt;<br />&lt;script type="text/javascript"&gt;<br />var shell = new ActiveXObject("WScript.Shell");<br />shell.Run('"<em>&lt;EXEPATH&gt;</em>\\BrowserClip.exe" c');<br />&lt;/script&gt;<br />&lt;/html&gt;</pre>
<p>Again, this has to specify a complete path, to the executable this time, but note that backslashes have to be escaped here (i.e., doubled) or could be switched to forward slashes.</p>
<p>With this in place, you should now see "Clip all URLs" on IE's right click menu, and selecting that will place all URLs on the clipboard, just the same as using the Notification Area icon or hotkey. (The first time you use it from the context menu, you'll get a warning that the web page wants to execute something, but you can suppress that warning thereafter.)</p>
<p>It is slightly annoying that full paths are needed in both the registry and the HTML file: a nice setup program could insert the correct paths at install time but that seems like a lot of work. Instead, I chose to add registration operations to the program. The argument switch statement is augmented with 'r' to register and 'u' to unregister:</p>
<pre>    case 'r':<br />    case 'R':<br />        RegisterContextMenu();<br />        break;<br />    case 'u':<br />    case 'U':<br />        UnregisterContextMenu();<br />        break;</pre>
<p>And the functions look like this:</p>
<pre>private const string regPath = @"Software\Microsoft\Internet Explorer\MenuExt\Clip all URLs";<br /><br />private static void RegisterContextMenu()<br />{<br />    var exePath = Assembly.GetExecutingAssembly().Location;<br />    var directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);<br />    var htmlPath = GetHtmlPath();<br />    using (var w = new StreamWriter(htmlPath))<br />    {<br />        w.WriteLine("&lt;html&gt;&lt;script type='text/javascript'&gt;");<br />        w.WriteLine("var shell = new ActiveXObject('WScript.Shell');");<br />        w.WriteLine("shell.Run('\"{0}\" c');", new Uri(exePath).AbsoluteUri);<br />        w.WriteLine("&lt;/script&gt;&lt;/html&gt;");<br />    }<br />    using (var key = Registry.CurrentUser.CreateSubKey(regPath))<br />    {<br />        key.SetValue(null, htmlPath, RegistryValueKind.String);<br />        key.SetValue("Contexts", 1, RegistryValueKind.DWord);<br />    }<br />}<br /><br />private static void UnregisterContextMenu()<br />{<br />    Registry.CurrentUser.DeleteSubKeyTree(regPath);<br />    var htmlPath = GetHtmlPath();<br />    File.Delete(htmlPath);<br />}<br /><br />private static string GetHtmlPath()<br />{<br />    var directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);<br />    return Path.Combine(directory, "RunBrowserClip.htm");<br />}</pre>
<p>I write the HTML file into the current user's LocalAppData space (somewhere I can write without requiring admin permissions), and the contents of both the registry value and that HTML file are built on the fly to point to the appropriate places. Unregistering simply removes both parts again.</p>]]></content:encoded>
    </item>
    <item>
      <title>Collecting URLs</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/collecting-urls</link>
      <pubDate>Sat, 17 Aug 2013 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/08/17/collecting-urls/</guid>
      <description><![CDATA[Another one of those itches that need to be scratched: someone posted a query internally asking for...]]></description>
      <content:encoded><![CDATA[<p>Another one of those itches that need to be scratched: someone posted a query internally asking for tools that would copy URLs for all open browser windows to the clipboard. I don't know if such a tool exists but I thought it would be a fun exercise to write one regardless, especially since I had chunks of the necessary code hiding in <a title="Project home page" href="http://research.microsoft.com/en-us/um/cambridge/projects/ResearchDesktop/ProjectColletta/default.htm">Project Colletta</a>&nbsp;and its test harness already.</p>
<p>The first part of the puzzle is to find all the browser windows (tabs, actually) - I'm going to restrict myself to Internet Explorer because there's a convenient mechanism for locating them all (and, beside, given who I work for, it's obvious where I'm going to start), <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/cc836570.aspx">IShellWindows</a>, if I get hold of an appropriate object exposing that interface, I can iterate over the collection, identifying which windows are actually browser windows (the collection includes Windows Explorer as well as Internet Explorer), and grab their URLs:</p>
<pre>        private static IEnumerable&lt;Tuple&lt;string, string&gt;&gt; GetAllInternetExplorerTabs()<br />        {<br />            var tabs = new List&lt;Tuple&lt;string, string&gt;&gt;();<br /><br />            var CLSID_ShellWindows = new Guid("9BA05972-F6A8-11CF-A442-00A0C90A8F39");<br />            var shellWindowsType = Type.GetTypeFromCLSID(CLSID_ShellWindows);<br />            dynamic shellWindows = Activator.CreateInstance(shellWindowsType);<br /><br />            int count = shellWindows.Count;<br />            for (int i = 0; i &lt; count; i++)<br />            {<br />                try<br />                {<br />                    var browser = shellWindows.Item[i];<br />                    if (browser != null)<br />                    {<br />                        if (GetClassName((IntPtr)browser.HWND) == "IEFrame")<br />                        {<br />                            string url = browser.LocationURL;<br />                            string title = browser.LocationName;<br />                            Marshal.ReleaseComObject(browser);<br />                            tabs.Add(new Tuple&lt;string, string&gt;(url, title));<br />                        }<br />                    }<br />                }<br />                catch<br />                {<br />                }<br />            }<br />            Marshal.ReleaseComObject(shellWindows);<br />            return tabs;<br />        }</pre>
<p>Ignoring the fact that I'm being embarrassingly cavalier with regard to exception handling here, this operates by grabbing a ShellWindows object and extracting the URL and title from found browser windows. I've managed to keep the code very short by (lazily) relying on "dynamic" to look up properties and methods instead of COM casting things to the correct types. There will be a performance cost, but it's not important for this trivial application. If any of the dynamic accesses fail, an exception is thrown, hence my try...catch. I identify IE windows by looking at their window class names, using the helper function below. Finally, this routine returns a list of URL and title pairs for further processing.</p>
<pre>        private static string GetClassName(IntPtr hwnd)<br />        {<br />            var sb = new StringBuilder(256);<br />            GetClassName(hwnd, sb, sb.Capacity);<br />            return sb.ToString();<br />        }<br /><br />        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]<br />        private static extern int GetClassName(IntPtr hwnd, StringBuilder lpString, int nMaxCount);</pre>
<p>.NET offers a very easy way to place matter on the clipboard, <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard.settext.aspx">Clipboard.SetText</a>, and I use it as follows:</p>
<pre>        private static void CopyInternetExplorerTabsToClipboard()<br />        {<br />            var sb = new StringBuilder();<br />            foreach (var t in GetAllInternetExplorerTabs())<br />            {<br />                if (Properties.Settings.Default.IncludeTitles)<br />                    sb.AppendLine(t.Item2);<br />                sb.AppendLine(t.Item1);<br />            }<br /><br />            if (sb.Length &gt; 0)<br />                Clipboard.SetText(sb.ToString());<br />        }</pre>
<p>I found I needed that length check because Clipboard.SetText got unhappy when given no text.</p>
<p>The next step is to wrap this in an application - I created a Windows Forms app, and threw away the form, creating a Notification Area icon instead:</p>
<pre>        private static NotifyIcon CreateNotificationIcon()<br />        {<br />            var menu = new ContextMenu(<br />                new MenuItem[]{<br />                    new MenuItem("Clip URLs", (sender, e) =&gt; { CopyInternetExplorerTabsToClipboard(); }),<br />                    new MenuItem("Include titles", (sender, e) =&gt;<br />                                                {<br />                                                    var mi = (MenuItem)sender;<br />                                                    Properties.Settings.Default.IncludeTitles = !mi.Checked;<br />                                                    Properties.Settings.Default.Save();<br />                                                    mi.Checked = Properties.Settings.Default.IncludeTitles;<br />                                                }){ Checked = Properties.Settings.Default.IncludeTitles },<br />                    new MenuItem("-"),<br />                    new MenuItem("Exit", (sender, ee) =&gt; { Application.Exit(); })<br />                });<br />            var notify = new NotifyIcon<br />            {<br />                Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location),<br />                ContextMenu = menu,<br />                Text = "Browser URL clipper",<br />                Visible = true<br />            };<br />            notify.Click += (sender, e) =&gt; { CopyInternetExplorerTabsToClipboard(); };<br /><br />            return notify;<br />        }</pre>
<p>Note that I added a boolean property, IncludeTitles, to the project settings to preserve the user's choice of whether to, er, include titles in the clipped text or not. A left click on the icon will clip all URLs, a right click pops up a menu which offers control of that property, and an application exit option.</p>
<p>Now, it is a bit of a chore to have to move the mouse pointer all the way to the Notification Area, so I added a basic <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms646279.aspx">hotkey handler</a> too. This would have been easier if my application had a main window, but it's only slightly more effort without - I need to install a <a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/system.windows.forms.imessagefilter.aspx">message filter</a>, which gets a chance to peek at all messages sent to the main thread, and traps my hotkey message:</p>
<pre>        private const int HotkeyId = 1196; // Totally arbitrary<br /><br />        private class MessageFilter : IMessageFilter<br />        {<br />            public bool PreFilterMessage(ref Message m)<br />            {<br />                if (m.Msg == 0x0312 /* WM_HOTKEY */ &amp;&amp; m.WParam.ToInt32() == HotkeyId)<br />                {<br />                    CopyInternetExplorerTabsToClipboard();<br />                    return true;<br />                }<br />                return false;<br />            }<br />        }</pre>
<p>With all that in place, all that remains is to register the hotkey, create the notification icon, install the message filter, and run the message pump. When the user exits the application, undo all of that too:</p>
<pre>        [STAThread]<br />        static void Main()<br />        {<br />            RegisterHotKey(IntPtr.Zero, HotkeyId, 6 /* Ctrl + Shift */, 'C');<br />            var notify = CreateNotificationIcon();<br />            var filter = new MessageFilter();<br />            Application.AddMessageFilter(filter);<br /><br />            Application.Run();<br /><br />            Application.RemoveMessageFilter(filter);<br />            notify.Dispose();<br />            UnregisterHotKey(IntPtr.Zero, HotkeyId);<br />        }<br /><br />        [DllImport("user32.dll")]<br />        [return: MarshalAs(UnmanagedType.Bool)]<br />        private static extern bool RegisterHotKey(IntPtr hwnd, int id, int modifiers, uint vk);<br /><br />        [DllImport("user32.dll")]<br />        [return: MarshalAs(UnmanagedType.Bool)]<br />        private static extern bool UnregisterHotKey(IntPtr hwnd, int id);</pre>
<p>I've arbitrarily chosen Ctrl+Shift+C to snapshot URLs - if I wanted to be less lazy, I'd include a configuration option for this, but I'll leave it as an exercise for the reader.</p>
<p>That's it: about 100 lines of code to grab URLs from all current Internet Explorer tabs and drop them in the clipboard. Sometimes .NET programming is very satisfying!</p>]]></content:encoded>
    </item>
    <item>
      <title>NoReplyAll Add-In 3.1</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/noreplyall-add-in-3-1</link>
      <pubDate>Fri, 02 Aug 2013 23:36:03 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/08/02/noreplyall-add-in-3-1/</guid>
      <description><![CDATA[A new release is available today: fixed some resource locking problems, added support for 64 bit...]]></description>
      <content:encoded><![CDATA[<p>A <a title="Download page" href="http://research.microsoft.com/en-us/downloads/60860f41-88ab-4bb4-8104-765feca9cfed/default.aspx">new release</a> is available today: fixed some <a title="Forum post" href="http://social.microsoft.com/Forums/en-US/6c931e06-e348-41ae-bbbd-f9e5bea910bd/noreplyall-2410-save-attachment-on-network-locking-file">resource locking problems</a>, added support for <a title="Previous blog post" href="http://blogs.msdn.com/b/gsmyth/archive/2013/07/12/add-in-for-64-and-32-bit-office.aspx">64 bit Outlook in the installer</a>, and added <a title="Previous blog post" href="http://blogs.msdn.com/b/gsmyth/archive/2013/06/09/talking-to-myself.aspx">self-BCC</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Add-in for 64 and 32 bit Office</title>
      <link>https://docs.microsoft.com/archive/blogs/gsmyth/add-in-for-64-and-32-bit-office</link>
      <pubDate>Fri, 12 Jul 2013 05:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Gavin Smyth]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gsmyth/2013/07/12/add-in-for-64-and-32-bit-office/</guid>
      <description><![CDATA[My NoReplyAll add-in, which I've talked about before, uses absolutely nothing that ties it to 32 or...]]></description>
      <content:encoded><![CDATA[<p>My <a title="Project home page" href="http://research.microsoft.com/en-us/projects/researchdesktop/noreplyall.aspx">NoReplyAll add-in</a>, which I've talked about before, uses absolutely nothing that ties it to 32 or 64 bit Outlook - it's all "anycpu" with no architecture specific dependencies. However, the latest installer <em>is</em>&nbsp;32 bit, with the result that the add-in won't appear in 64 bit Outlook.</p>
<p>This wasn't a problem with a ClickOnce installer but, for reasons explained <a title="Previous post" href="http://blogs.msdn.com/b/gsmyth/archive/2013/01/27/wix-installer-for-vsto-projects.aspx">elsewhere</a>, I wanted to make a MSI based install package, and MSI technology is bit-width specific. One approach is to create both 32 and 64 bit packages, and have a bootstrapper to choose which to run but I want to avoid that because the content of the two packages would be identical, apart from the flags saying whether they were 64 bit or not. It's also totally the wrong thing for another reason: the MSI bitness declares what flavour of the operating system the package is intended for, and says nothing about the bitness of Office. People run 32 bit Office on 64 bit Windows (I do, for example), so I'd really want a 32 bit installer for this setup, not the 64 bit one.</p>
<p>Let's take a brief step back: what does it mean for the installer to be 64 or 32 bit? Pretty much all that happens is when a 64 bit installer runs on a 64 bit OS, or when a 32 bit one runs on a 32 bit OS, the program files directory maps to (typically) "C:\Program Files" and the registry keys such as HKLM\Software\Microsoft map, not too surprisingly, on to HKLM\Software\Microsoft. However, if you run a 32 bit MSI on a 64 bit OS, program files is mapped to "C:\Program Files <strong>(x86)</strong>" and that registry key will be sent to HKLM\Software\<strong>Wow6432Node\</strong>Microsoft - this all happens automatically via "<a title="MSDN page" href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384235.aspx">registry reflection</a>." I'm sure there are a few other differences too, but they're not important here. What's more, there's no way (within Windows Installer technology), as far as I'm aware, for a 32 bit MSI package to reach out to the non-redirected parts of the filing system or registry without writing extra code. (For completeness, there's no similar mapping when running a 64 bit installer on a 32 bit OS - primarily because you just can't install 64 bit MSIs on 32 bit Windows!)</p>
<p>Now, the directory in which I place the add-in bits is irrelevant, but the registry is significant... By releasing a 32 bit installer, I was placing the registry stuff under HKLM\Software\Wow6432Node\Microsoft\Office\Outlook on a 64 bit version of Windows - and this so happens to be where 32 bit Outlook looks for its add-ins. People running 64 bit Office would see no add-in because it's looking under HKLM\Software\Microsoft\Office\Outlook. (And the reason that there's no problem with ClickOnce is that it adds the registry settings under HKCU, which doesn't have this redirection and is visible to both 32 and 64 bit Outlook.)</p>
<p>I did consider looking to see what bitness of Office is installed and trying to modify the appropriate part of the registry, but decided against that because I wouldn't want the add-in to "vanish" were someone to uninstall their 32 bit Outlook and then install 64 bit (or vice versa). Instead, I decided that I would always install in the 32 bit friendly location but, on 64 bit Windows, also copy the registry settings "up" as part of the install process. Now, 32 bit applications can't (easily) see the 64 bit parts of the registry because of the automatic redirection, but 64 bit executables get to see everything, so I considered writing a small executable which would run post-install to copy the contents of the appropriate registry key, and also delete it on uninstall. However, then I stumbled across the <a title="TechNet documentation" href="http://technet.microsoft.com/en-us/library/bb490984.aspx">REG</a> command - which does allow access to the whole registry without me having to write anything more than a command line! In particular, it can copy the contents of one registry key to another, so I can let Windows Installer deal with the 32 bit part of the registry (in a 32 bit installer) as normal, and then use REG to copy what was placed there into the equivalent 64 bit location.</p>
<p>I made the following additions to the WiX Product.wxs file:</p>
<pre>    &lt;Property Id="CopyReg64Key" Value='"REG.EXE" COPY "HKLM\Software\WoW6432Node\Microsoft\Office\Outlook\Addins\NoReplyAll" "HKLM\Software\Microsoft\Office\Outlook\Addins\NoReplyAll" /s /f /reg:64' /&gt;<br />    &lt;CustomAction Id="CopyReg64Key" Execute="deferred" Return="ignore" Impersonate="no" BinaryKey="WixCA" DllEntry="CAQuietExec" /&gt;<br /><br />    &lt;Property Id="DeleteReg64Key" Value='"REG.EXE" DELETE "HKLM\Software\Microsoft\Office\Outlook\Addins\NoReplyAll" /f /reg:64' /&gt;<br />    &lt;CustomAction Id="DeleteReg64Key" Execute="deferred" Return="ignore" Impersonate="no" BinaryKey="WixCA" DllEntry="CAQuietExec" /&gt;</pre>
<pre>    &lt;InstallExecuteSequence&gt;<br />      &lt;Custom Action="CopyReg64Key" Before="InstallFinalize"&gt;<br />        &lt;![CDATA[$CMP_VstoManifest=3]]&gt;<br />      &lt;/Custom&gt;<br />      &lt;Custom Action="DeleteReg64Key" Before="RemoveFiles"&gt;<br />        &lt;![CDATA[$CMP_VstoManifest=2]]&gt;<br />      &lt;/Custom&gt;<br />    &lt;/InstallExecuteSequence&gt;</pre>
<p>The first pair of lines defines a custom action which copies the 32 bit registry entries to the "same place" in the 64 bit part. This will fail silently on a 32 bit operating system, which is fine. Unfortunately it will also fail on Windows XP, since the reg.exe that that comes with doesn't recognise the /reg:64 command line option, but I don't expect that to affect very many people. This is using the WiX <a title="WiX documentation" href="http://wix.sourceforge.net/manual-wix3/qtexec.htm">quiet execution</a> extension, which lets me invoke a command line <em>without</em>&nbsp;showing a console window - the simpler custom action shown below would cause a brief console flash when it executes:</p>
<pre>&lt;CustomAction Id="CopyReg64Key" Execute="deferred" Return="ignore" Impersonate="no" Directory="INSTALLFOLDER"<br />              ExeCommand='REG COPY "HKLM\Software\WoW6432Node\Microsoft\Office\Outlook\Addins\NoReplyAll" "HKLM\Software\Microsoft\Office\Outlook\Addins\NoReplyAll" /s /f /reg:64' /&gt;</pre>
<p>The next pair of lines deletes the extra registry setting. On a 32 bit OS, this would delete the same values as the "normal" registry manipulation, so that's OK too. And the final bunch of lines cause the first custom action to be executed near the end of the install sequence and uninstall sequence as appropriate.</p>
<p>With all this in place, the bulk of the installer runs as before, updating the 32 bit parts of the registry. After all that, the custom actions fiddle with the 64 bit part of the registry, and we're done.</p>
<p>Look out for this in the next version of the add-in to be published...</p>]]></content:encoded>
    </item>
  </channel>
</rss>