DragAndDrop in Outlook - is it a mail, an attachment or a file?

If you are developing an addin for outlook and you are building a drag and drop able control, you will need to check what kind of data droped in. In the following code I made differences between those three types: files from the filesystem, mails out of Outlook and attachments that came from mails in Outlook. I used the DragEventArgs to figure out what was droped and then I handle each way a bit different.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
private void panel_Drop(object sender, DragEventArgs e)
{
 //get a temporary path to save the files
 string TemporaryPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\TempFiles\\";
 if (!Directory.Exists(TemporaryPath))
 {
  Directory.CreateDirectory(TemporaryPath);
 }
       
 string[] fileNames = null;

 try
 {
  // a bunch of files was dragged into the panel
  if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
  {
   fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);                  
   // handle each file passed as needed
   foreach (string fileName in fileNames)
   {
    // move file to TemporaryPath
    FileInfo FI = new FileInfo(fileName);
    string DesinationPath = TemporaryPath + FI.Name;
    File.Copy(fileName, DesinationPath,true);
                   
    FI = new FileInfo(DesinationPath);
    // always good to make sure we actually created the file
    if (tempFile.Exists == true)
    {
     // do something with the file
    }
    else
    {
     // Error
     Exception ex1 = new Exception("File was not created!");
     throw ex1;
    }
   }
  }
  // something that comes from Outlook was dropped here
  else if (e.Data.GetDataPresent("FileGroupDescriptor"))
  {
   MemoryStream ms = null;
   try
   {
    // get the actual raw file into memory
    ms = (MemoryStream)e.Data.GetData("FileContents", true);
   }
   catch (Exception ex)
   { }                
               
   // if ms = null there was an error in starting a memory stream
   // so there was no attachment dropped.. it was an email
   if (ms == null)
   {                  
    //get the current Outlook instance
    Outlook.Application outlook;
    outlook = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
    Outlook.Explorer explorer = outlook.ActiveExplorer();

    // get all selected mails because they where droped right here
    foreach (Outlook.MailItem MI in explorer.Selection)
    {
     // get a mail and save it as msg-file
     string MailPath = TemporaryPath + MI.Subject + ".msg";
     MI.SaveAs(MailPath);
     MI.Close(Outlook.OlInspectorClose.olDiscard);

     FileInfo tempFile = new FileInfo(MailPath);
     // always good to make sure we actually created the file
     if (tempFile.Exists == true)
     {
      // do something with the file
     }
     else
     {
      // Error
      Exception ex1 = new Exception("File was not created!");
      throw ex1;
     } 
    }
   }
   else
   {                    
    // the first step here is to get the filename of the attachment and
    // build a full-path name so we can store it in the temporary folder

    // set up to obtain the FileGroupDescriptor
    // and extract the file name
    Stream theStream = (Stream)e.Data.GetData("FileGroupDescriptor");
    byte[] fileGroupDescriptor = new byte[512];
    theStream.Read(fileGroupDescriptor, 0, 512);
    // used to build the filename from the FileGroupDescriptor block
    StringBuilder fileName = new StringBuilder("");
    // this trick gets the filename of the passed attached file
    for (int i = 76; fileGroupDescriptor[i] != 0; i++)
    {
     fileName.Append(Convert.ToChar(fileGroupDescriptor[i]));
    }
    theStream.Close();
                   
    // put the zip file into the temp directory
    string theFile = TemporaryPath + fileName.ToString();
    // create the full-path name

    // Second step:  we have the file name.
    // Now we need to get the actual raw
    // data for the attached file and copy it to disk so we work on it.

    // allocate enough bytes to hold the raw data
    byte[] fileBytes = new byte[ms.Length];
    // set starting position at first byte and read in the raw data
    ms.Position = 0;
    ms.Read(fileBytes, 0, (int)ms.Length);
    // create a file and save the raw zip file to it
    FileStream fs = new FileStream(theFile, FileMode.Create);
    fs.Write(fileBytes, 0, (int)fileBytes.Length);

    fs.Close();  // close the file

    FileInfo tempFile = new FileInfo(theFile);

    // always good to make sure we actually created the file
    if (tempFile.Exists == true)
    {
     // do something with the file
    }
    else
    {
     // error
     Exception ex1 = new Exception("File was not created!");
     throw ex1;
    }
   }                
  }
 }
 catch (Exception ex)
 {
  // don't use MessageBox here - Outlook or Explorer is waiting for it !
 }  
}

Comments

Popular posts from this blog

How to support multiple languages in WPF