<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>2</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>4</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>33</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>7</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>6</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 &lt;/a&gt;
   &lt;/div&gt;
   &lt;div style="FONT-SIZE:15px;OVERFLOW:auto;FONT-FAMILY:'Courier New'"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;font color="#0000ff"&gt;
     void&lt;/font&gt; MinimizeInTray()&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.ShowInTaskbar =&lt;font color="#0000ff"&gt;
      false&lt;/font&gt;;&lt;br&gt;
     &lt;font color="#0000ff"&gt;this&lt;/font&gt;.WindowState = FormWindowState.Minimized;&lt;/div&gt;
    }&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- MinimizeInTray code end --&gt;
  &lt;p&gt;Now, supposing that you have a context menu attached to the &lt;i&gt;NotifyIcon&lt;/i&gt; object 
   that represents the systray icon for your application, you can add the 
   following menu items:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    An &lt;i&gt;openMenu&lt;/i&gt; menu item that restores the window,&lt;/li&gt;&lt;/ul&gt;
  &lt;!-- openMenu_Click 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="#0000ff"&gt;private&lt;/font&gt;&lt;font color="#0000ff"&gt;
     void&lt;/font&gt; openMenu_Click(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, 
    System.EventArgs e)&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;ShowFromTray();&lt;/div&gt;
    }&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;font color="#0000ff"&gt; void&lt;/font&gt; ShowFromTray()&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.WindowState = 
     FormWindowState.Normal;&lt;br&gt;
     &lt;font color="#0000ff"&gt;this&lt;/font&gt;.ShowInTaskbar =&lt;font color="#0000ff"&gt; true&lt;/font&gt;;&lt;/div&gt;
    }&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- openMenu_Click code end --&gt;
  &lt;ul&gt;
   &lt;li&gt;
    And an &lt;i&gt;exitMenu&lt;/i&gt; item that closes the application.&lt;/li&gt;&lt;/ul&gt;
  &lt;!-- exitMenu_Click 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="#0000ff"&gt;private&lt;/font&gt;&lt;font color="#0000ff"&gt;
     void&lt;/font&gt; exitMenu_Click(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, 
    System.EventArgs e)&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;Application.Exit();&lt;/div&gt;
    }&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- exitMenu_Click code end --&gt;
  &lt;p&gt;Note that calling &lt;i&gt;Close()&lt;/i&gt; fails because our &lt;i&gt;OnClosing&lt;/i&gt; method 
   prevents the window to close...&lt;/p&gt;
  &lt;p&gt;Now, we should think that our job is completed. But (yes, there's always a &lt;i&gt;but&lt;/i&gt;
   in programming), what happens if the computer is being shutdown ? The answer is 
   quite simple : our &lt;i&gt;OnClosing&lt;/i&gt; implementation prevents the window to be 
   closed, which prevents the computer to be shutdown...&lt;/p&gt;
  &lt;p&gt;To solve this issue, we need some lightweight Interop :&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;
    First, override the &lt;i&gt;WndProc&lt;/i&gt; virtual method to handle the 
    WM_QUERYENDSESSION message:&lt;/li&gt;&lt;/ul&gt;
  &lt;!-- WndProc 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="#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_QUERYENDSESSION = 0x11;&lt;br&gt;
    &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;font color="#0000ff"&gt; bool&lt;/font&gt; endSessionPending;&lt;br&gt;
    &lt;font color="#0000ff"&gt;
     &lt;br&gt;
     protected&lt;/font&gt;&lt;font color="#0000ff"&gt; override&lt;/font&gt;&lt;font color="#0000ff"&gt; void&lt;/font&gt;
    WndProc(&lt;font color="#0000ff"&gt;ref&lt;/font&gt; Message m)&lt;br&gt;
    {&lt;div style="MARGIN-LEFT:20pt"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; (m.Msg == 
     WM_QUERYENDSESSION)&lt;div style="MARGIN-LEFT:20pt"&gt;endSessionPending =&lt;font color="#0000ff"&gt;
       true&lt;/font&gt;;&lt;font color="#0000ff"&gt;&lt;/div&gt;
     base&lt;/FONT&gt;.WndProc(&lt;font color="#0000ff"&gt;ref&lt;/font&gt; m);&lt;/div&gt;
    }&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- WndProc code end --&gt;
  &lt;ul&gt;
   &lt;li&gt;
    Then, modify the &lt;i&gt;OnClosing&lt;/i&gt; method to handle the event in a different way 
    :&lt;/li&gt;&lt;/ul&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" 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;&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="e2fab706625143d9a14e7044aa0961b0"
     ID="Radio1" VALUE="Radio1"&gt;Hide&lt;input type="radio" onclick="parentNode.sel=1" name="e2fab706625143d9a14e7044aa0961b0"
     checked ID="Radio2" VALUE="Radio2"&gt;Scroll&lt;input type="radio" onclick="parentNode.sel=2" name="e2fab706625143d9a14e7044aa0961b0"
     ID="Radio3" VALUE="Radio3"&gt;Full&lt;/div&gt;
   &lt;div style="FONT-SIZE:15px;OVERFLOW:auto;FONT-FAMILY:'Courier New';HEIGHT:200px"&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="#0000ff"&gt;if&lt;/font&gt; (endSessionPending)&lt;br&gt;
     {&lt;div style="MARGIN-LEFT:20pt"&gt;&lt;font color="#008000"&gt;// The session is ending.&lt;/font&gt;&lt;br&gt;
      e.Cancel =&lt;font color="#0000ff"&gt; false&lt;/font&gt;;&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 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;/div&gt;
     }&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 style="DISPLAY:none;BACKGROUND-COLOR:#ffffff"&gt;&lt;b&gt; . . .&lt;/b&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- OnClosing code end --&gt;
  &lt;p&gt;And that's all!&lt;/p&gt;
  &lt;p&gt;The full C# sample code is available below. There's only missing icon resources, 
   but you will correct them by yourself!&lt;/p&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="29a965f573134f84ac3617c202e996d6"
     checked ID="Radio4" VALUE="Radio4"&gt;Hide&lt;input type="Radio" onclick="parentNode.sel=1" name="29a965f573134f84ac3617c202e996d6"
     ID="Radio5" VALUE="Radio5"&gt;Scroll&lt;input type="Radio" onclick="parentNode.sel=2" name="29a965f573134f84ac3617c202e996d6"
     ID="Radio6" VALUE="Radio6"&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;#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.ComponentModel;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Windows.Forms;&lt;br&gt;
    &lt;font color="#0000FF"&gt;using&lt;/font&gt; System.Security.Permissions;&lt;br&gt;
    &lt;br&gt;
    &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
     &lt;br&gt;
     namespace&lt;/font&gt; MinimizeOnClose&lt;br&gt;
    {&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; Represents the main window 
      of the application.&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; MinimizeOnClose 
     : System.Windows.Forms.Form&lt;br&gt;
     {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;#region&lt;/font&gt; Interop 
      Constants&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_QUERYENDSESSION = 0x11;&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Fields&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.NotifyIcon 
      notifyIcon;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.ContextMenu 
      notifyIconMenu;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.MenuItem openMenu;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.MenuItem hideMenu;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.MenuItem exitMenu;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.ComponentModel.IContainer 
      components;&lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt; System.Windows.Forms.MenuItem blankMenu;&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; bool&lt;/font&gt; endSessionPending;&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; MinimizeOnClose()&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;InitializeComponent();&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; Protected Overrides&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; Cleans all the 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;protected&lt;/font&gt;&lt;font color="#0000FF"&gt; override&lt;/font&gt;&lt;font color="#0000FF"&gt;
       void&lt;/font&gt; Dispose(&lt;font color="#0000FF"&gt;bool&lt;/font&gt; disposing)&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (disposing)&lt;br&gt;
       {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (components !=&lt;font color="#0000FF"&gt;
         null&lt;/font&gt;)&lt;div style="margin-left:20pt"&gt;components.Dispose();&lt;/div&gt;
       &lt;/div&gt;
       }&lt;br&gt;
       &lt;font color="#0000FF"&gt;base&lt;/font&gt;.Dispose(disposing);&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; 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;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#808080"&gt; &amp;lt;param 
       name=&amp;quot;e&amp;quot;&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="#0000FF"&gt;if&lt;/font&gt; (endSessionPending)&lt;br&gt;
       {&lt;div style="margin-left:20pt"&gt;&lt;font color="#008000"&gt;// The session is ending&lt;/font&gt;&lt;br&gt;
        e.Cancel =&lt;font color="#0000FF"&gt; false&lt;/font&gt;;&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 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;/div&gt;
       }&lt;br&gt;
       &lt;br&gt;
       &lt;font color="#0000FF"&gt;base&lt;/font&gt;.OnClosing(e);&lt;/div&gt;
      }&lt;br&gt;
      &lt;div style="margin-left:40pt"&gt;[SecurityPermission(SecurityAction.LinkDemand, 
       UnmanagedCode=&lt;font color="#0000FF"&gt;true&lt;/font&gt;)]&lt;font color="#0000FF"&gt;&lt;/div&gt;
      protected&lt;/font&gt;&lt;font color="#0000FF"&gt; override&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt;
      WndProc(&lt;font color="#0000FF"&gt;ref&lt;/font&gt; Message m)&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt; (m.Msg == 
       WM_QUERYENDSESSION)&lt;div style="margin-left:20pt"&gt;endSessionPending =&lt;font color="#0000FF"&gt;
         true&lt;/font&gt;;&lt;font color="#0000FF"&gt;&lt;/div&gt;
       base&lt;/font&gt;.WndProc(&lt;font color="#0000FF"&gt;ref&lt;/font&gt; m);&lt;/div&gt;
      }&lt;br&gt;
      &lt;div style="margin-left:40pt"&gt;&lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
      &lt;/div&gt;
      #region&lt;/font&gt; Private Members&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;#region&lt;/font&gt; Event Handlers&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; openMenu_Click(&lt;font color="#0000FF"&gt;object&lt;/font&gt;
      sender, System.EventArgs e)&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;ShowFromTray();&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; hideMenu_Click(&lt;font color="#0000FF"&gt;object&lt;/font&gt;
      sender, System.EventArgs e)&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;MinimizeInTray();&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; exitMenu_Click(&lt;font color="#0000FF"&gt;object&lt;/font&gt;
      sender, System.EventArgs e)&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;Application.Exit();&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; Private Methods&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; MinimizeInTray()&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.ShowInTaskbar =&lt;font color="#0000FF"&gt;
        false&lt;/font&gt;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.WindowState = FormWindowState.Minimized;&lt;br&gt;
       &lt;br&gt;
       openMenu.Visible =&lt;font color="#0000FF"&gt; true&lt;/font&gt;;&lt;br&gt;
       hideMenu.Visible =&lt;font color="#0000FF"&gt; false&lt;/font&gt;;&lt;/div&gt;
      }&lt;br&gt;
      &lt;br&gt;
      &lt;font color="#0000FF"&gt;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; ShowFromTray()&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.WindowState = 
       FormWindowState.Normal;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.ShowInTaskbar =&lt;font color="#0000FF"&gt; true&lt;/font&gt;;&lt;br&gt;
       &lt;br&gt;
       openMenu.Visible =&lt;font color="#0000FF"&gt; true&lt;/font&gt;;&lt;br&gt;
       hideMenu.Visible =&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;br&gt;
       &lt;br&gt;
       #region&lt;/font&gt; Windows Form Designer generated code&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; Required method for Designer 
       support - do not modify&lt;/font&gt;&lt;br&gt;
      &lt;font color="#808080"&gt;///&lt;/font&gt;&lt;font color="#008000"&gt; the contents of this method 
       with the code editor.&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;private&lt;/font&gt;&lt;font color="#0000FF"&gt; void&lt;/font&gt; InitializeComponent()&lt;br&gt;
      {&lt;div style="margin-left:20pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.components =&lt;font color="#0000FF"&gt;
        new&lt;/font&gt; System.ComponentModel.Container();&lt;br&gt;
       System.Resources.ResourceManager resources =&lt;font color="#0000FF"&gt; new&lt;/font&gt; System.Resources.ResourceManager(&lt;font color="#0000FF"&gt;typeof&lt;/font&gt;(MinimizeOnClose));&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIcon =&lt;font color="#0000FF"&gt; new&lt;/font&gt; 
       System.Windows.Forms.NotifyIcon(&lt;font color="#0000FF"&gt;this&lt;/font&gt;.components);&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIconMenu =&lt;font color="#0000FF"&gt; new&lt;/font&gt;
       System.Windows.Forms.ContextMenu();&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu =&lt;font color="#0000FF"&gt; new&lt;/font&gt; System.Windows.Forms.MenuItem();&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu =&lt;font color="#0000FF"&gt; new&lt;/font&gt; System.Windows.Forms.MenuItem();&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.blankMenu =&lt;font color="#0000FF"&gt; new&lt;/font&gt; System.Windows.Forms.MenuItem();&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu =&lt;font color="#0000FF"&gt; new&lt;/font&gt; System.Windows.Forms.MenuItem();&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// notifyIcon&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIcon.ContextMenu =&lt;font color="#0000FF"&gt; this&lt;/font&gt;.notifyIconMenu;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIcon.Icon = 
       ((System.Drawing.Icon)(resources.GetObject(&amp;quot;notifyIcon.Icon&amp;quot;)));&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIcon.Text = 
       &amp;quot;MinimizeOnClose&amp;quot;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIcon.Visible =&lt;font color="#0000FF"&gt; true&lt;/font&gt;;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// notifyIconMenu&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.notifyIconMenu.MenuItems.AddRange(&lt;font color="#0000FF"&gt;new&lt;/font&gt;
       System.Windows.Forms.MenuItem[] {&lt;div style="margin-left:40pt"&gt;&lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu,&lt;br&gt;
        &lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu,&lt;br&gt;
        &lt;font color="#0000FF"&gt;this&lt;/font&gt;.blankMenu,&lt;br&gt;
        &lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu});&lt;font color="#008000"&gt;&lt;/div&gt;
       //&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// openMenu&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu.Index = 0;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu.Text = &amp;quot;&amp;amp;Open&amp;quot;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu.Visible =&lt;font color="#0000FF"&gt; false&lt;/font&gt;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu.Click +=&lt;font color="#0000FF"&gt; new&lt;/font&gt;
       System.EventHandler(&lt;font color="#0000FF"&gt;this&lt;/font&gt;.openMenu_Click);&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// hideMenu&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu.Index = 1;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu.Text = &amp;quot;&amp;amp;Hide&amp;quot;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu.Click +=&lt;font color="#0000FF"&gt; new&lt;/font&gt;
       System.EventHandler(&lt;font color="#0000FF"&gt;this&lt;/font&gt;.hideMenu_Click);&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// blankMenu&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.blankMenu.Index = 2;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.blankMenu.Text = &amp;quot;-&amp;quot;;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// exitMenu&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu.Index = 3;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu.Text = &amp;quot;E&amp;amp;xit&amp;quot;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu.Click +=&lt;font color="#0000FF"&gt; new&lt;/font&gt;
       System.EventHandler(&lt;font color="#0000FF"&gt;this&lt;/font&gt;.exitMenu_Click);&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;// MinimizeOnClose&lt;/font&gt;&lt;br&gt;
       &lt;font color="#008000"&gt;//&lt;/font&gt;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.AutoScaleBaseSize =&lt;font color="#0000FF"&gt; new&lt;/font&gt;
       System.Drawing.Size(5, 13);&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.ClientSize =&lt;font color="#0000FF"&gt; new&lt;/font&gt; 
       System.Drawing.Size(240, 78);&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.Icon = 
       ((System.Drawing.Icon)(resources.GetObject(&amp;quot;$this.Icon&amp;quot;)));&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.Name = &amp;quot;MinimizeOnClose&amp;quot;;&lt;br&gt;
       &lt;font color="#0000FF"&gt;this&lt;/font&gt;.Text = &amp;quot;MinimizeOnClose&amp;quot;;&lt;br&gt;
      &lt;/div&gt;
      }&lt;br&gt;
      &lt;font color="#0000FF"&gt;#endregion&lt;br&gt;
      &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="#008000"&gt; The 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;br&gt;
      {&lt;div style="margin-left:20pt"&gt;Application.Run(&lt;font color="#0000FF"&gt;new&lt;/font&gt; MinimizeOnClose());&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;p&gt;Have a nice week-end, and do not overindulge in Easter eggs too much!&lt;/p&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/174.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>COM Interop without additional assemblies</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx</link><pubDate>Thu, 24 Mar 2005 00:08:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/167.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/167.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/167.aspx</trackback:ping><description>&lt;P&gt;In this post, I'm about to deal with the use of COM components inside a .Net project. &lt;/P&gt;
&lt;P&gt;Access to Windows or third-party API is commonly made through COM, and when you're working on a .Net project, this is typically done by adding a reference to the project (&lt;EM&gt;Project&lt;/EM&gt;, &lt;EM&gt;Add Reference...&lt;/EM&gt; menu, &lt;EM&gt;COM&lt;/EM&gt; tab). Visual Studio then creates an assembly that contains the stub of interop code for the COM Type Library.&lt;/P&gt;
&lt;P&gt;Unfortunatelly, each assembly corresponds to a file on the disk, and each file is at least 64KBytes large.&lt;/P&gt;
&lt;P&gt;In the &lt;A href="http://www.pixvillage.com/"&gt;PixVillage&lt;/A&gt; project, the installation package need to be as small as possible in order to reduce download time and bandwidth, so we looked after a way to reduce the number and size of COM Interop assemblies.&lt;/P&gt;
&lt;P&gt;A (quite) simple way to achieve both these goals is to use &lt;A href="http://www.aisto.com/roeder/dotnet"&gt;Lutz Roeder's Reflector&lt;/A&gt; to generate the C# code of the COM stub directly from the assembly IL.&lt;/P&gt;
&lt;P&gt;To do so (&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt; represents the name of the Type Library) :&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Start Reflector, 
&lt;LI&gt;Find the COM Interop assembly (refer to the properties of the reference : the file name should be "Interop.&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;.dll"), 
&lt;LI&gt;Open the COM Interop assembly in Reflector, 
&lt;LI&gt;Expand both the assembly (Interop.&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;) and file (&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;.dll) nodes in the treeview, 
&lt;LI&gt;Select the node of the Type Library base namespace in the tree (the node called &lt;EM&gt;&lt;STRONG&gt;xxx&lt;/STRONG&gt;&lt;/EM&gt; with a &lt;STRONG&gt;{ } &lt;/STRONG&gt;icon), 
&lt;LI&gt;Press the &lt;EM&gt;Space&lt;/EM&gt; bar to generate C# code for the namespace, 
&lt;LI&gt;Click in the right pane, select all code (&lt;EM&gt;Ctrl+A&lt;/EM&gt;) and copy it to the clipboard (&lt;EM&gt;Ctrl+C&lt;/EM&gt;), 
&lt;LI&gt;Paste the code in a new C# (&lt;EM&gt;.cs&lt;/EM&gt;) file in Visual Studio.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Now, there might be missing references : you must add them (with the &lt;EM&gt;using&lt;/EM&gt; keyword) at the very beginning of the new file. For instance, you may have to add references to the following namespace : &lt;EM&gt;System, System.Collections&lt;/EM&gt;, &lt;EM&gt;System.Runtime.InteropServices&lt;/EM&gt;, &lt;EM&gt;System.Reflection&lt;/EM&gt;, &lt;EM&gt;System.Runtime.CompilerServices&lt;/EM&gt;...&lt;/P&gt;
&lt;P&gt;You may also have duplicate member definitions because inheriting interfaces define the same members as their parent : remove them.&lt;/P&gt;
&lt;P&gt;The last thing to do is to clean the content of the &lt;EM&gt;classes&lt;/EM&gt; (which are different from &lt;EM&gt;interfaces&lt;/EM&gt;) contained in the namespace. When rendered by Reflector, a class implements one or more interfaces and contains a number of properties / methods with no code, which do not compile. To make your code compile, remove all of its base interfaces and all of its content to make it empty.&lt;/P&gt;
&lt;P&gt;Now you might have in your code :&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;A number of enums and interfaces that represents the &lt;EM&gt;interfaces&lt;/EM&gt; and &lt;EM&gt;constant values&lt;/EM&gt; exposed by the Class Library, 
&lt;LI&gt;One or more interfaces having a &lt;EM&gt;&lt;STRONG&gt;CoClass&lt;/STRONG&gt;&lt;/EM&gt; attribute, corresponding to the &lt;EM&gt;components&lt;/EM&gt; exposed by the Class Library 
&lt;LI&gt;One or mode classes used by the framework to create the instances of the exposed components.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;For instance, if you are importing the MSN Messenger API, you may have a &lt;EM&gt;IMessenger&lt;/EM&gt; interface, a &lt;EM&gt;Messenger&lt;/EM&gt; component and a &lt;EM&gt;MessengerClass&lt;/EM&gt; class. In order to access the API, you will have to type &lt;EM&gt;IMessenger msn = new Messenger();&lt;/EM&gt;&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/167.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Exif Properties in .Net - Part 1 : (fast) loading</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/17/159.aspx</link><pubDate>Thu, 17 Mar 2005 11:51:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/17/159.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/159.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/17/159.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/159.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/159.aspx</trackback:ping><description>&lt;P style="TEXT-ALIGN: justify"&gt;In .Net, handling a picture's Exif properties seems, at first sight, to be a very simple job.&lt;/P&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;Since &lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;System.Drawing&lt;/SPAN&gt; is only a wrapper around GDI+, loading Exif information from an image file is as simple as the following :&lt;/P&gt;&lt;!-- Sample 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; static&lt;/FONT&gt; PropertyItem[] GetExifProperties(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; fileName) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt;(Image image = Image.FromFile(fileName))
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; image.PropertyItems;&lt;/DIV&gt;&lt;/DIV&gt;}&lt;BR&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- End of sample code --&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;Unfortunately, this method requires to load - and validate - all image data in order to access the Exif properties. For instance, if you want to retrieve the thumbnail contained in the Exif properties, you first have to load and uncompress the entire image file.&lt;/P&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;This problem has been workarounded in the .Net Framework 1.1 Service Pack 1, and now you can process as follow :&lt;/P&gt;&lt;!-- Sample 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; static&lt;/FONT&gt; PropertyItem[] GetExifProperties(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; fileName) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; (FileStream stream =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; FileStream(fileName, FileMode.Open, FileAccess.Read))&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; (Image image = Image.FromStream(stream,
&lt;DIV style="MARGIN-LEFT: 60pt"&gt;&lt;FONT color=#008000&gt;/* useEmbeddedColorManagement = */&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; true&lt;/FONT&gt;,&lt;BR&gt;&lt;FONT color=#008000&gt;/* validateImageData = */&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; false&lt;/FONT&gt;))&lt;FONT color=#0000ff&gt;&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;return&lt;/FONT&gt; image.PropertyItems;&lt;/DIV&gt;&lt;/DIV&gt;}&lt;BR&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- End of sample code --&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;However, since there is only a small share of PixVillage users that have the .Net Framework 1.1 Service Pack 1 installed, I eventually have implemented a custom ExifLoader helper class that use Interop to load Exif properties.&lt;/P&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;The first step is to load the image using the GDI+ Flat API and get the Exif properties raw data : &lt;/P&gt;&lt;!-- Sample 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;&amp;amp; o.offsetHeight&gt;h)o.style.height=h;" selold="1" sel="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=Radio1 onclick=parentNode.sel=0 type=radio value=Radio1 name=eab1f002b1ce46c08b7a6a77c28de267&gt;Hide&lt;INPUT id=Radio2 onclick=parentNode.sel=1 type=radio CHECKED value=Radio2 name=eab1f002b1ce46c08b7a6a77c28de267&gt;Scroll&lt;INPUT id=Radio3 onclick=parentNode.sel=2 type=radio value=Radio3 name=eab1f002b1ce46c08b7a6a77c28de267&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;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;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Runtime.InteropServices;&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; Contains helper methods for loading 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; sealed&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; class&lt;/FONT&gt; ExifLoader {&lt;BR&gt;
&lt;DIV style="MARGIN-LEFT: 40pt"&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt; ExifLoader() {}&lt;BR&gt;&lt;FONT color=#808080&gt;&lt;/DIV&gt;
&lt;DIV style="MARGIN-LEFT: 20pt"&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; Retrieves Exif properties from a file.&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="fileName"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The name of the Exif image file.&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="PropertyItem"/&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt; objects containing the Exif properties.&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[] GetExifProperties(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; fileName) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#008000&gt;// Loads the image file using the GDI+ Flat API&lt;/FONT&gt;&lt;BR&gt;IntPtr imageHandle = IntPtr.Zero;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (GdipLoadImageFromFile(fileName,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt; imageHandle)!=0)
&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;int&lt;/FONT&gt; count;&lt;BR&gt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; totalSize;&lt;BR&gt;IntPtr data = IntPtr.Zero;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#008000&gt;// Retrieves the number of properties the image contains&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (GdipGetPropertyCount(imageHandle,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt; count)!=0)
&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=#008000&gt;&lt;/DIV&gt;// Gets the total size, in bytes, of the properties&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (GdipGetPropertySize(imageHandle,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt; totalSize,&lt;FONT color=#0000ff&gt; ref&lt;/FONT&gt; count)!=0)
&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=#008000&gt;&lt;/DIV&gt;// There is no available properties...&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (count == 0 || totalSize == 0)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; PropertyItem[0];&lt;BR&gt;&lt;FONT color=#008000&gt;&lt;/DIV&gt;// Loads all properties into memory.&lt;/FONT&gt;&lt;BR&gt;data = Marshal.AllocHGlobal(totalSize);&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (GdipGetAllPropertyItems(imageHandle, totalSize, count, data)!=0)
&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=#008000&gt;&lt;/DIV&gt;// Convert the properties buffer into an array of PropertyItem objects.&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; ExifPropertyItem.ConvertFromMemory(data, count);&lt;/DIV&gt;}&lt;BR&gt;&lt;FONT color=#0000ff&gt;finally&lt;/FONT&gt; {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (data != IntPtr.Zero)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;Marshal.FreeHGlobal(data);&lt;BR&gt;&lt;FONT color=#008000&gt;&lt;/DIV&gt;// Releases the GDI+ image.&lt;/FONT&gt;&lt;BR&gt;GdipDisposeImage(imageHandle);&lt;/DIV&gt;}&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; COLOR: #808080; BORDER-BOTTOM: #808080 1px solid"&gt;ExifPropertyItem Helper Class&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// GDI+ Interop&lt;/FONT&gt;&lt;BR&gt;[DllImport(&lt;FONT color=#800000&gt;"gdiplus.dll"&lt;/FONT&gt;, CharSet=CharSet.Unicode, ExactSpelling=&lt;FONT color=#0000ff&gt;true&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; extern&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; GdipLoadImageFromFile(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; filename,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt; IntPtr image);&lt;BR&gt;&lt;BR&gt;[DllImport(&lt;FONT color=#800000&gt;"gdiplus.dll"&lt;/FONT&gt;, CharSet=CharSet.Unicode, ExactSpelling=&lt;FONT color=#0000ff&gt;true&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; extern&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; GdipDisposeImage(IntPtr image);&lt;BR&gt;&lt;BR&gt;[DllImport(&lt;FONT color=#800000&gt;"gdiplus.dll"&lt;/FONT&gt;, CharSet=CharSet.Unicode, ExactSpelling=&lt;FONT color=#0000ff&gt;true&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; extern&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; GdipGetPropertyCount(IntPtr image,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; count);&lt;BR&gt;&lt;BR&gt;[DllImport(&lt;FONT color=#800000&gt;"gdiplus.dll"&lt;/FONT&gt;, CharSet=CharSet.Unicode, ExactSpelling=&lt;FONT color=#0000ff&gt;true&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; extern&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; GdipGetPropertySize(IntPtr image,&lt;FONT color=#0000ff&gt; out&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; totalSize,&lt;FONT color=#0000ff&gt; ref&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; count);&lt;BR&gt;&lt;BR&gt;[DllImport(&lt;FONT color=#800000&gt;"gdiplus.dll"&lt;/FONT&gt;, CharSet=CharSet.Unicode, ExactSpelling=&lt;FONT color=#0000ff&gt;true&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; extern&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; GdipGetAllPropertyItems(IntPtr image,&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; totalSize,&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; count, IntPtr buffer);&lt;BR&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;!-- End of sample code --&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;Then, we have to decode the buffer filled by &lt;FONT face="Courier New"&gt;GdipGetAllPropertyItems&lt;/FONT&gt;. This is done using a private inner class, as follow :&lt;/P&gt;&lt;!-- Sample 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;&amp;amp; o.offsetHeight&gt;h)o.style.height=h;" selold="1" sel="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=Radio4 onclick=parentNode.sel=0 type=radio value=Radio4 name=1e209960657449fc85d6ff6c5d6aa1ed&gt;Hide&lt;INPUT id=Radio5 onclick=parentNode.sel=1 type=radio CHECKED value=Radio5 name=1e209960657449fc85d6ff6c5d6aa1ed&gt;Scroll&lt;INPUT id=Radio6 onclick=parentNode.sel=2 type=radio value=Radio6 name=1e209960657449fc85d6ff6c5d6aa1ed&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; ExifPropertyItem Helper Class&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; Represents an helper class for marshaling Exif property items.&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;[StructLayout(LayoutKind.Sequential)]
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; class&lt;/FONT&gt; ExifPropertyItem {&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Public members used for marshaling.&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; id = 0;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; len = 0;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; short&lt;/FONT&gt; type = 0;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; IntPtr&lt;FONT color=#0000ff&gt; value&lt;/FONT&gt; = IntPtr.Zero;&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="ExifPropertyItem"/&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;remarks&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;Used only by the&lt;/FONT&gt;&lt;FONT color=#808080&gt; &amp;lt;see cref="Marshal.PtrToStructure"/&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt; method.&lt;/FONT&gt;&lt;FONT color=#808080&gt;&amp;lt;/remarks&amp;gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt; ExifPropertyItem() {}&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 value of the property.&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; byte&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;byte&lt;/FONT&gt;[] buffer =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; byte&lt;/FONT&gt;[len];&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt; (len &amp;gt; 0)
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;Marshal.Copy(&lt;FONT color=#0000ff&gt;value&lt;/FONT&gt;, buffer, 0, len);&lt;FONT color=#0000ff&gt;&lt;/DIV&gt;return&lt;/FONT&gt; buffer;&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; Converts a buffer into an array of PropertyItem 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="propertyData"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The properties data buffer.&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="count"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The number of properties in the buffer.&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="PropertyItem"/&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt; objects.&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[] ConvertFromMemory(IntPtr propertyData,&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; count) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;PropertyItem[] itemArray =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt; PropertyItem[count];&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; count; i++) {
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;&lt;FONT color=#008000&gt;// Marshals the buffer into a ExifPropertyItem structure.&lt;/FONT&gt;&lt;BR&gt;ExifPropertyItem item = (ExifPropertyItem)Marshal.PtrToStructure(propertyData,&lt;FONT color=#0000ff&gt; typeof&lt;/FONT&gt;(ExifPropertyItem));&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Creates the PropertyItem from the data.&lt;/FONT&gt;&lt;BR&gt;itemArray[i] = Create(item.type,&amp;nbsp;&amp;nbsp;item.id, item.len, item.Value);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Seek to next property.&lt;/FONT&gt;&lt;BR&gt;propertyData = (IntPtr)(((&lt;FONT color=#0000ff&gt;long&lt;/FONT&gt;)propertyData) + Marshal.SizeOf(&lt;FONT color=#0000ff&gt;typeof&lt;/FONT&gt;(ExifPropertyItem)));&lt;/DIV&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; itemArray;&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; Creates a PropertyItem from its components.&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="type"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The property type.&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="tag"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The property tag.&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="len"&amp;gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;The length of the property.&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="value"&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;/FONT&gt;&lt;BR&gt;&lt;FONT color=#808080&gt;///&lt;/FONT&gt;&lt;FONT color=#808080&gt; &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; static&lt;/FONT&gt; PropertyItem Create(&lt;FONT color=#0000ff&gt;short&lt;/FONT&gt; type,&lt;FONT color=#0000ff&gt; int&lt;/FONT&gt; tag,&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;DIV style="MARGIN-LEFT: 20pt"&gt;PropertyItem item;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;// Loads a PropertyItem from a Jpeg image stored in the assembly as a resource.&lt;/FONT&gt;&lt;BR&gt;Assembly assembly = Assembly.GetExecutingAssembly();&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt;(Stream emptyBitmapStream = assembly.GetManifestResourceStream(&lt;FONT color=#800000&gt;"ExifLoader.empty.jpg"&lt;/FONT&gt;))&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt;(Image empty = Image.FromStream(emptyBitmapStream))
&lt;DIV style="MARGIN-LEFT: 20pt"&gt;item = empty.PropertyItems[0];&lt;BR&gt;&lt;FONT color=#008000&gt;&lt;/DIV&gt;// Copies the data to the property item.&lt;/FONT&gt;&lt;BR&gt;item.Type = type;&lt;BR&gt;item.Len = len;&lt;BR&gt;item.Id = tag;&lt;BR&gt;item.Value =&lt;FONT color=#0000ff&gt; new&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; byte&lt;/FONT&gt;[&lt;FONT color=#0000ff&gt;value&lt;/FONT&gt;.Length];&lt;BR&gt;&lt;FONT color=#0000ff&gt;value&lt;/FONT&gt;.CopyTo(item.Value, 0);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; item;&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="DISPLAY: none; BACKGROUND-COLOR: #ffffff"&gt;&lt;B&gt;. . .&lt;/B&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;!-- End of sample code --&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;Note that in the class above, we load a jpeg file from resources into memory. This file is named "empty.jpg" but the resource is referenced as "ExifLoader.empty.jpg" since "ExifLoader" is the name of the assembly.&lt;/P&gt;
&lt;P style="TEXT-ALIGN: justify"&gt;Since the &lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;PropertyItem&lt;/SPAN&gt; class does not provide a public initializer to create a property "from scratch", we have to use an existing property item.&lt;/P&gt;&lt;!-- End of article --&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/159.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>Soon blogging...</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/04/148.aspx</link><pubDate>Fri, 04 Mar 2005 00:17:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/04/148.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/148.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/04/148.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/148.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/148.aspx</trackback:ping><description>&lt;P&gt;&lt;STRONG&gt;Welcome on the PixVillage DevTeam blog !&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pixvillage.com/"&gt;PixVillage&lt;/A&gt;&amp;nbsp;is a photo sharing software that use both a web service and a P2P protocol to transmit data between users,&amp;nbsp;and&amp;nbsp;has been (and is still being) developed in C# using the .Net Framework.&lt;/P&gt;
&lt;P&gt;During the development process, we have to solve design and implementation problems, find workarounds for OS or framework bugs, etc. That's we'll deal with in this blog !&lt;/P&gt;
&lt;P&gt;In the next weeks, I will work on the development of an EXIF handling&amp;nbsp;framework. I guess that will be my first series of posts on this blog.&lt;/P&gt;
&lt;P&gt;Soon blogging...&lt;/P&gt;
&lt;P&gt;For the PixVillage DevTeam,&lt;BR&gt;Buz&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/148.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>