<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>by Buz</title><link>http://www.pixvillage.com/blogs/devblog/category/1.aspx</link><description>by Buz</description><managingEditor>Buz &amp; Skup</managingEditor><dc:language>en-US</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Buz &amp; Skup</dc:creator><title>Single Instance Application - Part 2 : activating existing instance</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/11/24/3030.aspx</link><pubDate>Thu, 24 Nov 2005 18:00:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/11/24/3030.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/3030.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/11/24/3030.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/3030.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/3030.aspx</trackback:ping><description>  &lt;p&gt;Well, I did not have post for a long time. I was working hard on the next version of
   &lt;a href="http://www.pixvillage.com"&gt;PixVillage&lt;/a&gt;, which will be released soon now.&lt;/p&gt;
  
  &lt;p&gt;I'm coming back with a new post in the &lt;i&gt;Single Instance Application&lt;/i&gt; series.&lt;/p&gt;
  &lt;p&gt;In the previous post, we have written a &lt;i&gt;ProcessLock&lt;/i&gt; object that help us to detect
   an existing instance of the program we attempt to run, so that we can prevent running it twice.&lt;/p&gt;
  
  &lt;p&gt;
   Today I'm dealing with the ability to activate an existing instance of a &lt;i&gt;Windows Forms&lt;/i&gt;
   application when running a new one. In order to achieve that, we have to notify the application 
   it has to go foreground and get focus.&lt;/p&gt;
   
  &lt;p&gt;This can be done though a message send to the main thread of the application. 
   The message is received by the thread, not by a window, so we have to write a specific handler 
   and register it. The &lt;i&gt;IMessageFilter&lt;/i&gt; interface helps providing this kind of service. Let's implement it!&lt;/p&gt;
  
  &lt;!-- ThreadMessageFilter code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel=1 selold=1&gt;&lt;b&gt;  Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;  Copy  &lt;/a&gt;&lt;input type=Radio onclick="parentNode.sel=0" name="ef385928b09345ea82636027bf303909" ID="Radio1" VALUE="Radio1"&gt;Hide&lt;input type=Radio onclick="parentNode.sel=1" name="ef385928b09345ea82636027bf303909" checked ID="Radio2" VALUE="Radio2"&gt;Scroll&lt;input type=Radio onclick="parentNode.sel=2" name="ef385928b09345ea82636027bf303909" ID="Radio3" VALUE="Radio3"&gt;Full&lt;/div&gt;&lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color=#0000FF&gt;namespace&lt;/font&gt; SingleInstance {&lt;div style="margin-left:20pt"&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#008000&gt; Provides a thread message filter and handle messages.&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;public&lt;/font&gt;&lt;font color=#0000FF&gt; class&lt;/font&gt; ThreadMessageFilter : IMessageFilter {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt; Form owner;&lt;br&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#008000&gt; Initializes a new instance of the&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;see cref=&amp;quot;ThreadMessageFilter&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color=#008000&gt; class.&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;param name=&amp;quot;owner&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color=#008000&gt;The owner.&lt;/font&gt;&lt;font color=#808080&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;public&lt;/font&gt; ThreadMessageFilter(Form owner) {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;this&lt;/font&gt;.owner = owner;&lt;/div&gt;}&lt;br&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;exclude/&amp;gt;&lt;/font&gt;&lt;br&gt;[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=&lt;font color=#0000FF&gt;true&lt;/font&gt;)]&lt;br&gt;&lt;font color=#0000FF&gt;bool&lt;/font&gt; IMessageFilter.PreFilterMessage(&lt;font color=#0000FF&gt;ref&lt;/font&gt; Message m) {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;if&lt;/font&gt; (m.HWnd != IntPtr.Zero)&lt;font color=#008000&gt; // Get rid of message if it's sent to a window...&lt;/font&gt;&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;return&lt;/font&gt;&lt;font color=#0000FF&gt; false&lt;/font&gt;;&lt;br&gt;&lt;font color=#008000&gt;&lt;/div&gt;// Handle the message here...&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;return&lt;/font&gt;&lt;font color=#0000FF&gt; false&lt;/font&gt;;&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;&lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;
  &lt;!-- ThreadMessageFilter code end --&gt;
  &lt;p&gt;Now, supposing we want to activate the window when a new instance of the application is launched, 
   we can, for instance, send a &lt;i&gt;WM_SHOWWINDOW&lt;/i&gt; message to the thread, using the Windows 
   &lt;i&gt;PostThreadMessage&lt;/i&gt; API. The &lt;i&gt;IMessageFilter.PreFilterMessage&lt;/i&gt; is implemented as follow:&lt;/p&gt;
   
  &lt;!-- WM_SHOWWINDOW handling code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel=1 selold=1&gt;&lt;b&gt;  Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;  Copy  &lt;/a&gt;&lt;input type=Radio onclick="parentNode.sel=0" name="6e09d35712bb49e391c0d707fddae175" ID="Radio4" VALUE="Radio4"&gt;Hide&lt;input type=Radio onclick="parentNode.sel=1" name="6e09d35712bb49e391c0d707fddae175" checked ID="Radio5" VALUE="Radio5"&gt;Scroll&lt;input type=Radio onclick="parentNode.sel=2" name="6e09d35712bb49e391c0d707fddae175" ID="Radio6" VALUE="Radio6"&gt;Full&lt;/div&gt;&lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;exclude/&amp;gt;&lt;/font&gt;&lt;br&gt;[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=&lt;font color=#0000FF&gt;true&lt;/font&gt;)]&lt;br&gt;&lt;font color=#0000FF&gt;bool&lt;/font&gt; IMessageFilter.PreFilterMessage(&lt;font color=#0000FF&gt;ref&lt;/font&gt; Message m) {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;if&lt;/font&gt; (m.HWnd != IntPtr.Zero)&lt;font color=#008000&gt; // Get rid of message if it's sent to a window...&lt;/font&gt;&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;return&lt;/font&gt;&lt;font color=#0000FF&gt; false&lt;/font&gt;;&lt;br&gt;&lt;font color=#0000FF&gt;&lt;/div&gt;if&lt;/font&gt; (m.Msg == WM_SHOWWINDOW) {&lt;div style="margin-left:20pt"&gt;&lt;font color=#008000&gt;// Shows the window&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;try&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;owner.Show();&lt;br&gt;&lt;font color=#0000FF&gt;if&lt;/font&gt; (owner.WindowState == FormWindowState.Minimized)&lt;div style="margin-left:20pt"&gt;owner.WindowState = FormWindowState.Normal;&lt;br&gt;&lt;font color=#0000FF&gt;&lt;/div&gt;return&lt;/font&gt;&lt;font color=#0000FF&gt; true&lt;/font&gt;;&lt;/div&gt;}&lt;br&gt;&lt;font color=#0000FF&gt;catch&lt;/font&gt; {}&lt;font color=#008000&gt; // return false;&lt;/font&gt;&lt;/div&gt;}&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;return&lt;/font&gt;&lt;font color=#0000FF&gt; false&lt;/font&gt;;&lt;/div&gt;}&lt;br&gt;&lt;/div&gt;&lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;
  &lt;!-- WM_SHOWWINDOW handling code end --&gt;
  
  &lt;p&gt;With &lt;i&gt;WM_SHOWWINDOW&lt;/i&gt; declared as follow:&lt;/p&gt;
  
  &lt;!-- WM_SHOWWINDOW code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid"&gt;&lt;b&gt;  Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;  Copy  &lt;/a&gt;&lt;/div&gt;&lt;div style="overflow:auto;font-size:15;font-family:'Courier New'"&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; const&lt;/font&gt;&lt;font color=#0000FF&gt; int&lt;/font&gt; WM_SHOWWINDOW = 0x18;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;  
  &lt;!-- WM_SHOWWINDOW code end --&gt;
  &lt;p&gt;Now, we just have to modify the &lt;i&gt;Main()&lt;/i&gt; method in order to:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;Create and show the form the first time the application is started.&lt;/li&gt;
   &lt;li&gt;Registers and unregisters a &lt;i&gt;ThreadMessageFilter&lt;/i&gt; object.&lt;/li&gt;
   &lt;li&gt;Send the message to any thread of any process having the same name as the current assembly.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;The code is given below. (&lt;i&gt;MainForm&lt;/i&gt; is a class derived from &lt;i&gt;System.Windows.Form&lt;/i&gt;).&lt;/p&gt;
  &lt;!-- Main() code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel=0 selold=0&gt;&lt;b&gt;  Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;  Copy  &lt;/a&gt;&lt;input type=Radio onclick="parentNode.sel=0" name="d66e1eda9d3d48aba90db3046ca2fffa" checked ID="Radio7" VALUE="Radio7"&gt;Hide&lt;input type=Radio onclick="parentNode.sel=1" name="d66e1eda9d3d48aba90db3046ca2fffa" ID="Radio8" VALUE="Radio8"&gt;Scroll&lt;input type=Radio onclick="parentNode.sel=2" name="d66e1eda9d3d48aba90db3046ca2fffa" ID="Radio9" VALUE="Radio9"&gt;Full&lt;/div&gt;&lt;div style="overflow:auto;font-size:15;font-family:'Courier New';display:'none'"&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt; System;&lt;br&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt; System.Diagnostics;&lt;br&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt; System.Reflection;&lt;br&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt; System.Runtime.InteropServices;&lt;br&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt; System.Windows.Forms;&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;namespace&lt;/font&gt; SingleInstance&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;public&lt;/font&gt;&lt;font color=#0000FF&gt; sealed&lt;/font&gt;&lt;font color=#0000FF&gt; class&lt;/font&gt; SingleInstance&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt; SingleInstance(){}&lt;br&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; static&lt;/font&gt;&lt;font color=#0000FF&gt; readonly&lt;/font&gt;&lt;font color=#0000FF&gt; string&lt;/font&gt; assemblyName = Assembly.GetExecutingAssembly().GetName().Name;&lt;br&gt;&lt;br&gt;[DllImport(&amp;quot;user32.dll&amp;quot;)]&lt;br&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; static&lt;/font&gt;&lt;font color=#0000FF&gt; extern&lt;/font&gt;&lt;font color=#0000FF&gt; bool&lt;/font&gt; PostThreadMessage(&lt;font color=#0000FF&gt;int&lt;/font&gt; threadId,&lt;font color=#0000FF&gt; int&lt;/font&gt; message,&lt;font color=#0000FF&gt; int&lt;/font&gt; wParam,&lt;font color=#0000FF&gt; int&lt;/font&gt; lParam);&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; const&lt;/font&gt;&lt;font color=#0000FF&gt; int&lt;/font&gt; WM_SHOWWINDOW = 0x18;&lt;br&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#008000&gt; Application entry point.&lt;/font&gt;&lt;br&gt;&lt;font color=#808080&gt;///&lt;/font&gt;&lt;font color=#808080&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;[STAThread]&lt;br&gt;&lt;font color=#0000FF&gt;static&lt;/font&gt;&lt;font color=#0000FF&gt; void&lt;/font&gt; Main() {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt;(ProcessLock processLock =&lt;font color=#0000FF&gt; new&lt;/font&gt; ProcessLock(assemblyName)) {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;if&lt;/font&gt; (processLock.AlreadyExists)&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;&lt;font color=#008000&gt;// Sets the existing application foreground.&lt;/font&gt;&lt;br&gt;SetForeground();&lt;/div&gt;}&lt;br&gt;&lt;font color=#0000FF&gt;else&lt;/font&gt;&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;&lt;font color=#008000&gt;// The program operation must run inside the 'using' block.&lt;/font&gt;&lt;br&gt;Run();&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;}&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; static&lt;/font&gt;&lt;font color=#0000FF&gt; void&lt;/font&gt; SetForeground() {&lt;div style="margin-left:20pt"&gt;&lt;font color=#008000&gt;// Find all processes having the same name&lt;/font&gt;&lt;br&gt;Process[] processes = Process.GetProcessesByName(assemblyName);&lt;br&gt;&lt;font color=#0000FF&gt;foreach&lt;/font&gt; (Process process&lt;font color=#0000FF&gt; in&lt;/font&gt; processes)&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;if&lt;/font&gt; (process.Id == Process.GetCurrentProcess().Id)&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&lt;div style="margin-left:20pt"&gt;&lt;font color=#008000&gt;// This is the current process, pass&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;continue&lt;/font&gt;;&lt;br&gt;&lt;font color=#008000&gt;&lt;/div&gt;// Activates the other instance window by sending the message to any thread in the process.&lt;/font&gt;&lt;br&gt;&lt;font color=#0000FF&gt;foreach&lt;/font&gt; (ProcessThread thread&lt;font color=#0000FF&gt; in&lt;/font&gt; process.Threads)&lt;div style="margin-left:20pt"&gt;PostThreadMessage(thread.Id, WM_SHOWWINDOW, 0, 0);&lt;/div&gt;&lt;/div&gt;}&lt;/div&gt;}&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;private&lt;/font&gt;&lt;font color=#0000FF&gt; static&lt;/font&gt;&lt;font color=#0000FF&gt; void&lt;/font&gt; Run() {&lt;div style="margin-left:20pt"&gt;&lt;font color=#0000FF&gt;using&lt;/font&gt;(MainForm form =&lt;font color=#0000FF&gt; new&lt;/font&gt; MainForm()) {&lt;div style="margin-left:20pt"&gt;IMessageFilter filter =&lt;font color=#0000FF&gt; new&lt;/font&gt; ThreadMessageFilter(form);&lt;br&gt;Application.AddMessageFilter(filter);&lt;br&gt;&lt;br&gt;&lt;font color=#0000FF&gt;try&lt;/font&gt;&lt;br&gt;{&lt;div style="margin-left:20pt"&gt;form.Show();&lt;br&gt;Application.Run(form);&lt;/div&gt;}&lt;br&gt;&lt;font color=#0000FF&gt;finally&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;Application.RemoveMessageFilter(filter);&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;}&lt;/div&gt;}&lt;br&gt;&lt;/div&gt;&lt;div style="background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;
  &lt;!-- Main() code end --&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/3030.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Single Instance Application - Part 1 : preventing multiple instances</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/04/21/218.aspx</link><pubDate>Thu, 21 Apr 2005 13:48:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/04/21/218.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/218.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/04/21/218.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/218.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/218.aspx</trackback:ping><description>  &lt;p&gt;Don't worry, the Exif series is not closed yet... preparing Part 4 just 
   requires more work...&lt;/p&gt;
  &lt;p&gt;This new post series is dedicated to - as title say - the 
   creation of a single instance application. That is, application that can only 
   run once simultaneously. That's a frequently encountered issue, particularly 
   when your program makes use of resources that cannot be shared (overlay video 
   surfaces, network listen ports, etc.)&lt;/p&gt;
  &lt;p&gt;My solution to the single instance application problem is to create a class 
   called &lt;i&gt;ProcessLock&lt;/i&gt; that can be locked, unlocked, and indicate whether 
   the application is running.&lt;br /&gt;
   The &lt;i&gt;ProcessLock&lt;/i&gt; implements the &lt;i&gt;IDisposable&lt;/i&gt; interface, so that the 
   process lock can be locked and unlocked through a &lt;i&gt;using&lt;/i&gt; statement. The 
   implementation uses a named mutex (with is global to the user session).&lt;/p&gt;
  &lt;p&gt;The &lt;i&gt;ProcessLock&lt;/i&gt; tries to create the underlying mutex in the constructor. 
   A failure means that the mutex does already exist : the application is running.&lt;/p&gt;
  &lt;!-- ProcessLock code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="1" selold="1"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="c5a5a67b7ca44767ba442f13e0c89c1e"
     ID="Radio1" VALUE="Radio1"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="c5a5a67b7ca44767ba442f13e0c89c1e"
     checked ID="Radio2" VALUE="Radio2"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="c5a5a67b7ca44767ba442f13e0c89c1e"
     ID="Radio3" VALUE="Radio3"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color="#0000FF"&gt;#region&lt;/font&gt;
    References&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Diagnostics;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Threading;&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
     &lt;br&gt;
     namespace&lt;/font&gt; SingleInstance {&lt;div style="margin-left:20pt"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
      &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Provides a lock object to 
      prevent a program from being launched multiple times.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; class&lt;/font&gt; ProcessLock 
     : IDisposable {&lt;br&gt;
     &lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;#region&lt;/font&gt; Fields&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; string&lt;/font&gt; applicationName;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; Mutex mutex;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; created;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; disposed;&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Instance Management&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Initializes a new instance 
       of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see cref=&amp;quot;ProcessLock&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;
       class.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
       name=&amp;quot;applicationName&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;Name of the 
       process lock&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt; ProcessLock(&lt;font color="#0000FF"&gt;string&lt;/font&gt;
      applicationName) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.applicationName 
       = applicationName;&lt;br&gt;
       TryLock();&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Disposes the process lock 
       resources.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; Dispose() 
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (mutex!=&lt;font color="#0000FF"&gt;null&lt;/font&gt;){&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;
        (created)&lt;div style="margin-left:20pt"&gt;Unlock();&lt;font color="#0000FF"&gt;&lt;/div&gt;
        else&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;mutex.Close();&lt;br&gt;
         mutex =&lt;font color="#0000FF"&gt; null&lt;/font&gt;;&lt;/div&gt;
        }&lt;/div&gt;
       }&lt;br&gt;
       &lt;br&gt;
       disposed =&lt;font color="#0000FF"&gt; true&lt;/font&gt;;&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Properties&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Indicates whether a process 
       for the given name does already exist.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; AlreadyExists 
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
        !created;&lt;/div&gt;
       }&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Indicates whether the 
       process lock is disposed.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; Disposed 
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
        disposed;&lt;/div&gt;
       }&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Methods&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Try to get the process lock 
       again.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; TryLock(){&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;
       (disposed)&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;font color="#0000FF"&gt;
         new&lt;/font&gt; ObjectDisposedException(&lt;font color="#800000"&gt;&amp;quot;ProcessLock&amp;quot;&lt;/font&gt;);&lt;br&gt;
        &lt;font color="#0000FF"&gt;
       &lt;/div&gt;
       if&lt;/font&gt; (created)&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;font color="#0000FF"&gt;
         new&lt;/font&gt; InvalidOperationException();&lt;br&gt;
        &lt;font color="#0000FF"&gt;
       &lt;/div&gt;
       if&lt;/font&gt; (mutex!=&lt;font color="#0000FF"&gt;null&lt;/font&gt;)&lt;div style="margin-left:20pt"&gt;mutex.Close();&lt;/div&gt;
       mutex =&lt;font color="#0000FF"&gt; new&lt;/font&gt; Mutex(&lt;font color="#0000FF"&gt;true&lt;/font&gt;, 
       applicationName,&lt;font color="#0000FF"&gt; out&lt;/font&gt; created);&lt;br&gt;
       &lt;br&gt;
       &lt;font color="#0000FF"&gt;return&lt;/font&gt; created;&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Releases the process lock.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; Unlock() 
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (disposed)&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;throw&lt;/font&gt;&lt;font color="#0000FF"&gt;
         new&lt;/font&gt; ObjectDisposedException(&lt;font color="#800000"&gt;&amp;quot;ProcessLock&amp;quot;&lt;/font&gt;);&lt;br&gt;
        &lt;div style="margin-left:40pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (!created)&lt;font color="#0000FF"&gt;&lt;/div&gt;
        throw&lt;/font&gt;&lt;font color="#0000FF"&gt; new&lt;/font&gt; InvalidOperationException();&lt;br&gt;
       &lt;/div&gt;
       Debug.Assert(mutex!=&lt;font color="#0000FF"&gt;null&lt;/font&gt;);&lt;br&gt;
       &lt;br&gt;
       mutex.ReleaseMutex();&lt;br&gt;
       mutex =&lt;font color="#0000FF"&gt; null&lt;/font&gt;;&lt;br&gt;
       created =&lt;font color="#0000FF"&gt; false&lt;/font&gt;;&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;/font&gt;&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;/div&gt;
   &lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- ProcessLock code end --&gt;
  &lt;p&gt;Using a &lt;i&gt;ProcessLock&lt;/i&gt; is quite straight-forward. A sample Console 
   application follows (you will note the use of &lt;i&gt;System.Reflection.Assembly&lt;/i&gt; 
   for retrieving the application name) :&lt;/p&gt;
  &lt;!-- Main code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="1" selold="1"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="5e0063b4fee54b8fb764ed8349a6d75c"
     ID="Radio4" VALUE="Radio4"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="5e0063b4fee54b8fb764ed8349a6d75c"
     checked ID="Radio5" VALUE="Radio5"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="5e0063b4fee54b8fb764ed8349a6d75c"
     ID="Radio6" VALUE="Radio6"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color="#0000FF"&gt;using&lt;/font&gt;
    System;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Reflection;&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;namespace&lt;/font&gt; SingleInstance&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt;
      sealed&lt;/font&gt;&lt;font color="#0000FF"&gt; class&lt;/font&gt; SingleInstance&lt;br&gt;
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;private&lt;/font&gt; SingleInstance(){}&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; string&lt;/font&gt; assemblyName = 
      Assembly.GetExecutingAssembly().GetName().Name;&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Application entry point.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      [STAThread]&lt;br&gt;
      &lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; Main() {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;using&lt;/font&gt;(ProcessLock 
       processLock =&lt;font color="#0000FF"&gt; new&lt;/font&gt; ProcessLock(assemblyName)) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;
        (processLock.AlreadyExists)&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;;&lt;br&gt;
         &lt;font color="#008000"&gt;
        &lt;/div&gt;
        // The program operation must run inside the 'using' block.&lt;/font&gt;&lt;br&gt;
        Run();&lt;/div&gt;
       }&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       void&lt;/font&gt; Run() {&lt;div style="margin-left:20pt"&gt;Console.WriteLine(&lt;font color="#800000"&gt;&amp;quot;{0} 
        running. Press 'Enter' to exit.&amp;quot;&lt;/font&gt;, assemblyName);&lt;br&gt;
       Console.ReadLine();&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;br&gt;
   &lt;/div&gt;
   &lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Main code end --&gt;
  
  &lt;p&gt;In the next post, I will explain how to bring a window to the foreground, even if it is currently invisible...&lt;/p&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/218.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Exif Properties in .Net - Part 3 : converting properties</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/04/19/215.aspx</link><pubDate>Tue, 19 Apr 2005 12:20:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/04/19/215.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/215.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/04/19/215.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/215.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/215.aspx</trackback:ping><description>  &lt;p&gt;
   In the first post of this Exif series, I talked about a technique for &lt;A href="http://www.pixvillage.com/blogs/devblog/archive/2005/03/17/159.aspx"&gt;
    loading Exif properties&lt;/a&gt; as fast as GDI+ is able to do.&lt;br /&gt;
   The second post was dealing with &lt;A href="http://www.pixvillage.com/blogs/devblog/archive/2005/03/27/176.aspx"&gt;
    adding new properties&lt;/a&gt; to an empty image.&lt;/p&gt;
  &lt;p&gt;Now it's time to look more precisely at the Exif properties. How is a 
   PropertyItem structured ?&lt;br /&gt;
   The final goal of this post is to convert the raw data exposed by GDI+ (and the 
   .Net Framework) into more useable data types.
  &lt;/p&gt;
  &lt;p&gt;
   An Exif property consists in the following information:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    An &lt;b&gt;identifier&lt;/b&gt;, determining the "meaning" of the property.&lt;/li&gt;
   &lt;li&gt;
    A &lt;b&gt;data type&lt;/b&gt;, indicating how the data are represented.&lt;/li&gt;
   &lt;li&gt;
    A &lt;b&gt;length&lt;/b&gt; (the number of bytes the property data contains).&lt;/li&gt;
   &lt;li&gt;
    A &lt;b&gt;value&lt;/b&gt; which is a raw array of bytes.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
   The Exif property data type is a 16-bit integer, but it's quite simple to build 
   an &lt;i&gt;enum&lt;/i&gt; type that maps the values to a more comprehensive type :
  &lt;/p&gt;
  &lt;!-- ExifPropertyType code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="1" selold="1"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="2642bbc82b3e4954b83504567c000b2c"
     ID="Radio4" VALUE="Radio4"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="2642bbc82b3e4954b83504567c000b2c"
     checked ID="Radio5" VALUE="Radio5"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="2642bbc82b3e4954b83504567c000b2c"
     ID="Radio6" VALUE="Radio6"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
     &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Defines types for Exif Properties.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; enum&lt;/font&gt; ExifPropertyType 
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of bytes.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     Byte = 1,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is a null-terminated ASCII string.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;remarks&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;If 
      you set&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see 
      cref=&amp;quot;PropertyItem.Type&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;PropertyItem.Type&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/see&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;
      to&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see cref=&amp;quot;PropertyItem.Type&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;, 
      you should set the length data member to the length of the string including the 
      NULL terminator. For example, the string HELLO would have a length of 6.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/remarks&amp;gt;&lt;/font&gt;&lt;br&gt;
     Ascii = 2,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of signed short (16-bit) integers.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     UInt16 = 3,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of unsigned long (32-bit) integers.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     UInt32 = 4,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of pairs of unsigned long integers. Each pair 
      represents a fraction; the first integer is the numerator and the second 
      integer is the denominator.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     URational = 5,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of bytes that can hold values of any data type.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     Raw = 7,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of signed long (32-bit) integers.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     Int32 = 9,&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Specifies that the value 
      data member is an array of pairs of signed long integers. Each pair represents 
      a fraction; the first integer is the numerator and the second integer is the 
      denominator.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     Rational = 10,&lt;/div&gt;
    }&lt;/div&gt;
   &lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- ExifPropertyType code end --&gt;
  &lt;p&gt;
   As you can see in the code above, most of the data types are simple and can be 
   directly mapped to .Net data types, excepted for rational and unsigned rational 
   values. We need to create a .Net representation for each of them :&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    Rational :&lt;/li&gt;
  &lt;/ul&gt;
  &lt;!-- Rational code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="0" selold="0"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="988984db983549d78652ccd87c368df7"
     checked ID="Radio7" VALUE="Radio7"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="988984db983549d78652ccd87c368df7"
     ID="Radio8" VALUE="Radio8"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="988984db983549d78652ccd87c368df7"
     ID="Radio9" VALUE="Radio9"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';display:'none'"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
     &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Represents a signed rational number.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; class&lt;/font&gt; Rational 
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt;
      int&lt;/font&gt; numerator;&lt;br&gt;
     &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; denominator;&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Initializes a new instance 
      of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see cref=&amp;quot;Rational&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;
      class.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
      name=&amp;quot;numerator&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The numerator of the 
      rational number.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
      name=&amp;quot;denominator&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The denominator of 
      the rational number.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt; Rational(&lt;font color="#0000FF"&gt;int&lt;/font&gt; numerator,&lt;font color="#0000FF"&gt;
      int&lt;/font&gt; denominator) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.numerator 
      = numerator;&lt;br&gt;
      &lt;font color="#0000FF"&gt;this&lt;/font&gt;.denominator = denominator;&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the numerator of the 
      rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; Numerator 
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       numerator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the denominator of the 
      rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; Denominator 
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       denominator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the floating-point 
      value of the rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; double&lt;/font&gt; Value {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt; (&lt;font color="#0000FF"&gt;double&lt;/font&gt;) 
       numerator/(&lt;font color="#0000FF"&gt;double&lt;/font&gt;) denominator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;exclude/&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; override&lt;/font&gt;&lt;font color="#0000FF"&gt;
      string&lt;/font&gt; ToString() {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
      Value.ToString();&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;/div&gt;
   &lt;div style="background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Rational code end --&gt;
  &lt;ul&gt;
   &lt;li&gt;
    URational :&lt;/li&gt;
  &lt;/ul&gt;
  &lt;!-- URational code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="0" selold="0"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="3dcd585a2e8f4c75af9fcecf2d55cb69"
     checked ID="Radio10" VALUE="Radio10"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="3dcd585a2e8f4c75af9fcecf2d55cb69"
     ID="Radio11" VALUE="Radio11"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="3dcd585a2e8f4c75af9fcecf2d55cb69"
     ID="Radio12" VALUE="Radio12"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';display:'none'"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
     &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Represents an unsigned rational number.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; class&lt;/font&gt; URational 
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt;
      uint&lt;/font&gt; numerator;&lt;br&gt;
     &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; uint&lt;/font&gt; denominator;&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Initializes a new instance 
      of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see cref=&amp;quot;Rational&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;
      class.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
      name=&amp;quot;numerator&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The numerator of the 
      rational number.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
      name=&amp;quot;denominator&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The denominator of 
      the rational number.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt; URational(&lt;font color="#0000FF"&gt;uint&lt;/font&gt; 
     numerator,&lt;font color="#0000FF"&gt; uint&lt;/font&gt; denominator) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.numerator 
      = numerator;&lt;br&gt;
      &lt;font color="#0000FF"&gt;this&lt;/font&gt;.denominator = denominator;&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the numerator of the 
      rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; uint&lt;/font&gt; Numerator 
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       numerator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the denominator of the 
      rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; uint&lt;/font&gt; Denominator 
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt; {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       denominator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Gets the floating-point 
      value of the rational number.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; double&lt;/font&gt; Value {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt; (&lt;font color="#0000FF"&gt;double&lt;/font&gt;) 
       numerator/(&lt;font color="#0000FF"&gt;double&lt;/font&gt;) denominator;&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;exclude/&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; override&lt;/font&gt;&lt;font color="#0000FF"&gt;
      string&lt;/font&gt; ToString() {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
      Value.ToString();&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;/div&gt;
   &lt;div style="background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- URational code end --&gt;
  &lt;p&gt;According to the &lt;a href="http://www.exif.org/specifications.html"&gt;Exif 
    specification&lt;/a&gt;, properties may contain arrays of values. Our conversion 
   tool must consequently have the following signature :&lt;/p&gt;
  &lt;!-- Empty FromPropertyItem code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New'"&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt;
     static&lt;/font&gt; Array FromPropertyItem(PropertyItem propertyItem) {}&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Empty FromPropertyItem code end --&gt;
  &lt;p&gt;The conversion code is quite simple (a &lt;i&gt;switch... case&lt;/i&gt; construct branching 
   on different code depending on the data type).&lt;br /&gt;
   When converting raw data into integers, just take care that Exif properties are 
   stored as big endian values.
  &lt;/p&gt;
  &lt;!-- ExifConvert code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="1" selold="1"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="0e8bd05ef388471bad8d2d72adb58fc3"
     ID="Radio1" VALUE="Radio1"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="0e8bd05ef388471bad8d2d72adb58fc3"
     checked ID="Radio2" VALUE="Radio2"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="0e8bd05ef388471bad8d2d72adb58fc3"
     ID="Radio3" VALUE="Radio3"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';Height:200"&gt;&lt;font color="#0000FF"&gt;#region&lt;/font&gt;
    References&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Drawing.Imaging;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Runtime.InteropServices;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Text;&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
     &lt;br&gt;
     namespace&lt;/font&gt; ExifNative {&lt;div style="margin-left:20pt"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
      &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Summary description for 
      ExifConvert.&lt;/font&gt;&lt;br&gt;
     &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
     &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; sealed&lt;/font&gt;&lt;font color="#0000FF"&gt;
      class&lt;/font&gt; ExifConvert {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;private&lt;/font&gt;
      ExifConvert() {}&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; Converts a property item to 
       an array of objects.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
       name=&amp;quot;propertyItem&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The property item 
       to convert.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;returns&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;An 
       array of&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see cref=&amp;quot;object&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;
       items.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br&gt;
      &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; Array 
      FromPropertyItem(PropertyItem propertyItem) {&lt;div style="margin-left:20pt"&gt;ExifPropertyType 
       type = (ExifPropertyType) propertyItem.Type;&lt;br&gt;
       &lt;br&gt;
       &lt;font color="#0000FF"&gt;switch&lt;/font&gt; (type) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;case&lt;/font&gt;
        ExifPropertyType.Raw:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// The value 
          represents raw data (a single byte[] value)&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;font color="#0000FF"&gt; new&lt;/font&gt;&lt;font color="#0000FF"&gt;
          byte&lt;/font&gt;[][] {propertyItem.Value};&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.Ascii:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of strings separated by \0 characters&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;string&lt;/font&gt; stringValue = 
         Encoding.ASCII.GetString(propertyItem.Value, 0, propertyItem.Len - 1);&lt;br&gt;
         &lt;font color="#0000FF"&gt;return&lt;/font&gt; stringValue.Split(&lt;font color="#800000"&gt;'\0'&lt;/font&gt;);&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.Byte:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of bytes&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;return&lt;/font&gt; propertyItem.Value;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.UInt16:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of unsigned 16-bit integers.&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt; ushortCount = propertyItem.Len/ushortSize;&lt;br&gt;
         &lt;br&gt;
         &lt;font color="#0000FF"&gt;ushort&lt;/font&gt;[] ushortResult =&lt;font color="#0000FF"&gt; new&lt;/font&gt;&lt;font color="#0000FF"&gt;
          ushort&lt;/font&gt;[ushortCount];&lt;br&gt;
         &lt;font color="#0000FF"&gt;for&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt; i = 0; i 
         &amp;lt; ushortCount; i++)&lt;div style="margin-left:20pt"&gt;ushortResult[i] = 
          ReadUInt16(propertyItem.Value, i * ushortSize);&lt;font color="#0000FF"&gt;&lt;/div&gt;
         return&lt;/font&gt; ushortResult;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.Int32:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of signed 32-bit integers.&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt; intCount = propertyItem.Len/intSize;&lt;br&gt;
         &lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt;[] intResult =&lt;font color="#0000FF"&gt; new&lt;/font&gt;&lt;font color="#0000FF"&gt;
          int&lt;/font&gt;[intCount];&lt;br&gt;
         &lt;font color="#0000FF"&gt;for&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt; i = 0; i 
         &amp;lt; intCount; i++)&lt;div style="margin-left:20pt"&gt;intResult[i] = 
          ReadInt32(propertyItem.Value, i * intSize);&lt;font color="#0000FF"&gt;&lt;/div&gt;
         return&lt;/font&gt; intResult;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.UInt32:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of unsigned 32-bit integers.&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt; uintCount = propertyItem.Len/uintSize;&lt;br&gt;
         &lt;br&gt;
         &lt;font color="#0000FF"&gt;uint&lt;/font&gt;[] uintResult =&lt;font color="#0000FF"&gt; new&lt;/font&gt;&lt;font color="#0000FF"&gt;
          uint&lt;/font&gt;[uintCount];&lt;br&gt;
         &lt;font color="#0000FF"&gt;for&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt; i = 0; i 
         &amp;lt; uintCount; i++)&lt;div style="margin-left:20pt"&gt;uintResult[i] = 
          ReadUInt32(propertyItem.Value, i * uintSize);&lt;font color="#0000FF"&gt;&lt;/div&gt;
         return&lt;/font&gt; uintResult;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.Rational:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of signed rational numbers&lt;/font&gt;&lt;br&gt;
         &lt;font color="#008000"&gt;// Numerator is an Int32 value, denominator a UInt32 value.&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt; rationalCount = propertyItem.Len/rationalSize;&lt;br&gt;
         &lt;br&gt;
         Rational[] rationalResult =&lt;font color="#0000FF"&gt; new&lt;/font&gt; Rational[rationalCount];&lt;br&gt;
         &lt;font color="#0000FF"&gt;for&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt; i = 0; i 
         &amp;lt; rationalCount; i++)&lt;div style="margin-left:20pt"&gt;rationalResult[i] =&lt;font color="#0000FF"&gt;
           new&lt;/font&gt; Rational(&lt;div style="margin-left:20pt"&gt;ReadInt32(propertyItem.Value, 
           i * rationalSize),&lt;br&gt;
           ReadInt32(propertyItem.Value, i * rationalSize + intSize));&lt;font color="#0000FF"&gt;&lt;/div&gt;
         &lt;/div&gt;
         return&lt;/font&gt; rationalResult;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;case&lt;/font&gt; ExifPropertyType.URational:&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// 
          The value represents an array of signed rational numbers&lt;/font&gt;&lt;br&gt;
         &lt;font color="#008000"&gt;// Numerator and denominator are UInt32 values.&lt;/font&gt;&lt;br&gt;
         &lt;font color="#0000FF"&gt;int&lt;/font&gt; urationalCount = 
         propertyItem.Len/rationalSize;&lt;br&gt;
         &lt;br&gt;
         URational[] urationalResult =&lt;font color="#0000FF"&gt; new&lt;/font&gt; URational[urationalCount];&lt;br&gt;
         &lt;font color="#0000FF"&gt;for&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt; i = 0; i 
         &amp;lt; urationalCount; i++)&lt;div style="margin-left:20pt"&gt;urationalResult[i] =&lt;font color="#0000FF"&gt;
           new&lt;/font&gt; URational(&lt;div style="margin-left:20pt"&gt;ReadUInt32(propertyItem.Value, 
           i * urationalSize),&lt;br&gt;
           ReadUInt32(propertyItem.Value, i * urationalSize + uintSize));&lt;font color="#0000FF"&gt;&lt;/div&gt;
         &lt;/div&gt;
         return&lt;/font&gt; urationalResult;&lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt;
        &lt;font color="#0000FF"&gt;default&lt;/font&gt;:&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;font color="#0000FF"&gt;
          null&lt;/font&gt;;&lt;/div&gt;
       &lt;/div&gt;
       }&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#region&lt;/font&gt; Static Fields&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; ushortSize = 
      Marshal.SizeOf(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt; (&lt;font color="#0000FF"&gt;ushort&lt;/font&gt;));&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; intSize = Marshal.SizeOf(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt;
      (&lt;font color="#0000FF"&gt;int&lt;/font&gt;));&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; uintSize = Marshal.SizeOf(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt;
      (&lt;font color="#0000FF"&gt;uint&lt;/font&gt;));&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; rationalSize = 2 * 
      Marshal.SizeOf(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt; (&lt;font color="#0000FF"&gt;int&lt;/font&gt;));&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       readonly&lt;/font&gt;&lt;font color="#0000FF"&gt; int&lt;/font&gt; urationalSize = 2 * 
      Marshal.SizeOf(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt; (&lt;font color="#0000FF"&gt;uint&lt;/font&gt;));&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Private Helpers&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       ushort&lt;/font&gt; ReadUInt16(&lt;font color="#0000FF"&gt;byte&lt;/font&gt;[] buffer,&lt;font color="#0000FF"&gt;
       int&lt;/font&gt; offset) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       (&lt;font color="#0000FF"&gt;ushort&lt;/font&gt;) (&lt;div style="margin-left:20pt"&gt;((&lt;font color="#0000FF"&gt;ushort&lt;/font&gt;) 
        buffer[offset] +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;ushort&lt;/font&gt;) buffer[offset + 1] &amp;lt;&amp;lt; 8)));&lt;/div&gt;
      &lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       int&lt;/font&gt; ReadInt32(&lt;font color="#0000FF"&gt;byte&lt;/font&gt;[] buffer,&lt;font color="#0000FF"&gt;
       int&lt;/font&gt; offset) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       (&lt;font color="#0000FF"&gt;int&lt;/font&gt;) (&lt;div style="margin-left:20pt"&gt;((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) 
        buffer[offset] +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) buffer[offset + 1] &amp;lt;&amp;lt; 8) +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) buffer[offset + 2] &amp;lt;&amp;lt; 16) +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;int&lt;/font&gt;) buffer[offset + 3] &amp;lt;&amp;lt; 24)));&lt;/div&gt;
      &lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
       uint&lt;/font&gt; ReadUInt32(&lt;font color="#0000FF"&gt;byte&lt;/font&gt;[] buffer,&lt;font color="#0000FF"&gt;
       int&lt;/font&gt; offset) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;
       (&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) (&lt;div style="margin-left:20pt"&gt;((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) 
        buffer[offset] +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) buffer[offset + 1] &amp;lt;&amp;lt; 8) +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) buffer[offset + 2] &amp;lt;&amp;lt; 16) +&lt;br&gt;
        ((&lt;font color="#0000FF"&gt;uint&lt;/font&gt;) buffer[offset + 3] &amp;lt;&amp;lt; 24)));&lt;/div&gt;
      &lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;/font&gt;&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;/div&gt;
   &lt;div style="display:none;background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- ExifConvert code end --&gt;
  &lt;p&gt;The following code is a sample console application that make use of the code 
   above to load an image and display the content of Exif properties.&lt;/p&gt;
  &lt;!-- Main code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New'"&gt;[STAThread]&lt;br&gt;
    &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt;&lt;font color="#0000FF"&gt;
     void&lt;/font&gt; Main(&lt;font color="#0000FF"&gt;string&lt;/font&gt;[] args) {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;using&lt;/font&gt;(Image 
     image = Image.FromFile(args[0])) {&lt;div style="margin-left:20pt"&gt;Console.WriteLine(&lt;font color="#800000"&gt;&amp;quot;{0} 
       : {1} properties&amp;quot;&lt;/font&gt;, args[0], image.PropertyItems.Length);&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;foreach&lt;/font&gt; (PropertyItem propertyItem&lt;font color="#0000FF"&gt;
       in&lt;/font&gt; image.PropertyItems) {&lt;div style="margin-left:20pt"&gt;Array result = 
       ExifConvert.FromPropertyItem(propertyItem);&lt;br&gt;
       Console.WriteLine(&lt;font color="#800000"&gt;&amp;quot;Property #{0}, type : {1}, {2} 
        value(s)&amp;quot;&lt;/font&gt;, propertyItem.Id, 
       (ExifPropertyType)propertyItem.Type, result.Length);&lt;br&gt;
       &lt;br&gt;
       &lt;font color="#0000FF"&gt;foreach&lt;/font&gt; (&lt;font color="#0000FF"&gt;object&lt;/font&gt;&lt;font color="#0000FF"&gt;
        value&lt;/font&gt;&lt;font color="#0000FF"&gt; in&lt;/font&gt; result)&lt;div style="margin-left:20pt"&gt;Console.WriteLine(&lt;font color="#800000"&gt;&amp;quot;\t{0}&amp;quot;&lt;/font&gt;,&lt;font color="#0000FF"&gt;
         value&lt;/font&gt;);&lt;br&gt;
       &lt;/div&gt;
       Console.WriteLine();&lt;/div&gt;
      }&lt;/div&gt;
     }&lt;/div&gt;
    }
   &lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Main code end --&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/215.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>C# code and copyright notice</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/04/18/211.aspx</link><pubDate>Mon, 18 Apr 2005 15:51:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/04/18/211.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/211.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/04/18/211.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/211.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/211.aspx</trackback:ping><description>&lt;P&gt;Some people asked me the question so...&lt;/P&gt;
&lt;P&gt;If you wish to use the C# code we are publishing on this blog, you're free to do so, under the following condition : if your application source code is public, you must include the following header at the top of the source code you got from this blog :&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;/*&lt;BR&gt;Copyright &amp;#169; 2005, The PixVillage Team&lt;BR&gt;All rights reserved.&lt;BR&gt;http://www.pixvillage.com/blogs/devblog/&lt;BR&gt;&lt;BR&gt;Redistribution and use in source and binary forms, with or without&lt;BR&gt;modification, are permitted provided that the following conditions&lt;BR&gt;are met:&lt;BR&gt;&lt;BR&gt;- Redistributions of source code must retain the above copyright&lt;BR&gt;notice, this list of conditions and the following disclaimer.&lt;BR&gt;&lt;BR&gt;- Neither the name of the PixVillage Team, nor the names of its&lt;BR&gt;contributors may be used to endorse or promote products&lt;BR&gt;derived from this software without specific prior written &lt;BR&gt;permission. &lt;BR&gt;&lt;BR&gt;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS&lt;BR&gt;"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT&lt;BR&gt;LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS&lt;BR&gt;FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE &lt;BR&gt;COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,&lt;BR&gt;INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES INCLUDING,&lt;BR&gt;BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; &lt;BR&gt;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER &lt;BR&gt;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT &lt;BR&gt;LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN &lt;BR&gt;ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE &lt;BR&gt;POSSIBILITY OF SUCH DAMAGE.&lt;BR&gt;*/&lt;BR&gt;&lt;/CODE&gt;&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/211.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Implementing UPnP Nat Traversal</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/31/183.aspx</link><pubDate>Thu, 31 Mar 2005 10:29:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/31/183.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/183.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/31/183.aspx#Feedback</comments><slash:comments>30</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/183.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/183.aspx</trackback:ping><description>&lt;P&gt;When creating a end-user network application, a number of problems arise such as, for instance, connectivity through firewalls and/or routers. Luckily, there is a number of standards and/or Windows API that deal with these problems, and the only thing we have to do to ensure a state-of-art support of networking technologies is to implement standards or stubs for API. &lt;/P&gt;
&lt;P&gt;For instance, in order to make a network-aware application available through an IGD (&lt;I&gt;Internet Gateway Device&lt;/I&gt;), The UPnP forum defines a standard for configuring IGD using UPnP: this is called NAT Traversal (where NAT stands for &lt;I&gt;Network Address Translation&lt;/I&gt;). Microsoft exposes an API that implement NAT Traversal. The scope of this post is to use it in C#. &lt;/P&gt;
&lt;P&gt;The &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ics/ics/network_address_translation_traversal_reference.asp" target=_blank&gt;NAT Traversal API&lt;/A&gt; is a COM Type Library. The first step is to add a stub for this component:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;First, add a reference to the &lt;I&gt;CustomMarshalers&lt;/I&gt; assembly (in the &lt;I&gt;Solution Explorer&lt;/I&gt;, right-click on the project's &lt;I&gt;References&lt;/I&gt; node, &lt;I&gt;Add References...&lt;/I&gt;, &lt;I&gt;.NET&lt;/I&gt; tab), 
&lt;LI&gt;Then, create a file containing the following COM Interop code:&lt;/LI&gt;&lt;/UL&gt;&lt;!-- Interop code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel="0" selold="0"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT id=Radio7 onclick=parentNode.sel=0 type=radio CHECKED value=Radio7 name=8ad16f798ced4298acbf95994d585b78&gt;Hide&lt;INPUT id=Radio8 onclick=parentNode.sel=1 type=radio value=Radio8 name=8ad16f798ced4298acbf95994d585b78&gt;Scroll&lt;INPUT id=Radio9 onclick=parentNode.sel=2 type=radio value=Radio9 name=8ad16f798ced4298acbf95994d585b78&gt;Full&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Runtime.CompilerServices;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Runtime.InteropServices;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Runtime.InteropServices.CustomMarshalers;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; NatTraversal.Interop {&lt;BR&gt;
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;[ComImport, Guid(&lt;FONT color=#800000&gt;"624BD588-9060-4109-B0B0-1ADBBCAC32DF"&lt;/FONT&gt;), TypeLibType(4160)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; INATEventManager {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;[DispId(1)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; ExternalIPAddressCallback { [param: In, MarshalAs(UnmanagedType.IUnknown)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]&lt;FONT color=#0000ff&gt; set&lt;/FONT&gt;; }&lt;BR&gt;[DispId(2)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt; NumberOfEntriesCallback { [param: In, MarshalAs(UnmanagedType.IUnknown)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)]&lt;FONT color=#0000ff&gt; set&lt;/FONT&gt;; }&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, TypeLibType(4160), Guid(&lt;FONT color=#800000&gt;"6F10711F-729B-41E5-93B8-F21D0F818DF1"&lt;/FONT&gt;)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; IStaticPortMapping {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;[DispId(1)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; ExternalIPAddress { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(2)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; ExternalPort { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(3)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; InternalPort { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(4)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; Protocol { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(4)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(5)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; InternalClient { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(5)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(6)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;bool&lt;/FONT&gt; Enabled { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(6)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(7)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; Description { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(7)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(8)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; EditInternalClient([In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrInternalClient);&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(9)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Enable([In]&lt;FONT color=#0000ff&gt; bool&lt;/FONT&gt; vb);&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(10)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; EditDescription([In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrDescription);&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(11)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; EditInternalPort([In]&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; lInternalPort);&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, Guid(&lt;FONT color=#800000&gt;"CD1F3E77-66D6-4664-82C7-36DBB641D0F1"&lt;/FONT&gt;), TypeLibType(4160)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; IStaticPortMappingCollection&lt;FONT color=#008000&gt; /*: IEnumerable*/&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;[&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=&lt;FONT color=#0000ff&gt;typeof&lt;/FONT&gt;(EnumeratorToEnumVariantMarshaler))]&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(-4), TypeLibFunc(0x41)]&lt;BR&gt;IEnumerator GetEnumerator();&lt;BR&gt;
&lt;DIV style="MARGIN-LEFT: 40pt"&gt;[DispId(0)]&lt;/DIV&gt;IStaticPortMapping&lt;FONT color=#0000ff&gt; this&lt;/FONT&gt;[&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; lExternalPort,&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrProtocol] { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(1)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; Count { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Remove([In]&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; lExternalPort, [In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrProtocol);&lt;BR&gt;[&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.Interface)]&lt;BR&gt;[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)]&lt;BR&gt;IStaticPortMapping Add([In]&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; lExternalPort, [In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrProtocol, [In]&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; lInternalPort, [In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrInternalClient, [In]&lt;FONT color=#0000ff&gt; bool&lt;/FONT&gt; bEnabled, [In, MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; bstrDescription);&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, Guid(&lt;FONT color=#800000&gt;"B171C812-CC76-485A-94D8-B6B3A2794E99"&lt;/FONT&gt;), TypeLibType(4160)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; IUPnPNAT {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;[DispId(1)]&lt;BR&gt;IStaticPortMappingCollection StaticPortMappingCollection { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(2)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;object&lt;/FONT&gt;&lt;FONT color=#008000&gt; /*IDynamicPortMappingCollection*/&lt;/FONT&gt; DynamicPortMappingCollection { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(2)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;BR&gt;[DispId(3)]&lt;BR&gt;INATEventManager NATEventManager { [&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(3)]&lt;FONT color=#0000ff&gt; get&lt;/FONT&gt;; }&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(&lt;FONT color=#800000&gt;"9C416740-A34E-446F-BA06-ABD04C3149AE"&lt;/FONT&gt;)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; INATExternalIPAddressCallback {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; NewExternalIPAddress([MarshalAs(UnmanagedType.BStr)]&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; newExternalIPAddress);&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(&lt;FONT color=#800000&gt;"C83A0A74-91EE-41B6-B67A-67E0F00BBD78"&lt;/FONT&gt;)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; INATNumberOfEntriesCallback {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; NewNumberOfEntries(&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; newNumberOfEntries);&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;[ComImport, Guid(&lt;FONT color=#800000&gt;"B171C812-CC76-485A-94D8-B6B3A2794E99"&lt;/FONT&gt;), CoClass(&lt;FONT color=#0000ff&gt;typeof&lt;/FONT&gt;(UPnPNATCreator))]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; interface&lt;/FONT&gt; UPnPNAT : IUPnPNAT {}&lt;BR&gt;&lt;BR&gt;[ComImport, TypeLibType(2), Guid(&lt;FONT color=#800000&gt;"AE1E00AA-3FD5-403C-8A27-2BBDC30CD0E1"&lt;/FONT&gt;), ClassInterface(ClassInterfaceType.None)]&lt;BR&gt;&lt;FONT color=#0000ff&gt;internal&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; class&lt;/FONT&gt; UPnPNATCreator {}&lt;/DIV&gt;}&lt;/DIV&gt;
&lt;DIV style="BACKGROUND-COLOR: #ffffff"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- Interop code end --&gt;
&lt;P&gt;According to the documentation, the &lt;I&gt;IUPnPNAT.DynamicPortMappingCollection&lt;/I&gt; property is not implemented: I removed the definition of &lt;I&gt;IDynamicPortMappingCollection&lt;/I&gt; and replaced it with a simple &lt;I&gt;object&lt;/I&gt; in the interface definition.&lt;/P&gt;
&lt;P&gt;Now we can work with the API. First, create a simple object that will represents the UPnP-compatible IGD, if present. The object initializer will create the COM object and check for availability of the &lt;I&gt;StaticPortMappingCollection&lt;/I&gt; property:&lt;/P&gt;&lt;!-- UPnPNat code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel="1" selold="1"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT id=Radio13 onclick=parentNode.sel=0 type=radio value=Radio13 name=ebc5785511c040d5a7e230a9566a164f&gt;Hide&lt;INPUT id=Radio14 onclick=parentNode.sel=1 type=radio CHECKED value=Radio14 name=ebc5785511c040d5a7e230a9566a164f&gt;Scroll&lt;INPUT id=Radio15 onclick=parentNode.sel=2 type=radio value=Radio15 name=ebc5785511c040d5a7e230a9566a164f&gt;Full&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'; HEIGHT: 200px"&gt;&lt;FONT color=#0000ff&gt;#region&lt;/FONT&gt; References&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Net;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; NatTraversal.Interop;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;BR&gt;&lt;BR&gt;namespace&lt;/FONT&gt; NatTraversal {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; class&lt;/FONT&gt; UPnPNat {&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 40pt"&gt;&lt;FONT color=#0000ff&gt;#region&lt;/FONT&gt; Fields&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 40pt"&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt; UPnPNAT uPnpNat;&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 40pt"&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;BR&gt;&lt;BR&gt;#region&lt;/FONT&gt; Instance Management&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; UPnPNat() {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;UPnPNAT nat =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; UPnPNAT();&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (nat.NATEventManager !=&lt;FONT color=#0000ff&gt; null&lt;/FONT&gt; &amp;&amp; nat.StaticPortMappingCollection !=&lt;FONT color=#0000ff&gt; null&lt;/FONT&gt;)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;uPnpNat = nat;&lt;/DIV&gt;&lt;/DIV&gt;}&lt;BR&gt;&lt;FONT color=#0000ff&gt;catch&lt;/FONT&gt; { }&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// No configurable UPNP NAT is available.&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (uPnpNat ==&lt;FONT color=#0000ff&gt; null&lt;/FONT&gt;)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;throw&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; NotSupportedException();&lt;/DIV&gt;&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;}&lt;/DIV&gt;}&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; BACKGROUND-COLOR: #ffffff"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- UPnPNat code end --&gt;
&lt;P&gt;In order to enumerate port mappings, we have to represent each mapping by a single object instead of a set of variables : the &lt;I&gt;PortMappingInfo&lt;/I&gt; class is a helper that contains all the settings of a port mapping :&lt;/P&gt;&lt;!-- PortMappingInfo code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel="0" selold="0"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT id=Radio10 onclick=parentNode.sel=0 type=radio CHECKED value=Radio10 name=598a3b710dc944d79e3a9ffe8bf27126&gt;Hide&lt;INPUT id=Radio11 onclick=parentNode.sel=1 type=radio value=Radio11 name=598a3b710dc944d79e3a9ffe8bf27126&gt;Scroll&lt;INPUT id=Radio12 onclick=parentNode.sel=2 type=radio value=Radio12 name=598a3b710dc944d79e3a9ffe8bf27126&gt;Full&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT color=#0000ff&gt;#region&lt;/FONT&gt; References&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Net;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;BR&gt;&lt;BR&gt;namespace&lt;/FONT&gt; NatTraversal {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; class&lt;/FONT&gt; PortMappingInfo {&lt;BR&gt;
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;#region&lt;/FONT&gt; Fields&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; bool&lt;/FONT&gt; enabled;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; description;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; internalHostName;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; internalPort;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt; IPAddress externalIPAddress;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; externalPort;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; protocol;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;BR&gt;&lt;BR&gt;#region&lt;/FONT&gt; Instance Management&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; PortMappingInfo(
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; description,&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; protocol,&lt;BR&gt;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; internalHostName,&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; internalPort,&lt;BR&gt;IPAddress externalIPAddress,&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; externalPort,&lt;BR&gt;&lt;FONT color=#0000ff&gt;bool&lt;/FONT&gt; enabled){&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Initializes fields&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.enabled = enabled;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.description = description;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.internalHostName = internalHostName;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.internalPort = internalPort;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.externalIPAddress = externalIPAddress;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.externalPort = externalPort;&lt;BR&gt;&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt;.protocol = protocol;&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;BR&gt;&lt;BR&gt;#region&lt;/FONT&gt; Properties&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; InternalHostName {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; internalHostName;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; InternalPort {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; internalPort;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; IPAddress ExternalIPAddress {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; externalIPAddress;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; ExternalPort {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; externalPort;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; Protocol {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; protocol;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; bool&lt;/FONT&gt; Enabled {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; enabled;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; string&lt;/FONT&gt; Description {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; description;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#endregion&lt;/FONT&gt;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;/DIV&gt;
&lt;DIV style="BACKGROUND-COLOR: #ffffff"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- PortMappingInfo code end --&gt;
&lt;P&gt;Now, we can enumerate the existing port mappings. Since the &lt;I&gt;StaticPortMappingCollection&lt;/I&gt; is an enumerator we should use the &lt;I&gt;foreach&lt;/I&gt; statement, but unfortunately it does not work and throw an exception. That's why we enumerate the items using &lt;I&gt;IEnumerator.MoveNext&lt;/I&gt;:&lt;/P&gt;&lt;!-- Enumerator code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;" sel="1" selold="1"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;INPUT id=Radio16 onclick=parentNode.sel=0 type=radio value=Radio16 name=24477c38553842f19af8fdfbe8d92917&gt;Hide&lt;INPUT id=Radio17 onclick=parentNode.sel=1 type=radio CHECKED value=Radio17 name=24477c38553842f19af8fdfbe8d92917&gt;Scroll&lt;INPUT id=Radio18 onclick=parentNode.sel=2 type=radio value=Radio18 name=24477c38553842f19af8fdfbe8d92917&gt;Full&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'; HEIGHT: 200px"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; PortMappingInfo[] PortMappings {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;get&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#008000&gt;// Builds port mappings list&lt;/FONT&gt;&lt;BR&gt;ArrayList portMappings =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; ArrayList();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Enumerates the ports without using the foreach statement (causes the interop to fail).&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; count = uPnpNat.StaticPortMappingCollection.Count;&lt;BR&gt;IEnumerator enumerator = uPnpNat.StaticPortMappingCollection.GetEnumerator();&lt;BR&gt;enumerator.Reset();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;for&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; i = 0; i &lt;= count; i++) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;IStaticPortMapping mapping =&lt;FONT color=#0000ff&gt; null&lt;/FONT&gt;;&lt;BR&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (enumerator.MoveNext())
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;mapping = (IStaticPortMapping)enumerator.Current;&lt;/DIV&gt;&lt;/DIV&gt;}&lt;BR&gt;&lt;FONT color=#0000ff&gt;catch&lt;/FONT&gt; { }&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (mapping !=&lt;FONT color=#0000ff&gt; null&lt;/FONT&gt;) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;portMappings.Add(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; PortMappingInfo(
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;mapping.Description,&lt;BR&gt;mapping.Protocol.ToUpper(),&lt;BR&gt;mapping.InternalClient,&lt;BR&gt;mapping.InternalPort,&lt;BR&gt;IPAddress.Parse(mapping.ExternalIPAddress),&lt;BR&gt;mapping.ExternalPort,&lt;BR&gt;mapping.Enabled));&lt;/DIV&gt;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Now copies the ArrayList to an array of PortMappingInfo.&lt;/FONT&gt;&lt;BR&gt;PortMappingInfo[] portMappingInfos =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; PortMappingInfo[portMappings.Count];&lt;BR&gt;portMappings.CopyTo(portMappingInfos);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; portMappingInfos;&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;/DIV&gt;
&lt;DIV style="DISPLAY: none; BACKGROUND-COLOR: #ffffff"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- Enumerator code end --&gt;
&lt;P&gt;Invoking this property is done this way:&lt;/P&gt;&lt;!-- Invoke Enumerator code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'"&gt;UPnPNat nat =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; UPnPNat();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;foreach&lt;/FONT&gt; (PortMappingInfo info&lt;FONT color=#0000ff&gt; in&lt;/FONT&gt; nat.PortMappings)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;Console.WriteLine(&lt;FONT color=#800000&gt;"{0} : {1} -&gt; {2}:{3} ({4})"&lt;/FONT&gt;, info.Description, info.ExternalPort, info.InternalHostName, info.InternalPort, info.Protocol); &lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- Invoke Enumerator code end --&gt;
&lt;P&gt;In order to use UPnP to configure the IGD, we have to implement stubs for adding and removing port mappings :&lt;/P&gt;&lt;!-- Add/Remove code --&gt;
&lt;DIV style="BORDER-RIGHT: #c0c0c0 1px solid; BORDER-TOP: #c0c0c0 1px solid; MARGIN-LEFT: 10pt; BORDER-LEFT: #c0c0c0 1px solid; MARGIN-RIGHT: 2pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;
&lt;DIV style="FONT-SIZE: 10pt; BORDER-BOTTOM: #c0c0c0 1px solid"&gt;&lt;B&gt;Code &lt;/B&gt;&lt;A onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');" href="javascript:"&gt;Copy &lt;/A&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 15px; OVERFLOW: auto; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; void&lt;/FONT&gt; AddPortMapping(PortMappingInfo portMapping) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;uPnpNat.StaticPortMappingCollection.Add(portMapping.ExternalPort, portMapping.Protocol, portMapping.InternalPort, portMapping.InternalHostName, portMapping.Enabled, portMapping.Description);&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; void&lt;/FONT&gt; RemovePortMapping(PortMappingInfo portMapping) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;uPnpNat.StaticPortMappingCollection.Remove(portMapping.ExternalPort, portMapping.Protocol);&lt;/DIV&gt;} &lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- Add/Remove code end --&gt;
&lt;P&gt;Now, last but not least, you have to configure both your IGD and Windows box to use UPnP !&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/183.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Exif Properties in .Net - Part 2 : creating new properties</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/27/176.aspx</link><pubDate>Sun, 27 Mar 2005 20:04:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/27/176.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/176.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/27/176.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/176.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/176.aspx</trackback:ping><description>&lt;p&gt;When you manage Exif properties, you commonly have two basic tasks to handle : &lt;i&gt;reading&lt;/i&gt;
   Exif properties (which is quite simple), and &lt;i&gt;writing&lt;/i&gt; Exif properties, 
   which is, in C#, as simple as:&lt;/p&gt;
  &lt;!-- SetPropertyItem code --&gt;
  &lt;div style='BORDER-RIGHT:#c0c0c0 1px solid;BORDER-TOP:#c0c0c0 1px solid;MARGIN-LEFT:10pt;BORDER-LEFT:#c0c0c0 1px solid;MARGIN-RIGHT:2pt;BORDER-BOTTOM:#c0c0c0 1px solid'&gt;&lt;div style="FONT-SIZE:10pt;BORDER-BOTTOM:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="FONT-SIZE:15px;OVERFLOW:auto;FONT-FAMILY:'Courier New'"&gt;PropertyItem 
    property = ...;&lt;br&gt;
    Image image = ...;&lt;br&gt;
    &lt;br&gt;
    image.SetPropertyItem(property);&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- SetPropertyItem code end --&gt;
  &lt;p&gt;
   In the code above, the &lt;i&gt;Image&lt;/i&gt; object may have been created from a file, a 
   stream, an existing image, or just from scratch...&lt;br&gt;
   The &lt;i&gt;PropertyItem&lt;/i&gt; may have been retrieved from an image, or... &lt;i&gt;nothing&lt;/i&gt;
   : the &lt;i&gt;System.Drawing.Imaging.PropertyItem&lt;/i&gt; class do not have a public 
   constructor!
  &lt;/p&gt;
  &lt;p&gt;
   In this post, I am describing a workaround that enable to create new &lt;i&gt;PropertyItem&lt;/i&gt;
   objects.
  &lt;/p&gt;
  &lt;p&gt;The method is, in fact, quite simple. It consists in having a small Jpeg image 
   with Exif information embedded in you application, and loading &lt;i&gt;PropertyItem&lt;/i&gt;
   from it when necessary.&lt;/p&gt;
  &lt;p&gt;First, you have to add your Jpeg file (let's call it "&lt;i&gt;property.jpg&lt;/i&gt;") to 
   your project, and mark it as an embedded resource.&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
   In the Solution Explorer, select the project icon,
   &lt;li&gt;
    In the &lt;i&gt;Project&lt;/i&gt; menu, click the &lt;i&gt;Add an existing item&lt;/i&gt;
   menu,
   &lt;li&gt;
   In the dialog box, choose a valid Jpeg file and click Open; the file does 
   appear in the Solution Explorer,
   &lt;li&gt;
   In the Solution Explorer, select the Jpeg file ,
   &lt;li&gt;
    In the Properties view, set the "&lt;i&gt;Build Action&lt;/i&gt;" property to "&lt;i&gt;Embedded 
     Resource&lt;/i&gt;".&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;The second step is to add a reference on the &lt;i&gt;System.Drawing&lt;/i&gt; assembly to 
   the project, if not present, and to add the following lines at the top of the 
   source file:&lt;/p&gt;
  &lt;!-- Using code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New'"&gt;&lt;font color="#0000FF"&gt;using&lt;/font&gt;
    System;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Drawing;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Drawing.Imaging;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.IO;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Reflection;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Using code end --&gt;
  &lt;p&gt;Now when have to load the image and return the first property item it contains :&lt;/p&gt;
  &lt;!-- CreatePropertyItem code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New'"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
     &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Creates a new property item.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;returns&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;A 
     new instance of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see 
     cref=&amp;quot;PropertyItem&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt; class.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; PropertyItem 
    CreatePropertyImage()&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// Gets the current assembly, 
      retrieves the stream for the resource and loads the associated image.&lt;/font&gt;&lt;br&gt;
     Assembly currentAssembly = Assembly.GetExecutingAssembly();&lt;br&gt;
     &lt;font color="#0000FF"&gt;using&lt;/font&gt;(Stream propertyStream = 
     currentAssembly.GetManifestResourceStream(currentAssembly.GetName().Name + 
     &amp;quot;.&amp;quot; + &amp;quot;property.jpg&amp;quot;))&lt;br&gt;
     &lt;font color="#0000FF"&gt;using&lt;/font&gt;(Image resourceImage = 
     (Image)Image.FromStream(propertyStream))&lt;br&gt;
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt; resourceImage.PropertyItems[0];&lt;/div&gt;
     }&lt;/div&gt;
    }
   &lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- CreatePropertyItem code end --&gt;
  &lt;p&gt;The job is almost complete : we can now optimize this code to load the image 
   only once and to return a clean object.&lt;/p&gt;
  &lt;!-- Full code --&gt;
  &lt;div style='margin-left:10pt;margin-right:2pt;border:#c0c0c0 1px solid'&gt;&lt;div style="font-size:10pt;border-bottom:#c0c0c0 1px solid" onclick="var i=this.sel,j;for(j=0;j&lt;3;j++)this.childNodes[2+j*2].checked=j==i;if(i==this.selold)return;var sh=new Array('none',''),o=this.parentNode;j=i==0?0:1;this.selold=i;o.childNodes[1].style.display=sh[j];o.childNodes[2].style.display=sh[1-j];o=o.childNodes[1];var h =o.offsetHeight;o.style.height=i==1?'200pt':'';if(i==1 &amp;&amp; o.offsetHeight&gt;h)o.style.height=h;"
    sel="0" selold="0"&gt;&lt;b&gt; Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;&lt;input type="Radio" onclick="parentNode.sel=0" name="b41da6f38c9a4f58a1a0503274a01439"
     checked ID="Radio1" VALUE="Radio1"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="b41da6f38c9a4f58a1a0503274a01439"
     ID="Radio2" VALUE="Radio2"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="b41da6f38c9a4f58a1a0503274a01439"
     ID="Radio3" VALUE="Radio3"&gt;Full&lt;/div&gt;
   &lt;div style="overflow:auto;font-size:15;font-family:'Courier New';display:'none'"&gt;&lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt;
     static&lt;/font&gt; Image propertyImage;&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; Image 
    PropertyImage&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;get&lt;/font&gt;&lt;br&gt;
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (propertyImage==&lt;font color="#0000FF"&gt;null&lt;/font&gt;)&lt;div style="margin-left:20pt"&gt;propertyImage 
       = LoadPropertyImage();&lt;br&gt;
       &lt;font color="#0000FF"&gt;
      &lt;/div&gt;
      return&lt;/font&gt; propertyImage;&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; Image 
    LoadPropertyImage()&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// Gets the current assembly, 
      retrieves the stream for the resource and loads the associated image.&lt;/font&gt;&lt;br&gt;
     Assembly currentAssembly = Assembly.GetExecutingAssembly();&lt;br&gt;
     &lt;font color="#0000FF"&gt;using&lt;/font&gt;(Stream propertyStream = 
     currentAssembly.GetManifestResourceStream(currentAssembly.GetName().Name + 
     &amp;quot;.&amp;quot; + &amp;quot;property.jpg&amp;quot;))&lt;br&gt;
     &lt;font color="#0000FF"&gt;using&lt;/font&gt;(Image resourceImage = 
     (Image)Image.FromStream(propertyStream))&lt;br&gt;
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// Creates a lightweight (1x1 
       pixel) bitmap with a single, empty exif property item.&lt;/font&gt;&lt;br&gt;
      &lt;font color="#008000"&gt;// This bitmap will remain in memory during the entire 
       application runtime.&lt;/font&gt;&lt;br&gt;
      Image propertyImage =&lt;font color="#0000FF"&gt; new&lt;/font&gt; Bitmap(1, 1);&lt;br&gt;
      PropertyItem propertyItem = resourceImage.PropertyItems[0];&lt;br&gt;
      propertyItem.Id = 0;&lt;br&gt;
      propertyItem.Type = 0;&lt;br&gt;
      propertyItem.Len = 0;&lt;br&gt;
      propertyItem.Value =&lt;font color="#0000FF"&gt; new&lt;/font&gt;&lt;font color="#0000FF"&gt; byte&lt;/font&gt;[0];&lt;br&gt;
      &lt;br&gt;
      propertyImage.SetPropertyItem(propertyItem);&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;return&lt;/font&gt; propertyImage;&lt;/div&gt;
     }&lt;/div&gt;
    }&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Creates an empty property item.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;returns&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;A 
     new, empty instance of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see 
     cref=&amp;quot;PropertyItem&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt; class.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; PropertyItem 
    CreatePropertyItem()&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt; PropertyImage.PropertyItems[0];&lt;/div&gt;
    }&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Creates a new property item having the given 
     id, type and value.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param name=&amp;quot;id&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The 
     identifier of the property item.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param name=&amp;quot;type&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The 
     type of value the property item does contain.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param name=&amp;quot;len&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The 
     length of the property value.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The 
     property value.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;returns&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;A 
     new, initialized, instance of the&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;see 
     cref=&amp;quot;PropertyItem&amp;quot;/&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt; class.&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;font color="#0000FF"&gt; static&lt;/font&gt; PropertyItem 
    CreatePropertyItem(&lt;font color="#0000FF"&gt;int&lt;/font&gt; id,&lt;font color="#0000FF"&gt; short&lt;/font&gt;
    type,&lt;font color="#0000FF"&gt; int&lt;/font&gt; len,&lt;font color="#0000FF"&gt; byte&lt;/font&gt;[]&lt;font color="#0000FF"&gt;
     value&lt;/font&gt;)&lt;br&gt;
    {&lt;div style="margin-left:20pt"&gt;PropertyItem property = CreatePropertyItem();&lt;br&gt;
     property.Id = id;&lt;br&gt;
     property.Type = type;&lt;br&gt;
     property.Len = len;&lt;br&gt;
     property.Value =&lt;font color="#0000FF"&gt; value&lt;/font&gt;;&lt;/div&gt;
    }&lt;br&gt;
   &lt;/div&gt;
   &lt;div style="background-color:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- Full code end --&gt;
  &lt;p&gt;In the next post, we will convert the raw Exif data buffer (the &lt;i&gt;PropertyItem.Value&lt;/i&gt;) 
   into the native type.&lt;/p&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/176.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Minimizing a window to the System Tray on a Close event</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/26/174.aspx</link><pubDate>Sat, 26 Mar 2005 12:02:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/26/174.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/174.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/26/174.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/174.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/174.aspx</trackback:ping><description>&lt;p&gt;
   A question that .Net programmers does frequently ask is the following : how to 
   minimize a window in the systray when the user clicks the "Close" button ? This 
   post exposes solutions to the various problems this quite simple need implies.
  &lt;/p&gt;
  &lt;p&gt;The first step is to prevent the window to close. This can be done either by 
   handling the &lt;i&gt;Closing&lt;/i&gt; event or by overriding the &lt;i&gt;OnClosing&lt;/i&gt; protected 
   virtual method. For performance and memory consumption reasons, I'd prefer not 
   to use event handlers whenever possible. The code is quite simple since whe 
   only need to cancel the operation, and looks like the following...&lt;/p&gt;
  &lt;!-- OnClosing code --&gt;
  &lt;div style='BORDER-RIGHT:#c0c0c0 1px solid;BORDER-TOP:#c0c0c0 1px solid;MARGIN-LEFT:10pt;BORDER-LEFT:#c0c0c0 1px solid;MARGIN-RIGHT:2pt;BORDER-BOTTOM:#c0c0c0 1px solid'&gt;&lt;div style="FONT-SIZE:10pt;BORDER-BOTTOM:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="FONT-SIZE:15px;OVERFLOW:auto;FONT-FAMILY:'Courier New'"&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt;
     &amp;lt;summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#008000"&gt; Occurs when the window is requested to be 
     closed.&lt;/font&gt;&lt;br&gt;
    &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;/summary&amp;gt;&lt;br&gt;
     ///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param name="e"&amp;gt;&lt;/font&gt;&lt;font color="#008000"&gt;The 
     event arguments&lt;/font&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br&gt;
    &lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;font color="#0000ff"&gt; override&lt;/font&gt;&lt;font color="#0000ff"&gt;
     void&lt;/font&gt; OnClosing(CancelEventArgs e)&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;&lt;font color="#008000"&gt;// The window must only be 
      minimized in tray&lt;/font&gt;&lt;br&gt;
     e.Cancel =&lt;font color="#0000ff"&gt; true&lt;/font&gt;;&lt;br&gt;
     MinimizeInTray();&lt;br&gt;
     &lt;br&gt;
     &lt;font color="#0000ff"&gt;base&lt;/font&gt;.OnClosing(e);&lt;/div&gt;
    }&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- OnClosing code end --&gt;
  &lt;p&gt;... and the &lt;i&gt;MinimizeInTray&lt;/i&gt; method must do the following:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
   Minimize the window,
   &lt;li&gt;
    Hide the window item in the taskbar.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;!-- MinimizeInTray code --&gt;
  &lt;div style='BORDER-RIGHT:#c0c0c0 1px solid;BORDER-TOP:#c0c0c0 1px solid;MARGIN-LEFT:10pt;BORDER-LEFT:#c0c0c0 1px solid;MARGIN-RIGHT:2pt;BORDER-BOTTOM:#c0c0c0 1px solid'&gt;&lt;div style="FONT-SIZE:10pt;BORDER-BOTTOM:#c0c0c0 1px solid"&gt;&lt;b&gt;
     Code &lt;/b&gt;&lt;a href='javascript:' onclick="window.clipboardData.setData('Text',this.parentNode.parentNode.childNodes[1].innerText);alert('Code copied to clipboard');"&gt;
     Copy &