title: How do I retrieve a UID from a ICS file being accepted in an Outlook add in?
body: <p>Thanks for looking.</p>
  <p>I am developing an Outlook Add-in and have a need to access the UID value embedded in a .ics file when the user accepts it:</p>
  <p><a href="https://i.stack.imgur.com/AAbvv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AAbvv.png" alt="enter image description here" /></a></p>
  <p>If I view the raw data in the .ICS file, I can see that the UID is there:</p>
  <p><a href="https://i.stack.imgur.com/AAbvv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DEGDx.png" alt="enter image description here" /></a></p>
  <p>I would like to know what event fires (that I can attach to) when a user accepts the meeting and, once I have the outlook object that is being accepted, how do I retrieve the UID from it?</p>
  <h1>UPDATE:</h1>
  <p>Thanks to Dmitry Streblechenko's help I now understand that the Global Appointment Id is just an encoded version of the UID. His tool <a href="http://www.dimastr.com/outspy/home.htm" rel="nofollow noreferrer">OutlookSpy</a>was very useful in seeing this. That said, I am still stuck on the last part which is to convert the Global Appointment ID to the UID in C#. Google leads me to this example to convert the <code>EntryId</code> property, but I can't locate the proper schema or hex code to get the Global Appointment ID property and decoded value. Any suggestions on how to modify the code below for the Global Appointment ID would be appreciated:</p>
  <pre><code>var oPA = appt.PropertyAccessor;
  
  //Get EntryId Value
  var entryIDProperty = &quot;http://schemas.microsoft.com/mapi/proptag/0x0FFF0102&quot;;
  var entryId= oPA.BinaryToString(oPA.GetProperty(entryIDProperty));
  
  //Now how to get the Global Appointment ID??
  var globalApptProperty = http://schemas.microsoft.com/mapi/proptag/0x????????&quot;;
  var globalId= oPA.BinaryToString(oPA.GetProperty(globalApptProperty ));
                 
  </code></pre>
  <p>Thanks in advance.</p>
  <h1>A SOLUTION</h1>
  <p>I realize that this may not be the best way to accomplish the goal, but it works so I am posting in case it helps anyone else:</p>
  <pre><code>var item = Item as Outlook.MeetingItem;
  var appt = item.GetAssociatedAppointment(false);              
  var oPA = appt.PropertyAccessor;
                  
  //This parses the Global Appointment ID to a byte array. We need to retrieve    the &quot;UID&quot; from it (if available).
  byte[] bytes = (byte[]) oPA.StringToBinary(appt.GlobalAppointmentID);
  
  //According to https://msdn.microsoft.com/en-us/library/ee157690(v=exchg.80).aspx we don't need first 40 bytes            
  if (bytes.Length&gt;=40)
  {                    
     byte[] bytesThatContainData = new byte[bytes.Length - 40];
     Array.Copy(bytes, 40, bytesThatContainData, 0, bytesThatContainData.Length);
  
     //In some cases, there won't be a UID.
     var test = Encoding.UTF8.GetString(bytesThatContainData, 0, bytesThatContainData.Length);
  
     if (test.StartsWith(&quot;vCal-Uid&quot;))
     {
        //remove vCal-Uid from start string and special symbols
        test = test.Replace(&quot;vCal-Uid&quot;, string.Empty);
        test = test.Replace(&quot;\u0001&quot;, string.Empty);
        test = test.Replace(&quot;\0&quot;, string.Empty);
  
        //Here is the result
        var uid = test;
      }else{
        // Bad format!!!
      }
   }
  </code></pre>