RDOMail.SaveAs sometimes doesn't work over a UNC - outlook

I have a C# Outlook add-in that is using the Redemption library.
This add-in, among other things, copy the selected mail to a share somewhere on the network.
It usually works pretty well but sometimes, the .msg file on the share seems to be corrupted. It cannot be read by the service that tries to process it. Double clicking on it shows this message: "Cannot read the item".
Sometimes, I can see an error message:
SaveEmail - System.Runtime.InteropServices.COMException (0x8007000):
Error in StgCreateDocFile: 0x8007000 at
Redemption.IRDOMail.SaveAs(String Path, Object Type) at
XYZNameSpace.Email.SaveEmail(...)
Here the code that save the mail to the share:
// Save the mail in a temp local file first
mailItem.SaveAs(temppath, Outlook.OlSaveAsType.olMSG);
(... some processing ...)
// Reload the mail
RDOMail rm = rdoSession.GetMessageFromMsgFile(temppath);
// Save it again on a share
rm.SaveAs(filePathName, Outlook.OlSaveAsType.olMSG);
Note 1 : I don't know why the mail is first saved locally!
Note 2 : It is using an older version of Redemption (2015).
Note 3 : The size of the message doesn't seem important. However, they are
usually between 2 and 15 MB.
Many thanks in advance.

IStorage API does not really like remote drives - there is no way for the storage sharing features to work.
Opening and saving the message the second time really does not make much sense - why not simply copy the MSG file using the file system API?

Related

Which OlSaveAsType can I add to the MailItem SaveAs method?

I am getting the currently selected mailItem from the explorer and saving it to the local file system. The file is then being uploaded to a server. My problem is sometimes the server (which I have no control over) returns that the file format is invalid.
I save the mailItem with the following code:
oMailItem.SaveAs("C:\path\savedEmail.msg")
This creates a file which is 174kb in size. If I add the OlSaveAsType of olMSG then I get the same file size.
If I save the exact same email with the Outlook UI then the chosen/suggested Message format is Unicode. This produces a file of about 251kb ie. much bigger. If I save it with the above code and olMSGUnicode then I also get the same file size.
I am therefore assuming that leaving out the OlSaveAsType option saves the mailItem as an olMSG.
I am currently also assuming that this may be causing some issues with the upload to the server.
What property of a mailItem tells me which OlSaveAsType to use? Can I safely use olMSGUnicode for all saves?
Yes, you can safely use olMSGUnicode format on all modern versions of Outlook.
But the real problem is why the server (?!) returns an error that the format is invalid? Was it corrupted? Can you successfully open the same file you sent to the server? You need to figure out why that error is returned.

WP7 + Live SDK - file overwrite doesn't work

I'm trying to upload a file to SkyDrive using Live SDK. It works well except overwriting existing files. Whenever I try to overwrite an existing file I get the error message "The resource file_name already exists.", although I use the Overwrite option:
_liveClient.UploadAsync(
FolderId,
Filename,
MemoryStream,
OverwriteOption.Overwrite);
Is there anything else I need to set?
I could try handling the error by deleting the file and uploading again but that's obviously not the cleanest way to do that.
Microsoft admitted here that it's a bug that they are aware of . It will be fixed in the next release.
Also, as per answer in that link, the overloaded method works fine:
_liveClient.UploadAsync(
FolderId,
Filename,
MemoryStream,
OverwriteOption.Overwrite,
null);
When your upload a file, and a file with the same name already exists in the same location in SkyDrive, the default behavior is for SkyDrive to overwrite the existing file. You are not required to specify OverwriteOption.
From my point of view, there is a problem else where. Try to use another folder and show a little more code.

Download large file from Skydrive to Windows Phone 7

Am having some trouble with the SkyDrive download process and hoping you can help me.
Following the standard SkyDrive API & examples, I've set up a page that browses the SkyDrive folder structure, lets User click on a file, prompt to download, and it all works correctly.
Where I'm having trouble is when the file downloaded is large, I get the OutOfMemoryException thrown at around the 100Mb mark.
Dennis speaks on this problem here http://dotnet.dzone.com/articles/2-things-you-should-consider but it relates to a direct URL download, not via the SkyDrive architecture.
I've tried extracting the URL from SkyDrive and doing the direct download that way but haven't had any success.
Here is the code I'm using - the "item" object is of type SkyDriveItem, having iterated through a folders content and selected this file.
LiveConnectClient downloadClient = new LiveConnectClient(App.Session);
try
{
downloadClient.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(downloadClient_DownloadCompleted);
downloadClient.DownloadProgressChanged += new EventHandler<LiveDownloadProgressChangedEventArgs>(downloadClient_DownloadProgressChanged);
downloadClient.DownloadAsync(item.ID + "/content", item);
This will work fine when the file isn't too large, but as mentioned, select a big file (>100Mb) and it dies with the OutOfMemory exception.
Any pointers?
Thanks in advance
Resolved - While I was never able to use the downloadClient.DownloadAsync() method to download large files, playing with the downloadClient.getAsync() and using the Pre-Authenticated URL via a regular Stream downloader does the trick.

Crystal Reports/Windows 7: Crystal reports asks for a default email client, and posts an error

Crystal Reports 11 (craxdrt.dll 11.5.7.1048)
Windows 7
I'm using Crystal Reports to export to a PDF document, using CRYSTALCRAXDRT::IReport::Export, and am getting an error, Windows 7 only.
"There is no email program associated to perform the requested action. Please install an email program or, if one is already installed, create an association in the Default Programs control panel."
Again, I'm not trying to send email, just create a document.
I've put forth a little debugging effort into this, and what seems to be happening is this:
I call into craxdrt.dll via the IReport interface, function Export(...), and then, monitoring with procmon, I find that there are several hundred registry queries for default mailer, contacts, etc.
It would seem that craxdrt.dll is building a large-ish data structure ahead of the task with whatever info it might need for a family of functions.
There's an error posted when the program can't find a default email client
Problems with this:
Windows 7 does not ship with a default email client, and early investigation seems to indicate that installing one does not necessarily ameliorate the problem. In any case, I do not expect all of our clients to have one installed, nor do our clients expect to have one installed by us.
Absent the actual need for an email client (i.e., in the above case), we're still getting this error message pop-up.
Note:
Interestingly, this doesn't actually prevent the user from pressing the export button again, and in fact if the user does this, the error does not show up, as the registry queries are apparently done only once per load or use of craxdrt.dll.
I think you are missing setting the ExportOptions before exporting:
Dim crxReport As Report
Set crxReport = Prepare()
crxReport.ExportOptions.FormatType = crEFTPortableDocFormat
crxReport.ExportOptions.DestinationType = crEDTDiskFile
crxReport.ExportOptions.DiskFileName = "C:\temp\Report.PDF"
crxReport.Export (False)

Launching a registered mime helper application

I used to be able to launch a locally installed helper application by registering a given mime-type in the Windows registry. This enabled me to allow users to be able to click once on a link to the current install of our internal browser application. This worked fine in Internet Explorer 5 (most of the time) and Firefox but now does not work in Internet Explorer 7.
The filename passed to my shell/open/command is not the full physical path to the downloaded install package. The path parameter I am handed by IE is
"C:\Document and Settings\chq-tomc\Local Settings\Temporary Internet Files\
EIPortal_DEV_2_0_5_4[1].expd"
This unfortunately does not resolve to the physical file when calling FileExists() or when attempting to create a TFileStream object.
The physical path is missing the Internet Explorer hidden caching sub-directory for Temporary Internet Files of "Content.IE5\ALBKHO3Q" whose absolute path would be expressed as
"C:\Document and Settings\chq-tomc\Local Settings\Temporary Internet Files\
Content.IE5\ALBKHO3Q\EIPortal_DEV_2_0_5_4[1].expd"
Yes, the sub-directories are randomly generated by IE and that should not be a concern so long as IE passes the full path to my helper application, which it unfortunately is not doing.
Installation of the mime helper application is not a concern. It is installed/updated by a global login script for all 10,000+ users worldwide. The mime helper is only invoked when the user clicks on an internal web page with a link to an installation of our Desktop browser application. That install is served back with a mime-type of "application/x-expeditors". The registration of the ".expd" / "application/x-expeditors" mime-type looks like this.
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.expd]
#="ExpeditorsInstaller"
"Content Type"="application/x-expeditors"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller]
"EditFlags"=hex:00,00,01,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell\open]
#=""
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell\open\command]
#="\"C:\\projects\\desktop2\\WebInstaller\\WebInstaller.exe\" \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\application/x-expeditors]
"Extension"=".expd"
I had considered enumerating all of a user's IE cache entries but I would be concerned with how long it may take to examine them all or that I may end up finding an older cache entry before the current entry I am looking for. However, the bracketed filename suffix "[n]" may be the unique key.
I have tried wininet method GetUrlCacheEntryInfo but that requires the URL, not the virtual path handed over by IE.
My hope is that there is a Shell function that given a virtual path will hand back the physical path.
I believe the sub-directories created by IE are randomly generated, so you won't be able guarantee that it will be named the same every time, and the problem I see with the registry method is that it only works when the file is still in the cache...emptying the cache would purge the file requiring yet another installation.
Would it not be better to install this helper into application data?
I'm not sure about this but perhaps this may lead you in the right direction: try using URL cache functions from the wininet DLL: FindFirstUrlCacheEntry, FindNextUrlCacheEntry, FindCloseUrlCache for enumeration and when you locate an entry whose local file name matches the given path maybe you can use RetrieveUrlCacheEntryFile to retrieve the file.
I am using a similar system with the X-Appl browser to display WAML web applications and it works perfectly. Maybe you should have a look at how they managed to do it.
It looks like iexplore is passing the shell namespace "name" of the file rather than the filesystem name.
I dont think there is a documented way to be passed a shell item id on the command line - explorer does it to itself, but there are marshaling considerations as shell item ids are (pointers to) binary data structures that are only valid in a single process.
What I might try doing is:
1. Call SHGetDesktopFolder which will return the root IShellFolder object of the shell namespace.
2. Call the IShellFolder::ParseDisplayName to turn the name you are given back into a shell item id list.
3. Try the IShellFolder::GetDisplayNameOF with the SHGDN_FORPARSING flag - which, frankly, feels like w'eve just gone in a complete circle and are back where we started. Because I think its this API thats ultimately responsible for returning the "wrong" filesystem relative path.
Some follow-up to close out this question.
Turned out the real issue was how I was creating the file handle using TFileStream. I changed to open with fmOpenRead or fmShareDenyWrite which solved what turned out to be a file locking issue.
srcFile := TFileStream.Create(physicalFilename, fmOpenRead or fmShareDenyWrite);

Resources