2009-08-12 12 views
6

J'ai besoin de lire des choses à partir d'un fichier MSg Outlook. Actuellement, j'utilise un projet de classe CodeProject.com pour y parvenir, car le déploiement de VSTO et Outlook sur un serveur n'est pas une option.Comment lire la date de réception des fichiers Outlook MSG (sans l'API Outlook)?

Cette classe obtient To, From, CC, Subject, Body et tout ce dont j'ai besoin à partir du fichier msg, à l'exception des informations Date (telles que Date de réception et Date d'envoi).

documentation (vraiment, vraiment de bas niveau) sur la façon de récupérer des fichiers msg sur MSDN, mais cela sort un peu du cadre de ce projet et ne mentionne aucune date.

Idéalement, je serais en mesure d'avoir un remplacement de la classe que j'utilise maintenant (OutlookStorage.cs dans le CodeProject mentionné précédemment) ou être en mesure de modifier un peu la classe existante. Pour modifier, j'aurais besoin de l'identifiant hexadécimal correct de 4 caractères pour la date reçue. Par exemple, Sujet est répertorié comme PR_SUBJECT = "0037" et le corps est répertorié comme PR_BOY = "1000".

Répondre

2

Je pense que la bibliothèque Aspose fera ce que vous voulez, ok c'est une librairie tierce, donc peut-être pas ce que vous voulez. Il y a quelques scripts vbs qui obtiennent des informations de base sur les fichiers msg qui pourraient être traduits.

1

Vous avez un soupçon de this:

string fullFileName = "c:\message.msg"; 
DateTime dateRevieved = new DateTime(); 

StreamReader sr = new StreamReader(fullFileName, Encoding.Default); 
string full = sr.ReadToEnd(); 

string date; 
int iStart; 
int iLast; 

string caption; 

//This -should- handle all manner of screwage 
//The ONLY way it would not is if someone guessed the -exact- to-the-second 
//time that they send the message, put it in their subject in the right format 
while (true) {  //not an infinite loop, I swear! 

    caption = "Date:"; 
    if (full.IndexOf("Date:") > -1) { //full shortens with each date is removed 
     string temp = ""; 

     iStart = full.LastIndexOf(caption); 
     temp = full.Remove(0, iStart + caption.Length); 
     full = full.Substring(0, iStart); 

     iLast = temp.IndexOf("\r\n"); 
     if (iLast < 0) { 
      date = temp; 
     } else { 
      date = temp.Substring(0, iLast); 
     } 

     date = date.Trim(); 

     if (date.Contains(subject) || subject.Contains(date)) { 
      continue; //would only happen if someone is trying to screw me 
     } 

     try { 
      dateRevieved = DateTime.Parse(date); //will fail if not a date 
      break; //if not a date breaks out of while loop 
     } catch { 
      continue; //try with a smaller subset of the msg 
     } 
    } else { 
     break; 
    } 
} 

Ce type est un hack par rapport aux façons dont vous pouvez obtenir d'autres choses à partir de fichiers msg en utilisant quelque chose ce lovely project. Pourtant, il a résisté à tout ce que j'ai jeté contre lui, et comme indiqué le seul moyen de le tromper est de mettre la date exacte à la seconde dans la ligne d'objet dans le format approprié.

1

de combiner vos deux postes, je suggère la solution suivante:

Pour modifier, je aurais besoin le caractère 4 correct hexadécimaux prop identifiant la date recieved. Par exemple, Subject est répertorié comme PR_SUBJECT = "0037" et Body est répertorié comme PR_BOY = "1000".

Recherchez «007D».

Utilisez la méthode que vous avez publiée dans votre deuxième message sur les données reçues pour éliminer le problème lorsque la même (date) chaîne est à l'intérieur du sujet.


Je dois mentionner que cette méthode ne semble pas fonctionner sur eMails internes: En mails que je reçois de collègues, il n'y a pas substg1.0_007Dxxxx-propriété.

Ici, la date semble être masquée dans substg1.0_0047xxxx.

Tout le meilleur!

Inno

7

Si vous utilisez OutlookStorage.cs de CodeProject, puis ajoutez ce qui suit:

private const string PR_RECEIVED_DATE="007D"; 
private const string PR_RECEIVED_DATE_2 = "0047"; 

... 

/// <summary> 
/// Gets the date the message was received. 
/// </summary> 
public DateTime ReceivedDate 
{ 
    get 
    { 
     if (_dateRevieved == DateTime.MinValue) 
     { 
      string dateMess = this.GetMapiPropertyString(OutlookStorage.PR_RECEIVED_DATE); 
      if (String.IsNullOrEmpty(dateMess)) 
      { 
       dateMess = this.GetMapiPropertyString(OutlookStorage.PR_RECEIVED_DATE_2); 
      } 
      _dateRevieved = ExtractDate(dateMess); 
     } 
     return _dateRevieved; 
     //return ExtractDate(dateMess); 
    } 
} 

private DateTime _dateRevieved = DateTime.MinValue; 

private DateTime ExtractDate(string dateMess) 
{ 
    string matchStr = "Date:"; 

    string[] lines = dateMess.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
    foreach (string line in lines) 
    { 
     if (line.StartsWith(matchStr)) 
     { 
      string dateStr = line.Substring(matchStr.Length); 
      DateTime response; 
      if (DateTime.TryParse(dateStr, out response)) 
      { 
       return response; 
      } 
     } 
    } 
    return DateTime.MinValue;     
}