<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>pinvoke &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/pinvoke/</link>
	<description>Feed of posts on WordPress.com tagged "pinvoke"</description>
	<pubDate>Thu, 24 Dec 2009 10:55:04 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[PInvoke: Getting all child handles of window]]></title>
<link>http://blog.ralch.com/2009/12/05/pinvoke-getting-all-child-handles-of-window/</link>
<pubDate>Sat, 05 Dec 2009 07:42:21 +0000</pubDate>
<dc:creator>Svetlin Ralchev</dc:creator>
<guid>http://blog.ralch.com/2009/12/05/pinvoke-getting-all-child-handles-of-window/</guid>
<description><![CDATA[If you don&#8217;t know I have a new job in Bulgaria. I went away form Web Development and now I]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>If you don&#8217;t know I have a new job in Bulgaria. I went away form Web Development and now I&#8217;m working as Winforms Developer. However, we had a client that exceed the number of window handles (more than 10 000) due to bad design of application. While diagnosing his application, we needed to understand how many handles are created and when they are born. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Reading MSDN I figure out that Windows API provide the availability to get all child handles for specified handle. We should use unmanaged <em>EnumChildWindows</em><strong> </strong>function provided by user32.dll.</p>
<p><strong>MSDN Definition</strong></p>
<p><em>EnumChildWindows</em> function enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. <em>EnumChildWindows</em> continues until the last child window is enumerated or the callback function returns FALSE.</p>
<p><strong>Syntax</strong></p>
<p>BOOL EnumChildWindows(    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HWND hWndParent,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; WNDENUMPROC lpEnumFunc,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LPARAM lParam     <br />);</p>
<dl>
<dt><em>hWndParent</em> </dt>
<dt>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [in] Handle to the parent window whose child windows are to be enumerated.<strong> </strong></dt>
<dt><em>lpEnumFunc</em> </dt>
<dd>[in] Pointer to an application-defined callback function. </dd>
<dt><em>lParam</em> </dt>
<dd>[in] Specifies an application-defined value to be passed to the callback function. </dd>
</dl>
<p><strong>Note:</strong> If a child window has created child windows of its own, <em>EnumChildWindows</em> enumerates those windows as well.</p>
<p><strong>How is used from .NET Framework</strong></p>
<div style="font-family:lucida console;background:white;color:black;font-size:8pt;">
<p style="margin:0;"><span style="color:blue;">public</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">WindowHandleInfo</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">delegate</span> <span style="color:blue;">bool</span> <span style="color:#2b91af;">EnumWindowProc</span>(<span style="color:#2b91af;">IntPtr</span> hwnd, <span style="color:#2b91af;">IntPtr</span> lParam);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; [<span style="color:#2b91af;">DllImport</span>(<span style="color:#a31515;">&#34;user32&#34;</span>)]</p>
<p style="margin:0;">&#160;&#160;&#160; [<span style="color:blue;">return</span>: <span style="color:#2b91af;">MarshalAs</span>(<span style="color:#2b91af;">UnmanagedType</span>.Bool)]</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">bool</span> EnumChildWindows(<span style="color:#2b91af;">IntPtr</span> window, <span style="color:#2b91af;">EnumWindowProc</span> callback, <span style="color:#2b91af;">IntPtr</span> lParam);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:#2b91af;">IntPtr</span> _MainHandle;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">public</span> WindowHandleInfo(<span style="color:#2b91af;">IntPtr</span> handle)</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>._MainHandle = handle;</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:#2b91af;">List</span>&#60;<span style="color:#2b91af;">IntPtr</span>&#62; GetAllChildHandles()</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&#60;<span style="color:#2b91af;">IntPtr</span>&#62; childHandles = <span style="color:blue;">new</span> <span style="color:#2b91af;">List</span>&#60;<span style="color:#2b91af;">IntPtr</span>&#62;();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">GCHandle</span> gcChildhandlesList = <span style="color:#2b91af;">GCHandle</span>.Alloc(childHandles);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">IntPtr</span> pointerChildHandlesList = <span style="color:#2b91af;">GCHandle</span>.ToIntPtr(gcChildhandlesList);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">try</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">EnumWindowProc</span> childProc = <span style="color:blue;">new</span> <span style="color:#2b91af;">EnumWindowProc</span>(EnumWindow);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EnumChildWindows(<span style="color:blue;">this</span>._MainHandle, childProc, pointerChildHandlesList);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">finally</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; gcChildhandlesList.Free();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">return</span> childHandles;</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">bool</span> EnumWindow(<span style="color:#2b91af;">IntPtr</span> hWnd, <span style="color:#2b91af;">IntPtr</span> lParam)</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">GCHandle</span> gcChildhandlesList = <span style="color:#2b91af;">GCHandle</span>.FromIntPtr(lParam);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (gcChildhandlesList == <span style="color:blue;">null</span> &#124;&#124; gcChildhandlesList.Target == <span style="color:blue;">null</span>)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">return</span> <span style="color:blue;">false</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&#60;<span style="color:#2b91af;">IntPtr</span>&#62; childHandles = gcChildhandlesList.Target <span style="color:blue;">as</span> <span style="color:#2b91af;">List</span>&#60;<span style="color:#2b91af;">IntPtr</span>&#62;;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; childHandles.Add(hWnd);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">return</span> <span style="color:blue;">true</span>;</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">}</p>
</p></div>
<p><strong></strong></p>
<p>We are using <em>DLLImport</em> attribute to expose the method in .NET Environment. The specific point is that we create a handle to the list where are collected all pointers, due to availability to access it from the callback function where we know which is the child handle.</p>
<p><strong>References</strong></p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms633494%28VS.85%29.aspx" target="_blank">MSDN</a> </li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Link a DLL a basso livello]]></title>
<link>http://dotnetlore.wordpress.com/2009/10/23/link-a-dll-a-basso-livello/</link>
<pubDate>Fri, 23 Oct 2009 19:04:41 +0000</pubDate>
<dc:creator>xmaverick</dc:creator>
<guid>http://dotnetlore.wordpress.com/2009/10/23/link-a-dll-a-basso-livello/</guid>
<description><![CDATA[Sebbene il C# possa essere utilizzato in modalità nativa (unmanaged), viene ormai visto solo e unica]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Sebbene il C# possa essere utilizzato in modalità nativa (unmanaged), viene ormai visto solo e unicamente come un linguaggio ad alto livello, è invece possibile utilizzarlo come ponte per il basso livello e la nostra applicazione. In questo modo, devo essere sincero, si dovranno gestire i problemi di entrambi i mondi, ma sarà possibile ottenere un controllo della macchina che è normalmente non possibile rimanendo nel dominio delle funzionalità managed.</p>
<p>Tutti sappiamo che il Framework .NET altro non è che un enorme conca di sabbia, dentro cui girano i nostri applicativi, del tutto ignari delle problematiche che un qualunque software dovrebbe gestire internamente, come l&#8217;allocazione della memoria e la richiesta e il rilascio delle risorse hardware. Abbiamo un applicativo che viene compilato in metaassembly CLR, e poi eseguito dalla macchina virtuale del .NET, particolarmente ottimizzata per le architetture moderne e non avente i vincoli che invece ha una JVM. Proprio perchè non esistono questi vincoli, .NET può chiamare funzioni esterne e allocare memoria sullo heap. In questo modo, può dialogare con il mondo esterno di Windows senza crearsi troppi problemi e estendendo le sue funzionalità anche a quelle non coperte dal Framework rilasciato da casa MS. L&#8217;inconveniente però è che il codice scritto in questa maniera viene marcato con i fuochi del P/INVOKE (Platform Invoke, ovvero tutto il dominio .NET che serve a invocare codice nativo per la piattaforma selezionata), e quindi non potremo ad esempio utilizzare la nostra applicazione in Mono.</p>
<p>L&#8217;argomento è esteso, quindi per oggi mi limiterò a trattare solo e unicamente quello che ho scritto nel titolo, ovvero l&#8217;invocazione di API C direttamente dal C#</p>
<p>Innanzitutto, per poter essere utilizzate in C#, le funzioni C devono essere scritte utilizzando lo standard di compilazione <strong>stdcall</strong>, come da standard Microsoft. Anche le API di Windows sono esposte utilizzando lo standard stdcall.</p>
<p>Ma prima un piccolo passo indietro. Quando a basso livello si parla di &#8220;richiamare una funzione&#8221;, semplicemente vengono fatte le seguenti operazioni:</p>
<ol>
<li>Viene memorizzato l&#8217;indirizzo del prossimo opcode della funzione chiamate nello stack</li>
<li>Vengono memorizzati a uno a uno i parametri da passare alla funzione da chiamare nello stack</li>
<li>Viene effettuato il jump alla funzione da chiamare</li>
</ol>
<p>Questa poi effettuerà le seguenti operazioni:</p>
<ol>
<li>Leggerà gli argomenti dallo stack</li>
<li>Eseguirà le sue operazioni</li>
<li>Leggerà il punto delle istruzioni dove ritornare una volta terminato</li>
<li>Scriverà sullo stack il valore di ritorno</li>
<li>Effettuerà il jump sul punto di istruzioni letto (ovvero l&#8217;istruzione successiva al salto nella funzione chiamante)</li>
</ol>
<p>Quando si parla di scrivere sullo stack, si usa l&#8217;istruzione assembly PUSH, quando si legge l&#8217;istruzione POP. Ricordo che lo stack è una pila, quindi un POP leggerà sempre l&#8217;ultimo valore immesso (e lo toglierà dalla pila), mentre un PUSH verrà sempre impilato sopra gli altri.</p>
<p>Questa divagazione è importante perchè nello standard di chiamata stdcall gli argomenti di una funzione vengono inseriti nello stack da destra verso sinistra (l&#8217;ultimo per primo) e i valori di ritorno, invece di essere inseriti nello stack, vengono tenuti nel registro EAX. Il chiamante è respostabile della pulitura dello stack.</p>
<p>(Per maggiori informazioni: <a href="http://en.wikipedia.org/wiki/X86_calling_conventions#stdcall">http://en.wikipedia.org/wiki/X86_calling_conventions#stdcall</a>)</p>
<p>Ipotizziamo di voler aprire un file utilizzando non File.Open(), ma una API di Win32. La API in questione è CreateFile e il prototipo è questo:</p>
<pre class="brush: cpp;"> 

HANDLE WINAPI CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
</pre>
</pre>
<p>Non ci tratteniamo sul significato dei parametri, anche perchè su MSDN possiamo trovare la pagina di aiuto completa:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx">http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx</a></p>
<p>Adesso, per poterlo importare in C#, dobbiamo inanzitutto:</p>
<ol>
<li>Conoscere il nome della DLL che contiene la funzione che ci interessa. La funzione deve essere esposta. Nel caso di CreateFile, la DLL è Kernel32.dll</li>
<li>Essere sicuri che il nome sia giusto. Ad esempio, nel caso di CreateFile, nella DLL esistono due funzioni, CreateFileA e CreateFileW, rispettivamente la versione ANSI e la versione UNICODE. Usando la chiamata in C, il compilatore si prende la briga di selezionare quella più giusta per il sistema su cui stiamo compilando il sorgente (per WinNTè UNICODE, come definito in windows.h). Nel caso nostro, o definiamo una flag per la selezione del charset, o dovremo scegliere quella più opportuna manualmente.</li>
<li>Essere sicuri che la DLL sia raggiungibile. La DLL deve essere o nel path dell'eseguibile, o nel path della macchina (ovvero anche nelle cartelle di sistema).</li>
<li>Creare una classe che contenga la definizione della funzione. La funzione deve essere dichiarata extern static.</li>
</ol>
<p>Ecco quindi come diventerà CreateFile per noi, utilizzando la flag di charset per definire l'Unicode:</p>
<pre class="brush: csharp;"> 

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

public class TestCLinking
{
    [DllImport(&#34;kernel32.dll&#34;, SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr pSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
}
</pre>
</pre>
<p>oppure, se vogliamo richiamare manualmente la versione ansi:</p>
<pre class="brush: csharp;"> 

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

public class TestCLinking
{
    [DllImport(&#34;kernel32.dll&#34;, SetLastError = true)]
    public static extern SafeFileHandle CreateFileA(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode, IntPtr pSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
}
</pre>
</pre>
<p>La struttura SafeFileHandle è un puntatore alla memoria appositamente wrappato dal .NET per l'utilizzo con operazioni di accesso ai files. Espone delle proprietà e dei distruttori atti ad assicurare che la risorsa di file sia restituita al sistema operativo. Il link diretto MSDN è: <a href="http://msdn.microsoft.com/it-it/library/microsoft.win32.safehandles.safefilehandle.aspx">http://msdn.microsoft.com/it-it/library/microsoft.win32.safehandles.safefilehandle.aspx</a></p>
<p>IntPtr è invece una classe che definisce un puntatore a un area di memoria (formato Int 32 bit). E' equivalente a mettere un operatore star davanti a un tipo C. Unica differenza, il controllo di un puntatore C# a null va fatto come:</p>
<pre class="brush: csharp;">

IntPtr a;

[ops]

if (a == IntPtr.Zero) { è a null }
</pre>
<p>Con questa semplice classe, passando i valori corretti, potremo aprire un file senza passare per il .NET, ma richiedendolo direttamente al sistema operativo. Immaginate di scrivere la vostra classe C, magari, che so, per comunicare con un microcontrollore mediante la porta COM e protocollo MODBUS (<a href="http://en.wikipedia.org/wiki/Modbus">http://en.wikipedia.org/wiki/Modbus</a>). Immaginate che sia estremamente performante, ma che adesso si presenti un piccolo problema: scrivere una GUI interamente in C può essere massacrante in termini di lavoro e tempo. Allora che si fa? Si scrive la GUI in .NET,e  si passa tutta la logica di controllo alla classe C. Facile e veloce.</p>
<p>La chiamata viene effettuata come un qualunque metodo static.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Calling native Win32 DLLs in C# with P/Invoke]]></title>
<link>http://hacktheugly.wordpress.com/2009/09/17/pinvoking-native-win32-dlls-in-csharp/</link>
<pubDate>Thu, 17 Sep 2009 23:45:24 +0000</pubDate>
<dc:creator>Gopal</dc:creator>
<guid>http://hacktheugly.wordpress.com/2009/09/17/pinvoking-native-win32-dlls-in-csharp/</guid>
<description><![CDATA[Calling an unmanaged Win32 DLL (Dynamic Linked Library) via a managed programming language is a hard]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Calling an unmanaged Win32 DLL (Dynamic Linked Library) via a managed programming language is a hard task. But I have found an easy lesson for beginner-intermediate C# programmer to learn how to call Win32 DLLs using P/Invoke. By calling a native Win32 DLL you can do advanced tasks in C#. The article is a very long so I have included the link to the article in the MSDN Library below.</p>
<p><img class="alignnone" src="http://codelog.blogial.com/files/pinvoke.jpg" alt="" width="557" height="204" /></p>
<p><a href="http://msdn.microsoft.com/en-us/magazine/cc164123.aspx">http://msdn.microsoft.com/en-us/magazine/cc164123.aspx</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[P/Invoke the easy way]]></title>
<link>http://y371.wordpress.com/2009/09/13/pinvoke-the-easy-way/</link>
<pubDate>Sun, 13 Sep 2009 06:30:00 +0000</pubDate>
<dc:creator>Yeti</dc:creator>
<guid>http://y371.wordpress.com/2009/09/13/pinvoke-the-easy-way/</guid>
<description><![CDATA[pinvoke.net: the interop wiki! A wiki for .NET developers PInvoke.net is primarily a wiki, allowing ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://pinvoke.net/">pinvoke.net: the interop wiki!</a><br />
<blockquote>A wiki for .NET developers</p>
<p>PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke* signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs from managed code (written in languages such as C# or VB.NET).</p>
<p>.NET developers worldwide can easily contribute to the community, sharing their valuable knowledge, whenever they have time to do so.</p>
</blockquote>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=6a716384-a74e-8826-878b-e556bee7a929" /></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[P/Invoke the easy way]]></title>
<link>http://y371de.wordpress.com/2009/09/13/pinvoke-the-easy-way/</link>
<pubDate>Sun, 13 Sep 2009 06:30:00 +0000</pubDate>
<dc:creator>Yeti</dc:creator>
<guid>http://y371de.wordpress.com/2009/09/13/pinvoke-the-easy-way/</guid>
<description><![CDATA[Das hier habe ich langelange gesucht: (und einen Teil der dort archivierten Schnippets auch schon se]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><big>Das hier habe ich langelange gesucht:</p>
<p></big>(und einen Teil der dort archivierten Schnippets auch schon selbst fabriziert)</p>
<p><a href="http://pinvoke.net/">pinvoke.net: the interop wiki!</a><br />
<blockquote>A wiki for .NET developers</p>
<p>PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke* signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs from managed code (written in languages such as C# or VB.NET).</p>
<p>.NET developers worldwide can easily contribute to the community, sharing their valuable knowledge, whenever they have time to do so.</p>
</blockquote>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=b9abe0fa-2a6e-8b0a-a1de-59b07fde6b0c" /></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Explicit P/Invoke: Memory management for return types and ref parameters]]></title>
<link>http://aonprog.wordpress.com/2009/09/06/explicit-pinvoke-callbacks-and-memory-management/</link>
<pubDate>Sun, 06 Sep 2009 12:43:26 +0000</pubDate>
<dc:creator>radiantway</dc:creator>
<guid>http://aonprog.wordpress.com/2009/09/06/explicit-pinvoke-callbacks-and-memory-management/</guid>
<description><![CDATA[In one of my recent assignments at work I was to communicate with native code from my C# application]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In one of my recent assignments at work I was to communicate with native code from my C# application. Micros0ft provides two kinds of platform invoke functionality i.e.</p>
<p>Implicit p/invoke: This is supported by VC++ only so managed C++ can call unmanaged code.</p>
<p>Explicit p/invoke: This is supported by .NET platform and any code written in C# or VB.NET can execute native code and vice versa.</p>
<p>Other than these, if native code is implemented as COM servers, .NET runtime provides COM Callable Wrappers to communicate with the managed code. Similarly it provides Runtime Callable Wrappers where managed code is exposed as COM objects for native code to communicate with the managed code.</p>
<p>In this article my focus will be on explicit p/invoke providing callback functionality and related memory issues.</p>
<p>To call unmanaged code from managed is pretty straight forward. All you have to do is to export the functions in the DLL. Then provide the declaration matching exact signature with Dllimport attribute and if custom structures or classes are being used as parameters provide their definition as well in the managed code.</p>
<p>For example if some dll Example.dll exports a function &#8220;int nStatus GetUpdate(char* strParam)&#8221;. To call this funciton in your .NET application declare it as follows</p>
<p><code>[Dllimport("Path\\Example.dll")]</p>
<p>public extern static int GetUpdate(MarshalAs(UnmanagedType.LPStr)] string strParam);</code></p>
<p>Then call it as follows</p>
<p><code>string strParam = "test data";</p>
<p>int iStatus = GetUpdate(strParam);</code></p>
<p>The native code would look like</p>
<p><code>int GetUpdate(char* strParam)</p>
<p>{</p>
<p>//Do some processing on strParam here...</p>
<p>// calculate status and return</p>
<p>return nStatus;</p>
<p>}</code></p>
<p>Lets involve custom structures first as value parameters and later on as ref parameter so that native application will allocate memory and managed code will consume.</p>
<p><code>[StructLayout(LayoutKind.Sequential)]<br />
    struct BridgeMember<br />
    {<br />
        public int nMember;<br />
        [MarshalAs(UnmanagedType.LPStr)]<br />
        public string strMember;<br />
    }<br />
    [StructLayout(LayoutKind.Sequential)]<br />
    struct BridgeData<br />
    {<br />
        public int nData;<br />
        public uint dwData;<br />
        [MarshalAs(UnmanagedType.LPStr)]<br />
        public string strData;<br />
        public eType eData;<br />
        public BridgeMember BMData;<br />
    }<br />
    enum eType { one = 1, two };</p>
<p>[DllImport(@"path\Example.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]<br />
public static extern int ProcessObjectByVal(BridgeData BInData);</code></p>
<p>Use it as follows<br />
<code>BridgeData oBridgeData = new BridgeData();<br />
oBridgeData.BMData.nMember = 10;<br />
oBridgeData.BMData.strMember = "From C# assembly";<br />
oBridgeData.dwData = 20;<br />
oBridgeData.eData = eType.one;<br />
oBridgeData.nData = 30;<br />
oBridgeData.strData = "From C#";</p>
<p>int n = ProcessObjectByVal(oBridgeData);</code></p>
<p>The native code will include the definitions of the structures exactly as above and the ProcessObjectByVal() will look like as follows</p>
<p><code><br />
int ProcessObjectByVal(BridgeData BInData)<br />
{<br />
	//get values from BInData and process...<br />
        return iSomeStatus;<br />
}<br />
</code></p>
<p>Now if we want to pass BridgeData as ref or out parameter, for strings allocations has to be done using COM memory functions such as CoTaskMemAlloc. Because .NET runtime expect native code to allocate memory using CoTaskMemAlloc and it frees the pointers using CoTaskMemFree. If memory is allocated using other functions like new or malloc; the memory will not be freed or worse crash can occur as .NET runtime will try to free it using CoTaskMemFree in any case.<br />
For details please <a href="http://msdn.microsoft.com/en-us/library/f1cf4kkz.aspx">this article</a> on MSDN.<br />
Following example illustrate the correct use of memory functions for p/invoke.<br />
<strong>Native Code:</strong><br />
<code><br />
int ProcessObjectByRef(BridgeData* pBOutData)<br />
{<br />
	pBOutData-&#62;BMData.nMember = 1;<br />
	int size = 400;<br />
        //pBOutData-&#62;BMData.strMember = new char[size]; //who will free it? using coTaskMemAlloc will fix this leak<br />
	pBOutData-&#62;BMData.strMember = (char*)CoTaskMemAlloc(size);<br />
	memset(pBOutData-&#62;BMData.strMember,0,size);<br />
	strcpy_s(pBOutData-&#62;BMData.strMember,size,"This is medium string");<br />
	pBOutData-&#62;dwData = 55;<br />
	pBOutData-&#62;eData  = two;<br />
	pBOutData-&#62;nData  = 14;<br />
	pBOutData-&#62;strData = (char*)CoTaskMemAlloc(20); //who will free it? will using coTaskMemAlloc fix this leak?<br />
	memset(pBOutData-&#62;strData,0,20);<br />
	strcpy_s(pBOutData-&#62;strData,20,"small string");<br />
	return pBOutData-&#62;nData;<br />
}<br />
</code></p>
<p><strong>Managed code:</strong><br />
<code><br />
[DllImport(@"path\Example.dll", ExactSpelling = true, CharSet = CharSet.Ansi)]<br />
public static extern int ProcessObjectByRef(out BridgeData BInData);</p>
<p>BridgeData oBridgeDataOut;<br />
n = ProcessObjectByRef(out oBridgeDataOut);<br />
//use oBridgeDataOut here...<br />
</code> </p>
<p>We just discussed out to process objects by ref where native code will allocate memory as required instead of passing String or StringBuilder with pre-allocated memory which might not be a good option for all cases where data is created by native application.</p>
<p>In the above example if IntPtr is used in place of attributed string, the managed code has to de-allocate the memory itself rather than relying on the Runtime for example</p>
<p><code>IntPtr IntPtrData;<br />
String strData = Marshal.PtrToStringAuto(IntPtrData);<br />
Marshal.FreeCoTaskMem(IntPtrData);</code></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Configuring bluetooth GPS receiver on virtual COM port with GPS Intermediate Driver]]></title>
<link>http://blog.aksam.it/2009/07/30/configuring-bluetooth-gps-receiver-on-virtual-com-port-with-gps-intermediate-driver/</link>
<pubDate>Thu, 30 Jul 2009 20:02:28 +0000</pubDate>
<dc:creator>Grzegorz Aksamit</dc:creator>
<guid>http://blog.aksam.it/2009/07/30/configuring-bluetooth-gps-receiver-on-virtual-com-port-with-gps-intermediate-driver/</guid>
<description><![CDATA[On various forums people report problems with programmatically assigning a virtual COM port to Bluet]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>On various forums people report problems with programmatically assigning a virtual COM port to Bluetooth GPS receivers. It seems especially hard for developers to configure the virtual COM port without the need to reboot the phone.</p>
<p>Below are my C# code snippets that I managed to write. The code still references some functions which I haven&#8217;t pasted, but you should be able to analyze it without them.</p>
<p>Here&#8217;s how it works:</p>
<ol>
<li>Use BluetoothClient.DiscoverDevices() from 32feet to find bluetooth devices in range</li>
<li>Let your user choose one &#8211; (lbDevices.SelectedValue in my code)</li>
<li>Check if the selected device already has COM port configured (lines 9-17 in first code snippet)</li>
<li>Let your user choose COM port and baud rate (that&#8217;s what GPSBluetoothSerialPortForm)</li>
<li>If the bluetooth GPS device is not paired yet, do it with BluetoothSecurity.PairRequest</li>
<li>Configure the COM port in the registry (HKLM\Software\Microsoft\Bluetooth\Serial\Ports (GPSConfig.SetBluetoothPortName() does that)</li>
<li>This is the key part if you don&#8217;t want to reboot the phone: call RegisterDevice() to notify the btd.dll driver about new COM port (GPSConfig.SetBluetoothPortName())</li>
</ol>
<p>Now, you can open the COM port directly and read the NMEA sentences from it. However, if you want a few applications to share the GPS receiver, you should use it through the GPS Intermediate Driver.</p>
<p>There are three things to set in the GPS ID:</p>
<ol>
<li>GPS ID hardware port (IntermediateDriver.SetExternalInPort())</li>
<li>GPS ID hardware port baud rate (IntermediateDriver.SetExternalInPortBaudRate())</li>
<li>GPS ID software port, if it&#8217;s not set (IntermediateDriver.GetOutPort() and IntermediateDriver.SetOutPort())</li>
<li>enable GPS ID (IntermediateDriver.EnableIntermediateDriver())</li>
<li>notice GPS ID about new config, so it reloads it (IntermediateDriver.Update())</li>
</ol>
<p>All the GPS Intermediate Driver config is done through the system registry (HKLM\System\CurrentControlSet\GPS Intermediate Driver\). To make the GPS ID reload configuration, you have to open the GPD0 device with CreateFileW() and call the DeviceIoControl() with IOCTL_SERVICE_REFRESH parameter. I didn&#8217;t paste the code here, but I think I&#8217;ll write another blog post about it later.</p>
<p>Here&#8217;s the main part of the code:</p>
<pre class="brush: csharp;">
        private void btDalej_Click(object sender, EventArgs e)
        {
            BluetoothDeviceInfo bdi = (BluetoothDeviceInfo)lbDevices.SelectedValue;
            bool has_serial_port = false;
            string serial_port = string.Empty;

            Guid[] services = bdi.InstalledServices;

            foreach (Guid serv in services)
            {
                if (serv == BluetoothService.SerialPort)
                {
                    has_serial_port = true;
                    serial_port = GPSConfig.GetBluetoothPortName(bdi.DeviceAddress);
                    break;
                }
            }

            using (GPSBluetoothSerialPortForm portform = new GPSBluetoothSerialPortForm(has_serial_port, serial_port))
            {
                portform.Owner = this;
                if (portform.ShowDialog() == DialogResult.OK)
                {
                    Application.DoEvents();

                    Cursor.Current = Cursors.WaitCursor;
                    string SelectedPort = (string)portform.cbPortName.SelectedItem;
                    string PinValue = (string)portform.tbPin.Text;
                    int SelectedBaudRate = (int)portform.cbBaud.SelectedItem;

                    // 1. setup selected COM port for bluetooth device
                    if (bdi.Authenticated == false)
                    {
                        bool ret = BluetoothSecurity.PairRequest(bdi.DeviceAddress, PinValue);
                        if (ret == false)
                        {
                            Cursor.Current = Cursors.Default;
                            MessageBox.Show(&quot;Connection to selected bluetooth device failed. If your GPS receiver was turned off, turn it on and try again, or try other device&quot;);
                            return;
                        }
                    }

                    if (GPSConfig.SetBluetoothPortName(bdi.DeviceAddress, SelectedPort) == false)
                    {
                        Cursor.Current = Cursors.Default;
                        MessageBox.Show(&quot;Failed to open selected COM port. Choose other COM port or restart your phone and try again&quot;);
                        return;
                    }

                    // 2. set selected COM port as GPS Intermediate Driver Hardware port
                    IntermediateDriver.SetExternalInPort(SelectedPort);
                    IntermediateDriver.SetExternalInPortBaudRate(SelectedBaudRate);

                    string GPSIDOutPort = IntermediateDriver.GetOutPort();
                    if (GPSIDOutPort == null &amp;#124;&amp;#124; GPSIDOutPort.Length == 0)
                    {
                        // there is no software COM port set in GPS Intermediate Driver

                        // choose first free COM port
                        GPSIDOutPort = GPSConfig.GetFreeGPSIDPort();
                        if (GPSIDOutPort == null &amp;#124;&amp;#124; GPSIDOutPort.Length == 0)
                        {
                            MessageBox.Show(&quot;Can't find free COM port. GPS configuration failed&quot;, &quot;Error&quot;, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                            Cursor.Current = Cursors.Default;
                            DialogResult = DialogResult.Cancel;
                            Close();
                        }

                        IntermediateDriver.SetOutPort(GPSIDOutPort);
                    }
                    IntermediateDriver.EnableIntermediateDriver();
                    IntermediateDriver.Update();

                    // 3. save configuration settings
                    Program.cfg.GPSPortName = IntermediateDriver.GetOutPort();
                    Program.cfg.GPSBaudRate = SelectedBaudRate;

                    Cursor.Current = Cursors.Default;
                    DialogResult = DialogResult.OK;
                    Close();
                }
            }
        }
</pre>
<p><code>GPSConfig.GetBluetoothPortName(...)</code> and <code>GPSConfig.SetBluetoothPortName(...)</code> code</p>
<pre class="brush: csharp;">
        public static string GetBluetoothPortName(BluetoothAddress deviceaddress)
        {
            string portname = string.Empty;
            long l_deviceaddress = deviceaddress.ToInt64();

            using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(@&quot;\Software\Microsoft\Bluetooth\Serial\Ports&quot;))
            {
                foreach (string s_address in rk.GetSubKeyNames())
                {
                    long address = long.Parse(s_address, System.Globalization.NumberStyles.AllowHexSpecifier);

                    if (address == l_deviceaddress)
                    {
                        using (RegistryKey thisrk = rk.OpenSubKey(s_address))
                        {
                            portname = (string)thisrk.GetValue(&quot;Port&quot;, string.Empty);
                        }
                        break;
                    }
                }
            }

            return portname.TrimEnd(new char[] { '', '\n', '\r' });
        }

        public static bool SetBluetoothPortName(BluetoothAddress deviceaddress, string portname)
        {
            if (portname == null)
                return false;   

            string strDeviceAddress = deviceaddress.ToString(&quot;8&quot;);

            using (RegistryKey rkPorts = Registry.LocalMachine.OpenSubKey(@&quot;SOFTWARE\Microsoft\Bluetooth\Serial\Ports&quot;, true))
            {
                RegistryKey rkNewPort;

                rkNewPort = rkPorts.OpenSubKey(strDeviceAddress, true);
                if (rkNewPort == null)
                {
                    rkNewPort = rkPorts.CreateSubKey(strDeviceAddress);

                    if (rkNewPort == null)
                    {
                        return false;
                    }
                }
                else
                {
                    // deregister for old port
                    string oldPort = ((string)rkNewPort.GetValue(&quot;Port&quot;, null)).Trim('');
                    if (oldPort != null)
                        DeregisterDevice(oldPort);
                }

                rkNewPort.SetValue(&quot;KeepDCB&quot;, 0);
                rkNewPort.SetValue(&quot;RemoteDCB&quot;, 0);
                rkNewPort.SetValue(&quot;Encryption&quot;, 0);
                rkNewPort.SetValue(&quot;Authentication&quot;, 0);
                rkNewPort.SetValue(&quot;Port&quot;, portname);
                rkNewPort.SetValue(&quot;Server&quot;, 0);

                rkNewPort.Close();
                rkNewPort = null;

                PORTEMUPortParams pep = new PORTEMUPortParams();
                pep.uiportflags = RFCOMM_PORT_FLAGS.REMOTE_DCB;
                pep.flocal = false;
                pep.device = deviceaddress.ToInt64();
                pep.uuidService = BluetoothService.SerialPort;

                string portprefix = portname.Substring(0, 3);
                int portindex = int.Parse(portname[3].ToString());

                IntPtr handle = RegisterDevice(portprefix, portindex, &quot;btd.dll&quot;, ref pep);
                if (handle == IntPtr.Zero)
                {
                    rkPorts.DeleteSubKeyTree(strDeviceAddress);

                    return false;
                }
            }

            return true;
        }
</pre>
<p>&#8230; and the pinvokes</p>
<pre class="brush: csharp;">
    [DllImport(&quot;coredll.dll&quot;, SetLastError = true)]
    private static extern IntPtr RegisterDevice(
        string lpszType,
        int dwIndex,
        string lpszLib,
        ref PORTEMUPortParams dwInfo);

    [StructLayout(LayoutKind.Sequential)]
    internal struct PORTEMUPortParams
    {
        internal int channel;
        [MarshalAs(UnmanagedType.Bool)]
        internal bool flocal;
        internal long device;//10
        internal int imtu;
        internal int iminmtu;
        internal int imaxmtu;
        internal int isendquota;
        internal int irecvquota;
        internal Guid uuidService;//16
        internal RFCOMM_PORT_FLAGS uiportflags;
    }
</pre>
<p>Update: this seems important, and I forgot to add it before. Below is the IntermediateDriver.Update() code</p>
<pre class="brush: csharp;">
    // update GPS intermediate driver configuration
    public static bool Update()
    {
        IntPtr hGPS;

        hGPS = CECreateFileW(&quot;GPD0:&quot;, GENERIC_READ, FILE_SHARE_READ &amp;#124; FILE_SHARE_WRITE,
        IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

        if ((int)hGPS != INVALID_HANDLE_VALUE)
        {
            uint bytesReturned;
            DeviceIoControl(hGPS, IOCTL_SERVICE_REFRESH, IntPtr.Zero, 0, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
            CECloseHandle(hGPS);
            return true;
        }
        else
            return false;
    }
</pre>
<div id="_mcePaste" style="overflow:hidden;position:absolute;left:-10000px;top:2822px;width:1px;height:1px;">
<pre></pre>
</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Having fun with Pinvoke]]></title>
<link>http://gcorbin.wordpress.com/2009/04/30/having-fun-with-pinvoke/</link>
<pubDate>Thu, 30 Apr 2009 12:49:19 +0000</pubDate>
<dc:creator>gcorbin</dc:creator>
<guid>http://gcorbin.wordpress.com/2009/04/30/having-fun-with-pinvoke/</guid>
<description><![CDATA[The .Net libraries have many built-in objects that can be used to create most types of programs for ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The .Net libraries have many built-in objects that can be used to create most types of programs for windows. In most cases, the typical developer would not need anything more. However, there are a few cases in which a direct call to a COM object is needed. The ability to call objects that are not .Net from within .Net is called Interoperability. InterOp calls are often used in cases where a .Net program needs to communicate with older software that is based on COM. It can also be used to make direct calls to the windows Kernel. In these cases, a common term among .Net developers is the Pinvoke. Using a Pinvoke is very similar to calling a Windows API from VB6. You need to copy the declaration and import the library and then you can use it. The compiler sees code that uses Pinvoke as being unsafe code. This means that you will need to set the project properties for your code to allow compile unsafe code. The declarations and constants used for these calls can all be found at <a href="http://www.pinvoke.net/" target="_blank">http://www.pinvoke.net/</a>. Some sample .Net code that uses a Pinvoke can be seen below. This code is using the Windows Kernel to create a file.</p>
<p> </p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;color:blue;font-size:10pt;">using</span><span style="font-family:&#34;font-size:10pt;"> System;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;color:blue;font-size:10pt;">using</span><span style="font-family:&#34;font-size:10pt;"> System.Collections.Generic;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;color:blue;font-size:10pt;">using</span><span style="font-family:&#34;font-size:10pt;"> System.Text;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;color:blue;font-size:10pt;">namespace</span><span style="font-family:&#34;font-size:10pt;"> CreateFilewithPinInvoke</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;">{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span><span style="color:blue;">class</span> <span style="color:#2b91af;">FileReader</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">const</span> <span style="color:blue;">uint</span> GENERIC_READ = 0&#215;80000000;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">const</span> <span style="color:blue;">uint</span> FILE_ALL_ACCESS = 0&#215;80000000;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">const</span> <span style="color:blue;">uint</span> OPEN_EXISTING = 3;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">const</span> <span style="color:blue;">uint</span> OPEN_ALWAYS = 3;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>System.<span style="color:#2b91af;">IntPtr</span> handle;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>[System.Runtime.InteropServices.<span style="color:#2b91af;">DllImport</span>(<span style="color:#a31515;">"kernel32"</span>, SetLastError = <span style="color:blue;">true</span>)]</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">unsafe</span> System.<span style="color:#2b91af;">IntPtr</span> CreateFile</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>(</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">string</span> FileName,<span>          </span><span style="color:green;">// file name</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">uint</span> DesiredAccess,<span>       </span><span style="color:green;">// access mode</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">uint</span> ShareMode,<span>           </span><span style="color:green;">// share mode</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">uint</span> SecurityAttributes,<span>  </span><span style="color:green;">// Security Attributes</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">uint</span> CreationDisposition, <span style="color:green;">// how to create</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">uint</span> FlagsAndAttributes,<span>  </span><span style="color:green;">// file attributes</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">int</span> hTemplateFile<span>         </span><span style="color:green;">// handle to template file</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span><span>    </span>);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>[System.Runtime.InteropServices.<span style="color:#2b91af;">DllImport</span>(<span style="color:#a31515;">"kernel32"</span>, SetLastError = <span style="color:blue;">true</span>)]</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">unsafe</span> <span style="color:blue;">bool</span> CloseHandle</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>(</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>System.<span style="color:#2b91af;">IntPtr</span> hObject <span style="color:green;">// handle to object</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">public</span> <span style="color:blue;">bool</span> Open(<span style="color:blue;">string</span> FileName)</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:green;">// open the existing file for reading<span>       </span></span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>handle = CreateFile(FileName,FILE_ALL_ACCESS,0,0, OPEN_ALWAYS,0,0);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">if</span> (handle != System.<span style="color:#2b91af;">IntPtr</span>.Zero)</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span><span style="color:blue;">return</span> <span style="color:blue;">true</span>;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">else</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span><span style="color:blue;">return</span> <span style="color:blue;">false</span>;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">public</span> <span style="color:blue;">bool</span> Close()</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">return</span> CloseHandle(handle);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span><span style="color:blue;">class</span> <span style="color:#2b91af;">Program</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span><span style="color:blue;">static</span> <span style="color:blue;">int</span> Main(<span style="color:blue;">string</span>[] args)</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">if</span> (args.Length != 1)</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span>System.<span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&#8220;Usage : CreateFile.exe &#60;FileName&#62;&#8221;</span>);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span><span style="color:blue;">return</span> 1;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>   </span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:#2b91af;">FileReader</span> fr = <span style="color:blue;">new</span> <span style="color:#2b91af;">FileReader</span>();</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"> </span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">if</span> (fr.Open(args[0]))</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span>System.<span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&#8220;Created requested file&#8221;</span>);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span><span style="color:blue;">return</span> 0;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span><span style="color:blue;">else</span></span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>{</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span>System.<span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&#8220;Failed to create file!&#8221;</span>);</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>                </span><span style="color:blue;">return</span> 1;</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>            </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>        </span>}</span></p>
<p class="MsoNormal" style="margin:0;"><span style="font-family:&#34;font-size:10pt;"><span>    </span>}</span></p>
<p><span style="font-family:&#34;font-size:10pt;">}</span></p>
<p>-Enjoy.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Desktop Developer’s Introduction to Compact Framework Development: Part 3-C++/CLI on Compact Framework]]></title>
<link>http://ericfarr.net/2009/01/29/desktop-developer%e2%80%99s-introduction-to-compact-framework-development-part-3-ccli-on-compact-framework/</link>
<pubDate>Thu, 29 Jan 2009 22:07:59 +0000</pubDate>
<dc:creator>Eric Farr</dc:creator>
<guid>http://ericfarr.net/2009/01/29/desktop-developer%e2%80%99s-introduction-to-compact-framework-development-part-3-ccli-on-compact-framework/</guid>
<description><![CDATA[It may seem like a waste to have a whole post dedicated to a feature that isn&#8217;t there, but kno]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>It may seem like a waste to have a whole post dedicated to a feature that isn&#8217;t there, but knowing this fact would have saved me some wasted mental effort and disappointment.</p>
<p>The Compact Framework is necessarily small. Microsoft only puts functionality into it that developers will be likely to actually need. This means that a lot of stuff you&#8217;d like to be there isn&#8217;t. This also means that you might need to interoperate with native code to do some of what you want to do.</p>
<p>If you are like me, this means you would like to use C++/CLI (the old-school .NET technology formerly known as Managed C++) to do that interop. You, like me, would be sorely disappointed. C++/CLI is not supported on the Compact Framework, and as far as I know there are no plans to add it. Prepare to P/Invoke.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Capture Video In C#.Net]]></title>
<link>http://codeprojects.wordpress.com/2008/11/19/capture-video-in-cnet/</link>
<pubDate>Tue, 18 Nov 2008 20:24:41 +0000</pubDate>
<dc:creator>codeprojects</dc:creator>
<guid>http://codeprojects.wordpress.com/2008/11/19/capture-video-in-cnet/</guid>
<description><![CDATA[با سلام خدمت دوستان خوبم امروز می خوام یک سری کد و یک نمونه برنامه براتون بزارم تا با نحوه دریافت تص]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">با سلام خدمت دوستان خوبم امروز می خوام یک سری کد و یک نمونه برنامه براتون بزارم تا با نحوه دریافت تصاویر از webcam و ذخیره تصاویر دریافتی در فایل avi آشنا بشین. بدون بحث اضافی می رم تا توضیح مختصری در مورد کد های برنامه براتون بدم. در این پروژه ما سه تا کلاس اساسی داریم که به قول معروف، تقریبا کارهای تصویر برداری و ضبط تصاویر رو بر عهده دارن.</p>
<p style="text-align:justify;">1- کلاس CaptureAPI : نمونه pinvoke شده API های کار با دوربین</p>
<p style="text-align:justify;">2- کلاس AVIStreamAPI : نمونه pinvoke شده API های کار با فایل های avi از قبیل ساخت فایل، ساخت استریم avi، ساختن header های فایل avi و &#8230;</p>
<p style="text-align:justify;">3- کلاس AviStream : که وظیفه ساخت فایل و ضبط تصاویر رو با استفاده از api های pinvoke شده رو بر عهده داره.</p>
<p style="text-align:justify;">در این پروژه پس از اتصال به webcam با استفاده از توابع کلاس CaptureAPI و پخش تصاویر با استفاده از event OnVideoCaptured هر frame به bitmap تبدیل شده و سپس بر روی pictureboxنمایش داده میشه. با استفاده از این روش و تبدیل frame های استخراج شده به bitmap نوبت میرسه به ساخت فایل avi و stream مربوط به فایل avi با استفاده از توابع کلاس AviStream، ابتدا فایل avi Initialize شده سپس با استفاده از flage Create فایل avi خام بدون هیچگونه data و header ی که در ساخت avi به کار میره، ساخته میشه . پس از مراحل ساخت فایل نوبت به initalize کردن stream فایل avi میرسه، پس از ساخت stream ، اولین frame که به صورت bitmap هستش به stream اضافه میشه و به همین ترتیب frame های بعدی تا زمان توقف تصویربرداری و بستن فایل avi . شما به راحتی میتونید با استفاده از این روش با دوربین یا webcam ی که در منزل دارید برنامه ای بنویسید که دوربین رو شناسایی کرده اطلاعات رو frame به frame بگیره و ضبط کنه.</p>
<p>نمونه ی برنامه رو می تونید از لینک پایین دانلودش کنید. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  امیدوارم تونسته باشم کمکی در یادگیری کار با دوربین و ضبط تصاویر کرده باشم.</p>
<p>لینک دریافت نمونه پروژه :<a href="http://www.megaupload.com/?d=2SJM7J40" target="_blank">http://www.megaupload.com/?d=2SJM7J40</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[.NET Tools, Framework und Visual Studio Addins]]></title>
<link>http://yogiswelt.wordpress.com/2008/10/09/net-tools-framework-and-visual-studio-addins/</link>
<pubDate>Thu, 09 Oct 2008 22:17:25 +0000</pubDate>
<dc:creator>sleepybo</dc:creator>
<guid>http://yogiswelt.wordpress.com/2008/10/09/net-tools-framework-and-visual-studio-addins/</guid>
<description><![CDATA[Meine persönliche Topliste der nützlichsten Tools, die jeder .NET-Programmierer kennen sollte: Visua]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Meine persönliche Topliste der nützlichsten Tools, die jeder .NET-Programmierer kennen sollte:</p>
<p>Visual Studio:</p>
<ul>
<li><a href="http://www.jetbrains.com/resharper/">Resharper 4.1</a> (sehr umfangreiches Produktivitäts-Add-In)</li>
<li><a href="http://www.visualsvn.com">VisualSVN</a>, <a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a>, <a href="http://subversion.tigris.org/">Subversion</a> (Versionsverwaltung)</li>
<li><a href="http://msdn.microsoft.com/en-us/vs2005/aa718340.aspx">PowerToys for Visual Studio</a> (Einige nützliche Helfer)</li>
<li><a href="http://www.jetbrains.com/teamcity/">TeamCity</a> (Continuous Integration Server)</li>
<li><a href="http://www.microsoft.com/germany/msdn/library/visualtools/WichtigeAddInsFuerVisualStudioNETUnd2005.mspx#EYE">PInvoke.NET </a>(Add-In mit (fast?) allen nativen P/Invokes)</li>
<li><a href="http://code.msdn.microsoft.com/PowerCommands">PowerCommands</a> (Noch mehr kleine nützliche Helfer)</li>
<li>Strg + Tab (Kein Add-In, sondern ein Tipp, den kaum einer nutzt *g*)</li>
<li><a href="http://www.codeplex.com/treesurgeon">Tree Surgeon</a> (Erlaubt zügiges Erstellen von Projekten-Bäumen)</li>
<li><a href="http://www.red-gate.com/products/reflector/">Reflector.NET</a> + <a href="http://www.codeplex.com/reflectoraddins">Addins</a> (Untersucht Klassen mit Reflektion)</li>
<li><a href="http://www.roland-weigelt.de/ghostdoc/" target="_blank">GhostDoc</a> (Erstellt automatische XML-Kommentare)</li>
</ul>
<div>General .NET</div>
<div>
<ul>
<li><a href="http://www.db4o.com/">db4o</a> (Objektorientierte Datenbank)</li>
<li><a href="http://www.castleproject.org/">Castle Project</a> Windsor Container, ActiveRecord und MonoRail (Diverse Pattern-Implementierungen)</li>
<li><a href="http://www.ogre3d.org/">Ogre3d</a> (Grafikengine) / <a href="http://mogre.sourceforge.net/">Mogre</a> (Managed)</li>
<li><a href="http://www.nunit.org/">NUnit</a> (Unit Testing for .Net)</li>
<li><a href="http://code.google.com/p/moq/">moq</a> (Mocking-Framework, das die neuen Features (Lambda-Expressions) von C# 3.5 nutzt)</li>
</ul>
<div>Bis auf Resharper und VisualSVN sind alle Tools kostenfrei erhältlich. Diese Liste werde ich in regelmäßigen Abständen erweitern <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </div>
</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Convert a Long File Name to a Short File Name]]></title>
<link>http://tomshelton.wordpress.com/2008/10/01/convert-a-long-file-name-to-a-short-file-name/</link>
<pubDate>Wed, 01 Oct 2008 04:26:34 +0000</pubDate>
<dc:creator>Tom Shelton</dc:creator>
<guid>http://tomshelton.wordpress.com/2008/10/01/convert-a-long-file-name-to-a-short-file-name/</guid>
<description><![CDATA[This article has moved.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This article has <a href="http://tom-shelton.net/?p=14" target="_self">moved</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[BlueTooth Dongle Detection in .NETCF]]></title>
<link>http://mramprasath.wordpress.com/2008/08/11/bluetooth-dongle-detection-in-netcf/</link>
<pubDate>Mon, 11 Aug 2008 19:01:42 +0000</pubDate>
<dc:creator>mramprasath</dc:creator>
<guid>http://mramprasath.wordpress.com/2008/08/11/bluetooth-dongle-detection-in-netcf/</guid>
<description><![CDATA[BlueTooth Dongle Detection in .NETCF Usb bluetooth dongle detection on RTOS Win CE using P/Invoke in]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td class="MsoNormal" colspan="2" align="center">
<h2><strong><span class="style1">BlueTooth Dongle Detection in .NETCF</span></strong></h2>
</td>
</tr>
<tr>
<td class="MsoNormal" colspan="2" align="justify">Usb bluetooth dongle detection on RTOS <a href="http://www.e-consystems.com/windowsce.asp">Win CE </a> using P/Invoke in C# Compact Framework application.</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td class="MsoNormal" colspan="2"><strong>Api:-</strong></td>
</tr>
<tr>
<td></td>
<td class="MsoNormal"></td>
</tr>
<tr>
<td width="4%"></td>
<td class="MsoNormal" width="96%">int BthGetHardwareStatus(int* pistatus);</td>
</tr>
<tr>
<td></td>
<td class="MsoNormal">pistatus [out] Pointer to an integer that returns the hardware status.</td>
</tr>
<tr>
<td></td>
<td class="MsoNormal">This function returns ERROR_SUCCESS when it completes successfully and returns ERROR_SERVICE_NOT_ACTIVE when the hardware is not inserted or that the Bluetooth stack is not present.</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td class="MsoNormal" colspan="2"><strong> Code Snippet:-</strong></td>
</tr>
<tr>
<td></td>
<td class="MsoNormal"></td>
</tr>
<tr>
<td></td>
<td class="MsoNormal">using System;</p>
<p>using System.Collections.Generic;</p>
<p>using System.Runtime.InteropServices;</p>
<p>using System.Diagnostics;</p>
<p>using System.IO;</p>
<p>using System.Threading;</p>
<p>namespace ECon.BlueTooth</p>
<p>{</p>
<p>public class BlueTooth</p>
<p>{</p>
<p>#region P/Invoke declarations.</p>
<p>[DllImport("Btdrt.Dll")]</p>
<p>private static extern int BthGetHardwareStatus(ref int pStatus);</p>
<p>private const int HCI_HARDWARE_UNKNOWN = 0;</p>
<p>private const int HCI_HARDWARE_NOT_PRESENT = 1;</p>
<p>private const int HCI_HARDWARE_INITIALIZING = 2;</p>
<p>private const int HCI_HARDWARE_RUNNING = 3;</p>
<p>private const int HCI_HARDWARE_SHUTDOWN = 4;</p>
<p>private const int HCI_HARDWARE_ERROR = 5;</p>
<p>#endregion</p>
<p>private System.Windows.Forms.Timer m_WatchTimer = new System.Windows.Forms.Timer();</p>
<p>public BlueTooth()</p>
<p>{</p>
<p>//	BlueTooth Constructor    //</p>
<p>System.Threading.Timer stt = new System.Threading.Timer(new TimerCallback(WatchTimer_Tick), null, 1, 1000);</p>
<p>}</p>
<p>private void WatchTimer_Tick(object sender)</p>
<p>{</p>
<p>int pStatus = HCI_HARDWARE_NOT_PRESENT;</p>
<p>int ret = BthGetHardwareStatus(ref pStatus);</p>
<p>if (ret == 0 &#38;&#38; pStatus == NativeMethods.HCI_HARDWARE_RUNNING)</p>
<p>{</p>
<p>MessageBox.Show(&#8220;BlueTooth Dongle Detected&#8221;);</p>
<p>}</p>
<p>else</p>
<p>{</p>
<p>MessageBox.Show(&#8220;BlueTooth Dongle Removed&#8221;);</p>
<p>}</p>
<p>}</p>
<p>}
</td>
</tr>
</tbody>
</table>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Reproducing Automatic Presence with the UCC API - Part 2]]></title>
<link>http://rhauert.wordpress.com/2008/04/01/reproducing-automatic-presence-with-the-ucc-api-part-2/</link>
<pubDate>Tue, 01 Apr 2008 22:47:51 +0000</pubDate>
<dc:creator>Ryan Hauert</dc:creator>
<guid>http://rhauert.wordpress.com/2008/04/01/reproducing-automatic-presence-with-the-ucc-api-part-2/</guid>
<description><![CDATA[My last post detailed how to monitor user activity and update the user&#8217;s state when they becom]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>My <a href="http://rhauert.wordpress.com/2008/03/27/reproducing-automatic-presence-with-the-ucc-api-part-1/">last post</a> detailed how to monitor user activity and update the user&#8217;s state when they become inactive.&#160; With that code, we can switch between <strong>Available</strong>, <strong>Inactive</strong>, and <strong>Away</strong> states based on user input via the keyboard or mouse.&#160; The next step is to notify OCS when the user locks their machine, by changing the user&#8217;s availability to <strong>Away</strong>.&#160; To do this, we&#8217;re going to need to use P/Invoke again, this time calling the <a href="http://msdn2.microsoft.com/en-us/library/aa383841.aspx" target="_blank">WTSRegisterSessionNotification</a> function, part of <strong>WtsApi32.dll</strong>.&#160; This will only work on a Windows XP or newer OS.&#160; This function takes a handle to a window we own, which is then notified of session changes by the WM_WTSSESSION_CHANGE message.&#160; To receive that notification we need a class that can hook into the windows message loop, something derived from System.Windows.Forms.Control, which I added as a private nested class in the PresenceManager:</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Registers for session changes for this session by calling </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> WTSRegisterSessionNotification.&#160; Provides events that </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> notify when the machine has been locked/unlocked.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">sealed</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">SessionChangeHandler</span> : <span style="color:#2b91af;">Control</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [DllImport(<span style="color:#a31515;">"WtsApi32.dll"</span>, SetLastError = <span style="color:blue;">true</span>)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:blue;">return</span>: MarshalAs(<span style="color:#2b91af;">UnmanagedType</span>.Bool)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">bool</span> WTSRegisterSessionNotification(</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">IntPtr</span> hWnd, [MarshalAs(<span style="color:#2b91af;">UnmanagedType</span>.U4)]<span style="color:blue;">int</span> dwFlags);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [DllImport(<span style="color:#a31515;">"WtsApi32.dll"</span>, SetLastError = <span style="color:blue;">true</span>)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:blue;">return</span>: <span style="color:#2b91af;">MarshalAs</span>(<span style="color:#2b91af;">UnmanagedType</span>.Bool)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">bool</span> WTSUnRegisterSessionNotification(<span style="color:#2b91af;">IntPtr</span> hWnd);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">const</span> <span style="color:blue;">int</span> NOTIFY_FOR_THIS_SESSION = 0;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">const</span> <span style="color:blue;">int</span> WM_WTSSESSION_CHANGE = 0&#215;2b1;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">const</span> <span style="color:blue;">int</span> WTS_SESSION_LOCK = 0&#215;7;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">const</span> <span style="color:blue;">int</span> WTS_SESSION_UNLOCK = 0&#215;8;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Raised when the machine has been locked.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span> MachineLocked;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Raised when the machine has been unlocked.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span> MachineUnlocked;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> SessionChangeHandler()</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (!WTSRegisterSessionNotification(<span style="color:blue;">this</span>.Handle, NOTIFY_FOR_THIS_SESSION))</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">Marshal</span>.ThrowExceptionForHR(<span style="color:#2b91af;">Marshal</span>.GetLastWin32Error());</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">protected</span> <span style="color:blue;">override</span> <span style="color:blue;">void</span> WndProc(<span style="color:blue;">ref</span> <span style="color:#2b91af;">Message</span> m)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (m.Msg == WM_WTSSESSION_CHANGE)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">int</span> value = m.WParam.ToInt32();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (value == WTS_SESSION_LOCK)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OnMachineLocked(<span style="color:#2b91af;">EventArgs</span>.Empty);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">else</span> <span style="color:blue;">if</span> (value == WTS_SESSION_UNLOCK)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OnMachineUnlocked(<span style="color:#2b91af;">EventArgs</span>.Empty);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">base</span>.WndProc(<span style="color:blue;">ref</span> m);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">protected</span> <span style="color:blue;">override</span> <span style="color:blue;">void</span> OnHandleDestroyed(<span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// unregister this instance before it&#8217;s destroyed</span></p>
</div>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (!WTSUnRegisterSessionNotification(<span style="color:blue;">this</span>.Handle))</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">Marshal</span>.ThrowExceptionForHR(<span style="color:#2b91af;">Marshal</span>.GetLastWin32Error());</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">base</span>.OnHandleDestroyed(e);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> OnMachineLocked(<span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">EventHandler</span> temp = MachineLocked;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (temp != <span style="color:blue;">null</span>)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp(<span style="color:blue;">this</span>, e);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> OnMachineUnlocked(<span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">EventHandler</span> temp = MachineUnlocked;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (temp != <span style="color:blue;">null</span>)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp(<span style="color:blue;">this</span>, e);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
</div>
<p style="margin:0;">Surprisingly, WTSRegisterSessionNotification was not yet documented at <a href="http://pinvoke.net/default.aspx/wtsapi32.WTSRegisterSessionNotification" target="_blank">pinvoke.net</a>, so I added a page for it.&#160; The SessionChangeHandler registers itself when it is constructing, and makes a corresponding call to WTSUnRegisterSessionNotification just before the handle is destroyed.&#160; Any time the machine is locked or unlocked, the appropiate event is fired, which the PresenceManager can easily handle:</p>
<p style="margin:0;">&#160;</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> MachineLocked(<span style="color:blue;">object</span> sender, <span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// disable the timer and notify OCS that the user is away</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myLastInputTimer.Change(<span style="color:#2b91af;">Timeout</span>.Infinite, <span style="color:#2b91af;">Timeout</span>.Infinite);</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.Away;</p>
</div>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> MachineUnlocked(<span style="color:blue;">object</span> sender, <span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// change the machine&#8217;s state back to available and re-enable the timer</span></p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.Away;</p>
</div>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myLastInputTimer.Change(2000, 2000);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
</div>
<p>We can use the same code to publish the presence state to OCS as we did in the timer callback, which I&#8217;ll cover in part three.&#160; If you&#8217;re not sure it worked, adding a few calls to Debug.WriteLine can help.&#160; At this point, the PresenceManager handles availability the same way we are used to seeing from other IM clients.&#160; It just needs to be instantiated and kept somewhere, and it will handle automatic presence until disposed.&#160; In the last part of this series I&#8217;ll cover publishing presence state to OCS, and the issues I encountered with the UCC API.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Reproducing Automatic Presence with the UCC API - Part 1]]></title>
<link>http://rhauert.wordpress.com/2008/03/27/reproducing-automatic-presence-with-the-ucc-api-part-1/</link>
<pubDate>Thu, 27 Mar 2008 16:57:22 +0000</pubDate>
<dc:creator>Ryan Hauert</dc:creator>
<guid>http://rhauert.wordpress.com/2008/03/27/reproducing-automatic-presence-with-the-ucc-api-part-1/</guid>
<description><![CDATA[Most popular IM clients, including Communicator 2007, automatically modify the user&#8217;s status w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Most popular IM clients, including Communicator 2007, automatically modify the user&#8217;s status when they are inactive or away.&#160; While piloting Office Communications Server we created a simple application that had the main features of Communicator (chat, A/V, presence, etc.) to show that we could incorporate that functionality into our in-house applications so that our agents only have to work with one piece of software.&#160; The presence functionality is important to us, as we don&#8217;t want to route inbound calls from <a href="http://www.microsoft.com/speech/speech2007/default.mspx" target="_blank">Speech Server</a> to an agent who isn&#8217;t available.&#160; As part of the pilot, I created a simple presence manager to monitor user activity and update availability when necessary.&#160; After five minutes of inactivity, a state value of <strong>Inactive</strong> is published.&#160; After 15 minutes, a state value of <strong>Away</strong> is published.&#160; Finally, if the user locks the machine, a state value of <strong>Away</strong> is published.</p>
<p>Basically, there are two different things the manager needs to detect: the last time there was input (keyboard/mouse) to the machine, and when Windows is locked.&#160; After a little digging, I found the easiest way to achieve our first goal was to P/Invoke the <a href="http://msdn2.microsoft.com/en-us/library/ms646302.aspx" target="_blank">GetLastInputInfo</a> <a href="http://pinvoke.net/default.aspx/user32.GetLastInputInfo" target="_blank">function</a>, which returns the time of the last keyboard/mouse activity.&#160; Using a timer, we can call this method as often as necessary to check if our thresholds (five and 15 minutes) have been reached.&#160; For the sake of simplicity, I removed the code that publishes the state to OCS.&#160; We could also easily add logic to check if the user is on the phone, so the &#8220;In a Call&#8221; state isn&#8217;t overwritten.&#160; </p>
<p>NOTE: I&#8217;m using the System.Threading.Timer class.</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">internal</span> <span style="color:blue;">sealed</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">PresenceManager</span> : <span style="color:#2b91af;">IDisposable</span></p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:#2b91af;">DllImport</span>(<span style="color:#a31515;">"user32.dll"</span>)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">extern</span> <span style="color:blue;">bool</span> GetLastInputInfo(<span style="color:blue;">ref</span> <span style="color:#2b91af;">LASTINPUTINFO</span> plii);</p>
<p style="margin:0;">&#160;</p>
</div>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:#2b91af;">Timer</span> myLastInputTimer;</p>
<p style="margin:0;">&#160;</p>
</div>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> PresenceManager()</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// initialize the timer to call back every two seconds</span></p>
</div>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myLastInputTimer = <span style="color:blue;">new</span> <span style="color:#2b91af;">Timer</span>(CheckIdleTime, <span style="color:blue;">null</span>, 2000, 2000);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p style="margin:0;">&#160;</p>
</div>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Gets the current availability of the signed-in user.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:#2b91af;">Availability</span> CurrentAvailability { <span style="color:blue;">get</span>; <span style="color:blue;">private</span> <span style="color:blue;">set</span>; } </p>
<p style="margin:0;">&#160;</p>
</div>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Callback method for </span><span style="color:gray;">&#60;see cref=&#8221;myLastInputTimer&#8221;/&#62;</span><span style="color:green;"> to check the idle time </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> of the computer and update the status if needed.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;param name=&#8221;state&#8221;&#62;</span><span style="color:green;">The state, unused by this method.</span><span style="color:gray;">&#60;/param&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> CheckIdleTime(<span style="color:blue;">object</span> state)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">LASTINPUTINFO</span> lastInputInfo = <span style="color:#2b91af;">LASTINPUTINFO</span>.Create();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (GetLastInputInfo(<span style="color:blue;">ref</span> lastInputInfo))</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// get the idle time by subtracting the tick count of the last input </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// event from the total tick count of the system</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">int</span> idleTicks = <span style="color:#2b91af;">Environment</span>.TickCount &#8211; lastInputInfo.dwTime;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">TimeSpan</span> idleTime = <span style="color:#2b91af;">TimeSpan</span>.FromSeconds(idleTicks / 1000.0);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">Availability</span> currentAvailability = <span style="color:blue;">this</span>.CurrentAvailability;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (idleTime &#60; <span style="color:#2b91af;">TimeSpan</span>.FromMinutes(5))</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (currentAvailability != <span style="color:#2b91af;">Availability</span>.Available)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// publish available state to OCS here&#8230;</span></p>
<p style="margin:0;"><span style="color:green;"></span>&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.Available;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">else</span> <span style="color:blue;">if</span> (idleTime &#60; <span style="color:#2b91af;">TimeSpan</span>.FromMinutes(15))</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (currentAvailability != <span style="color:#2b91af;">Availability</span>.AvailableIdle</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#38;&#38; currentAvailability != <span style="color:#2b91af;">Availability</span>.BusyIdle)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (currentAvailability == <span style="color:#2b91af;">Availability</span>.Busy)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// publish busy-idle state to OCS here&#8230;</span></p>
<p style="margin:0;"><span style="color:green;"></span>&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.BusyIdle;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">else</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// publish inactive state to OCS here&#8230;</span></p>
<p style="margin:0;"><span style="color:green;"></span>&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.AvailableIdle;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">else</span> <span style="color:blue;">if</span> (<span style="color:blue;">c</span>urrentAvailability != <span style="color:#2b91af;">Availability</span>.Away)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// publish away state to OCS here&#8230;</span></p>
<p style="margin:0;"><span style="color:green;"></span>&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">this</span>.CurrentAvailability = <span style="color:#2b91af;">Availability</span>.Away;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
</div>
<p style="margin:0;">Now we just need to define the <span style="color:#2b91af;">LASTINPUTINFO </span>structure that we pass in GetLastInputInfo.&#160; I nested it inside the manager:</p>
<p style="margin:0;">&#160;</p>
<div style="font-size:10pt;background:white;color:black;font-family:consolas, courier new;">
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Structure used by the </span><span style="color:gray;">&#60;see cref=&#8221;GetLastInputInfo&#8221;/&#62;</span><span style="color:green;"> method.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:#2b91af;">StructLayout</span>(<span style="color:#2b91af;">LayoutKind</span>.Sequential)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">struct</span> <span style="color:#2b91af;">LASTINPUTINFO</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">static</span> <span style="color:blue;">readonly</span> <span style="color:blue;">int</span> size = <span style="color:#2b91af;">Marshal</span>.SizeOf(<span style="color:blue;">typeof</span>(<span style="color:#2b91af;">LASTINPUTINFO</span>));</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Creates a new </span><span style="color:gray;">&#60;see cref=&#8221;LASTINPUTINFO&#8221;/&#62;</span><span style="color:green;"> initialized and ready to </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> be used by the </span><span style="color:gray;">&#60;see cref=&#8221;GetLastInputInfo&#8221;/&#62;</span><span style="color:green;"> method.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;returns&#62;&#60;/returns&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:#2b91af;">LASTINPUTINFO</span> Create()</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">LASTINPUTINFO</span> lii = <span style="color:blue;">new</span> <span style="color:#2b91af;">LASTINPUTINFO</span>();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; lii.cbSize = size;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">return</span> lii;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> The size of this instance, required by the </span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">/// </span><span style="color:gray;">&#60;see cref=&#8221;GetLastInputInfo&#8221;/&#62;</span><span style="color:green;"> method.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:#2b91af;">MarshalAs</span>(<span style="color:#2b91af;">UnmanagedType</span>.U4)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">int</span> cbSize;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> The system tick-count at the last recorded user input, set</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> by the </span><span style="color:gray;">&#60;see cref=&#8221;GetLastInputInfo&#8221;/&#62;</span><span style="color:green;"> method.</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&#60;/summary&#62;</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span style="color:#2b91af;">MarshalAs</span>(<span style="color:#2b91af;">UnmanagedType</span>.U4)]</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">int</span> dwTime;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
</div>
<p>GetLastInputInfo requires the cbSize field to be set before the method is called, so I added a Create method to return an instance ready to be uses.&#160; The timer calls back on a thread retrieved from the thread pool, but we can publish to OCS from any thread.&#160; I found that two seconds was a good interval that updated the state to <strong>Available</strong> in a reasonable time.&#160; In the second post I&#8217;ll cover detecting when the machine is locked/unlocked using another P/Invoke operation. </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[p/invoke Add-in für Visual Studio]]></title>
<link>http://geraldhuber.wordpress.com/2008/01/28/pinvoke-add-in-fur-visual-studio/</link>
<pubDate>Mon, 28 Jan 2008 19:07:57 +0000</pubDate>
<dc:creator>Gerald Huber</dc:creator>
<guid>http://geraldhuber.wordpress.com/2008/01/28/pinvoke-add-in-fur-visual-studio/</guid>
<description><![CDATA[Am Anfang dieses Monats habe ich über Win 32-Api-Calls in C#-Anwendungen geschrieben. Ich beschrieb ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Am Anfang dieses Monats habe ich über Win 32-Api-Calls in C#-Anwendungen geschrieben. Ich beschrieb wie ich diese Funktionen mittels DllImport usw. aufrufen und benutzen kann.</p>
<p>Die Schwiereigkeit dabei ist, die geeigneten Datentypen oder überhaupt die richtige DLL-Datei zu finden. Hier schafft die Seite <a href="http://pinvoke.net/">http://pinvoke.net/</a> Abhilfe.</p>
<p>Die Seite selbst beschreibt sich: &#8220;A wiki for .NET developers: PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs from managed code (written in languages such as C# or VB.NET).&#8221;</p>
<p>Das ist schonmal gut. Aber besser ist noch, dass die Community um PInvoke ein Add-in für Visual Studio bereitstellt um direkt auf den Inhalt von Pinvoke zuzugreifen:  <a href="http://www.red-gate.com/pinvoke/download">Download the PInvoke.net Add-in for FREE now</a>.</p>
<p>Einfacher geht es nur, wenn wir Win32-Api-Calls nie mehr benutzen müssten&#8230; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Interoperabilidad de bibliotecas con Mono]]></title>
<link>http://ocurrenciashabituales.wordpress.com/2008/01/13/interoperabilidad-de-bibliotecas-con-mono/</link>
<pubDate>Sun, 13 Jan 2008 16:33:30 +0000</pubDate>
<dc:creator>Manuel Abeledo</dc:creator>
<guid>http://ocurrenciashabituales.wordpress.com/2008/01/13/interoperabilidad-de-bibliotecas-con-mono/</guid>
<description><![CDATA[Una de las cosas que más me atrae de Mono para ciertas tareas es su plataforma P/Invoke, un método p]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Una de las cosas que más me atrae de <a href="http://www.mono-project.com/Main_Page">Mono</a> para ciertas tareas es su plataforma <a href="http://www.pinvoke.net/">P/Invoke</a>, un método para aprovechar las bibliotecas dinámicas que estén presentes en el sistema. Esto permitiría, por ejemplo, utilizar las funciones de bibliotecas no nativas como <a href="http://www.gnu.org/software/ncurses/">NCurses</a> o <a href="http://tcl.sourceforge.net/">TCL</a>.</p>
<p>Utilizar P/Invoke es muy sencillo incluso para un profano como yo. Sólo es necesario incluir el namespace System.Runtime.InteropServices y la etiqueta DllImport. A continuación lo ilustraré con un ejemplo.</p>
<p><!--more--><code><br />
using System;<br />
using System.Runtime.InteropServices;<br />
public class Libc<br />
{<br />
[DllImport ("libc")]<br />
private extern static int getpid ();<br />
public int Getpid ()<br />
{<br />
return (getpid());<br />
}<br />
}<br />
public class PruebaLibc<br />
{<br />
public static void Main (string [] args)<br />
{<br />
Libc obtenerPID = new Libc();<br />
Console.WriteLine ("El PID del proceso es: {0}", obtenerPID.Getpid());<br />
}<br />
}</code></p>
<p>El ejemplo es muy sencillo. En la clase que he definido, la etiqueta indica el nombre de la biblioteca de donde se va a tomar la función. En este caso basta poner <i>libc</i> ya que se corresponde con la biblioteca <i>libc.so.6</i>. En el archivo <i>/etc/mono/config</i> podemos ver todas las correspondencias configuradas por defecto.</p>
<p>Una vez importadas todas las funciones de la biblioteca es necesario crear envolturas para cada una de ellas. Esto se debe a que es muy aconsejable definir las funciones importadas como privadas.</p>
<p>¡Y ya está! Sólo falta escribir una nueva clase de prueba. En ella he creado un objeto de la clase <i>Libc</i> y he llamado al método <i>Getpid()</i>, cuyo funcionamiento es idéntico al <i>getpid()</i> original.</p>
<p>La salida de este programa será algo así.<br />
<code><br />
$ mono Libc.exe<br />
El PID del proceso es: 19090<br />
$</code></p>
<p>En los enlaces que he puesto más arriba podreis encontrar más información sobre P/Invoke. Yo, con vuestro permiso, seguiré explorando las bondades de Mono <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[C# - Win32 API calls in C# ?!?!]]></title>
<link>http://geraldhuber.wordpress.com/2008/01/07/c-win32-api-calls-in-c/</link>
<pubDate>Mon, 07 Jan 2008 14:35:19 +0000</pubDate>
<dc:creator>Gerald Huber</dc:creator>
<guid>http://geraldhuber.wordpress.com/2008/01/07/c-win32-api-calls-in-c/</guid>
<description><![CDATA[Wieder einmal eine Frage, die sich der ein oder andere sicherlich schon mal gestellt hat, was ist, w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Wieder einmal eine Frage, die sich der ein oder andere sicherlich schon mal gestellt hat, was ist, wenn der Befehl/die Funktion die ich brauche nicht in der .NET-Library enthalten ist? &#8211; Klar, momentan gibt es (so gut wie .NET 3.5) aber es ist immer noch nicht alles von Windows &#8220;gewrappt&#8221; worden.</p>
<p>Kann man also unter (innerhalb) von C# Win32-Api-Methoden aufrufen? &#8211; JA.</p>
<p>Und zwar so:</p>
<ol>
<li>
<div>Wir machen unsere Funktion ausfindig. Z.B. die Methode den um die Workstation, also unsere aktuelle Windows-Sitzung zu sperren.</div>
</li>
<li>
<div>Die MSDN-Library sagt hierzu, dass wir die Methode <code>LockWorkStation</code> aus der <code>user32.dll</code>-Datei brauchen.</div>
</li>
<li>
<div>Nun schreiben wir in unsere C#-Klasse folgende Zeilen:<code><br />
[DllImport("user32.dll", SetLastError = true)]<br />
public static extern bool LockWorkStation();<br />
</code><br />
Hierbei Importieren wir die &#8220;user32.dll&#8221; mittels &#8220;DllImport&#8221; und müssen natürlich die Methode als &#8220;extern&#8221; definieren, da sie ja aus dieser DLL-Datei importiert wird.<br />
&#8220;SetLastError=true&#8221; sagt nur, dass wir eine Fehlermeldung der Importierten Methode auslesen könnten.Anmerkung: Hätten wir zu dem DllImport-Attribute noch &#8221; EntryPoint=&#8221;LockWorkStation&#8221; &#8221; geschrieben hätten wir unsere Methode anders benennen können, also z.B. wie folgt:<br />
<code>[DllImport("user32.dll", EntryPoint="LockWorkStation", SetLastError = true)]<br />
public static extern bool Lock();<br />
</code></div>
</li>
<li>
<div>Das ist auch schon alles.<br />
 </div>
</li>
</ol>
<p>Viel Spass!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Visual Studio Add-Ins Every Developer Should Download Now]]></title>
<link>http://vakul.wordpress.com/2006/10/29/visual-studio-add-ins-every-developer-should-download-now/</link>
<pubDate>Sun, 29 Oct 2006 10:44:18 +0000</pubDate>
<dc:creator>Vakul Kumar More</dc:creator>
<guid>http://vakul.wordpress.com/2006/10/29/visual-studio-add-ins-every-developer-should-download-now/</guid>
<description><![CDATA[Visual Studio provides a rich extensibility model that developers at Microsoft and in the community ]]></description>
<content:encoded><![CDATA[Visual Studio provides a rich extensibility model that developers at Microsoft and in the community ]]></content:encoded>
</item>

</channel>
</rss>
