Z każdym dniem programowanie pod Office mnie zaskakuje – czy to Outlook czy Word, Excel, PowerPoint, cokolwiek, to jedno i to samo bagno. Sam nie wiem co mam o tym myśleć i jakie rozwiązania mam stosować by problemy rozwiązać. Możliwe, że to wszystko jest spowodowane tym, że muszę wspierać wersje od 2007 aż po najnowszą 2016. Przez co pewne API nie są dostępne. Dziś właśnie opiszę jeden z takich przypadków.

W windowsie możemy wysłać komuś plik emailem na wiele sposobów (oczywiście z użyciem Outlooka):

  1. Możemy to zrobić wykorzystując normalnie aplikację
  2. Możemy to zrobić z aplikacji typu word/excel (File | Share)
  3. Możemy też to zrobić z poziomu systemu operacyjnego – prawy przycisk myszy na pliku Send to | Mail Reciepient (działa tak samo jak punkt 2)

Jeżeli celem naszego pluginu jest przeczytanie własności pliku i zareagowanie odpowiednie – na przykład jakaś wartość pliku powoduje, że mail musi mieć włączone szyfrowanie – to potrzebujemy do tego problemu podejść na wiele sposobów. W outlooku nie można dostać się do pliku jako strumienia – takie API nie istnieje. Jedyny sposób dostania się do własności załącznika to zapisanie go na dysk i następnie odczytanie jego wartości.

Outlook każdy załącznik (ekhm… część, nie wszystkie, te które my załączamy tak, ale też nie zawsze bo są różne typy załączników… ogólnie, dla uproszczenia przyjmijmy, że jednak każdy) zapisuje do swojego temp folderu do którego ścieżkę możemy znaleźć w rejestrze: Software\Microsoft\Office\{0}\Outlook\Security pod kluczem OutlookSecureTempFolder. Dla przykładu taka wartości może być równa:

C:\Users\Gutek\AppData\Local\Microsoft\Windows\INetCache\Content.Outlook\A4ZQ2BGZ

Tam trafiają pliku dodane do maila jako załączniki. I tam są przetrzymywane. Jak długo? Z tego co zaobserwowałem to przez okres trwania sesji outlook albo do czasu wysłania/skasowania draft (wraz z oczyszczeniem kosza). Czyli mogą tam siedzieć dość długo.

Tu pojawia się problem posiadania wielu plików o tej samej nazwie. Łatwo sobie wyobrazić sytuację, ze mając dwa pliki o tej samej nazwie. Co robi wtedy outlook/system? Nadaje nazwy NAME (XXX) gdzie XXX to liczba porządkowa zaczynająca się dopiero od drugiego pliku.

Wszystko byłoby fajnie gdyby Outlook (zaznaczam wsparcie do 2007) dał nam informację do jakiego pliku się on odwołuje. Jednak jedyne co daje nam Outlook to nazwę tego pliku (pamiętajcie o uproszczeniu, ale warto wiedzieć, plik typu OLE wywali wam wyjątek przy próbie dobrania się do nazwy pliku w starszych officach). O path i innych własnościach pliku możemy zapomnieć. Co prawda od 2010 dostępna jest metoda GetTempFilePath ale dla 2007 nie ma. Więc nawet nie wiem co ona robi.

Ale tutaj pojawia się drugi problem… nie wszystkie pliki trafiają do temp fodleru! :) Jeżeli wyślemy mail za pomocą Send to | Mail Reciepient, to plik nie zmienia swojego położenia. Nawet jeżeli go zapiszemy. Jedynie po zapisaniu, zamknięciu okna i ponownym otwarciu maila już w outlooku plik zostanie zapisany w tymczasowej lokalizacji.

Niezależnie na jaki problem natrafimy (czy to send to, czy normalny mail), nigdy nie będziemy mieli gwarancji co do nazwy i lokalizacji pliku. ZERO, NADA. To co więc musimy zrobić to zapisać nasz załącznik do katalogu temp tylko po to by potem móc się do niego dowołać i pobrać jedną własność pliku…..

A oczywiście jak coś mamy zapisywać i odczytywać z dysku……. No właśnie. Pomimo, że podobno ten temp folder to jest jakiś bezpieczny folder. Nie jest to piękne. Nie jest to bezpieczne. Ale jest to Sparta by Outlook…. Dosłownie by Outlook:

Sparta by Outlook
Sparta by Outlook