Outlook Redemption - Permissions issues when opening .msg file from local folder (System.UnauthorizedAccessException) - outlook-redemption

I have a folder of Journaling messages in .EML format.
I'm writing some code to save an .EML file as a .MSG file, then access the attached .MSG file within the saved .MSG file. When I try to access any of the fields with the attached .MSG file I get the following exception:
$exception{"Error in IMessage.OpenAttach: MAPI_E_NO_ACCESS"} System.UnauthorizedAccessException
I've checked the permission on the file created and they appear to ok.
The code I'm using:
RDOSession Session = new RDOSession();
foreach (var file in System.IO.Directory.GetFiles(#"\\win2012r2-ns\UserProfiles\phil\Downloads\email Archive\Beth_1\"))
{
RDOMail mi = Session.CreateMessageFromMsgFile(#"C:\Temp\temp.msg", "IPM.Mail");
mi.Import(file, 1024);
mi.Save();
Marshal.ReleaseComObject(mi);
mi = Session.GetMessageFromMsgFile(#"C:\Temp\temp.msg");
for (int i = mi.Attachments.Count; i >= 1; i--)
{
if (mi.Attachments[i].FileName.IndexOf(".msg") != -1)
{
Create_Folders(mi.Attachments[i].EmbeddedMsg.ReceivedTime.Year.ToString(), mi.Attachments[i].EmbeddedMsg.ReceivedTime.Month.ToString(), mi.Attachments[i].EmbeddedMsg.ReceivedTime.Day.ToString());
mi.Attachments[i].SaveAsFile(#"\\win2012r2-ns\EmailArchive\" + mi.Attachments[i].EmbeddedMsg.ReceivedTime.Year.ToString() + #"\" + mi.Attachments[i].EmbeddedMsg.ReceivedTime.Month.ToString() + #"\" + mi.Attachments[i].EmbeddedMsg.ReceivedTime.Day.ToString() + #"\" + mi.EntryID.ToString() + ".msg");
}
}
Marshal.ReleaseComObject(mi);
}

Messages opened on top of MSG files won’t let you open attachments and attachment table until the previous instances of that object are released.
You are using multiple dot notation, resulting in implicit variables that you cannot explicitly release. Try to change the code to the following:
RDOAttachments attachments = mi.Attachments;
for (int i = attachments.Count; i >= 1; i--)
{
RDOAttachment attach = mi.Attachments[i];
if (attach.Type == OlAttachmentType.olEmbeddeditem)
{
RDOMail embeddedMsg = attach.EmbeddedMsg;
Create_FoldersembeddedMsg.ReceivedTime.Year.ToString(), embeddedMsg.ReceivedTime.Month.ToString(), embeddedMsg.ReceivedTime.Day.ToString());
attach.SaveAsFile(#"\\win2012r2-ns\EmailArchive\" + embeddedMsg.ReceivedTime.Year.ToString() + #"\" + embeddedMsg.ReceivedTime.Month.ToString() + #"\" + embeddedMsg.ReceivedTime.Day.ToString() + #"\" + mi.EntryID.ToString() + ".msg");
Marshal.ReleaseComObject(embeddedMsg);
}
Marshal.ReleaseComObject(attach);
}
Marshal.ReleaseComObject(attachments);

Related

Wants to save Image of my user on 2nd sever MVC

I am currently working on a project in which we want to store image on separate sever. I don't now how to connect both the server so that i can easily save image on remote server.
if (Request.Files.AllKeys.Any())
{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
string oldFileName = file.FileName;
NewFileName = Guid.NewGuid().ToString();
string FileExtention = oldFileName.Substring(oldFileName.LastIndexOf('.') + 1);
if (FileExtention == "blob")
{
FileExtention = "jpg";
}
NewFileName = NewFileName + "." + FileExtention;
var fileSavePath = Path.Combine(Server.MapPath("~" + filePath + "Document"), file.FileName.Replace(oldFileName, NewFileName));
file.SaveAs(fileSavePath);
VisitDocument document = new VisitDocument();
document.VisitId = vid;
document.Title = oldFileName.Substring(0, oldFileName.LastIndexOf('.'));
document.RefPath = (filePath + "Document/" + NewFileName).Replace("/", #"\").Substring(1);
document.CreatedBy = tempUser.UserId;
document.CreatedOn = DateTime.Now;
document.IsDeleted = 0;
dal.VisitDocuments.Add(document);
dal.SaveChanges();
}
}
You have two options to do:
1- Use Web API application to do this task and deploy it on the server you want.
2- Open connection on the server and save the file there but you need to have account on this server and this account has the privileges to write and read.
string path = #"\\xxx.xxx.xxx.xxx\Uploads\"; // server IP
if (!System.IO.Directory.Exists(serverPath))
System.IO.Directory.CreateDirectory(path );
file.SaveAs(path + FileName);

.NET Graph SDK - OneDrive File Upload Fails with "Unsupported segment type"

Trying to upload file using the .NET SDK for Microsoft Graph. Here is the code:
DriveItem file = new DriveItem()
{
File = new Microsoft.Graph.File(),
Name = filename,
ParentReference = new ItemReference()
{
DriveId = parent.ParentReference.DriveId,
Path = path + "/" + filename
}
};
var freq = _client
.Me
.Drive
.Items[parent.Id]
.Children
.Request();
// add the drive item
file = await freq.AddAsync(file);
DriveItem uploadedFile = null;
using (MemoryStream stream = new MemoryStream(data))
{
var req = _client
.Me
.ItemWithPath(path + "/" + file.Name)
.Content
.Request();
stream.Position = 0;
// upload the content to the driveitem just created
try
{
uploadedFile = await req.PutAsync<DriveItem>(stream);
}
catch(Exception ex)
{
Debug.WriteLine("File Put Error"); <<< FAILS HERE
}
}
return uploadedFile;
An exception is thrown on the req.PutAsync method to upload the byte array containing the file contents. I am just testing with a simple text file, less than 100 bytes in size. The exception contains Bad Request and Unsupported segment type.
The file is created in OneDrive, but contains 0 bytes.
Me.ItemWithPath() requires the full path after /me. For example, _client.Me.ItemWithPath("/drives/driveId/items/itemId:/file/path"). This method is so the Path returned on the ItemReference returned via the API can be passed into the ItemWithPath method without any processing.
What you'll want to use is:
var req = _client
.Me
.Drive
.ItemWithPath(path + "/" + file.Name)
.Content
.Request();
or:
var req = _client
.Me
.ItemWithPath(file.ParentReference.Path + "/" + file.Name)
.Content
.Request();
I have found that it is sometimes easier to skip the path in lee of setting the containing folder id in the SDK statement... works in OneDrive and unified groups..
var createdFile = await graphClient.Me.Drive
.Items[currentDriveFolder.id]
.ItemWithPath(fileName)
.Content.Request()
.PutAsync<DriveItem>(stream);
I would really like to be able to just set drive id and folder id like this:
var createdFile = await graphClient
.Drives[driveId]
.Items[folderId]
.ItemWithPath(fileName)
.Content
.Request()
.PutAsync<DriveItem>(stream);

File Read-Write Error in iOS

I have used following code for file reading and writing.
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
string fileData = streamReader.ReadLine ();
}
But I am getting following error in actual iOS device running. This code working correct in iMac as well in android device.
Please give me some suggestion what changes I need to do to make this correct.
It seems you're using Windows-style paths in a Unix-like (Apple Mac OS) environment. Notice that on windows you have paths with a backslash like
C:\Users\Maxi\Desktop
On Unix-like system however something like
/var/mobile/Containers
You notice that in your faulty path you have mixed forward and backward slashes, which makes the path invalid.
/var/mobile/Containers/Data/Application/2.....\debutan1.txt
The correct way to always generate the correct path is to use the Path.Combine(string, string) function. This will combine two paths using the correct directory path seperator, which can also be seperatly accessed through Path.DirectorySeparatorChar.
So, in order to make your code correct, you would do
using System.IO; /* must be imported */
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
string fileData = streamReader.ReadLine ();
}
If this still gives an "Access denied" error it must be because of filepermissions. Post the output of ls -la <thatpath> then.

Appcelerator App crashes when downloading large (>500mb) zip file

We are currently developing an iOS-App with Appcelerator which stores media files on the device for later viewing (pdf, mp4, zipped web pages).
We are now facing a problem with files above 500MB which crash the app on iPhone. The app is working on iPad2, but all iPhones tested crash (at random) when downloading these files.
The files are unzipped (all media files come with additional information inside the archive) via ti.compression.
The code used is (broken down to the relevant parts):
var zipDownloader = Ti.Network.createHTTPClient({
'onload' : function() {
var tempname = Math.floor((Math.random() * 10000000) + 1);
var dir = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, 'tempDownloads', tempname);
dir.createDirectory();
filename = '' + tempname + '.zip';
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'tempDownloads', filename);
f.write(this.responseData);
var Compression = require('ti.compression');
var zipFileName = Ti.Filesystem.applicationDataDirectory + 'tempDownloads/' + filename;
var outputDirectory = Ti.Filesystem.applicationDataDirectory + 'tempDownloads/' + tempname + '/';
var start = Math.floor(Date.now() / 1000);
var result = Compression.unzip(outputDirectory, zipFileName, true);
var finished = Math.floor(Date.now() / 1000) - start;
f.deleteFile();
Compression = null;
this.callback(outputDirectory);
}
});
zipDownloader.open('GET', url);
zipDownloader.callback = callback; // given in previous code, not relevant
zipDownloader.send();
Set the file property of the HTTPClient (https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network.HTTPClient-property-file) instead of writing the file once it is downloaded.
This will work for larger files because it writes the data directly into the file. Otherwise it will try to cache your file first and your app might crash because of memory errors. Tried it with 500+MB files

Copy/rename google sheet, share & get share id with script in form

Is it possible for a script to copy/rename an (unrelated) Google spreadsheet, share it with a given email (preferably testing for the existence of a google account associated with the given email first), and save the shared url? I have spent hours and can't find any part of the answer to this: nothing on copying/renaming, nothing on share id. I may be missing some keyword or something. I realize I'll probably be downvoted for a general question, but this is the only Google Script support out there, I think. If you give me a thread, I'll follow it.
So: I had to figure this out, and finally hired someone to code this snippet for me, here's what I got. This works pretty great for me. I did a tiny bit of customization.
Here's the requirement:
Given 2 Google Sheets, GTemplate & GTracker (these are two separate spreadsheets, not tabs in the same spreadsheet). Create a form (that reports to a tab/sheet in GTracker) which a user (anyone) fills in online with an email "UserEmail", and a string "UserID". Upon submission:
1) Make a copy of GTemplate, and rename it to "GTUserID" (if GTUserID already exists, name it GTUserID1, 2, or whatever)
2) Check that the submitted email has an associated Google Account
3) Share GTUserID with UserEmail
4) Save the URL of GTUserID to GTracker
5) Send an email to UserEmail confirming success or failure of above
//************ Edit here *******************************
var stremplateID = '1PBO9KhoZa9iX3Uik-FxXGnvhgs0BoNQUJmV95UUg56o';
//******************************************************
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Initialization')
.addItem('Initialize', 'setTrigger')
.addToUi();
}
function setTrigger(){
var arr= ScriptApp.getProjectTriggers();
for (var i= arr.length; i>0; i--){
ScriptApp.deleteTrigger(arr[i-1])
}
ScriptApp.newTrigger('onFormSubmit')
.forSpreadsheet(SpreadsheetApp
.getActiveSpreadsheet().getId())
.onFormSubmit()
.create()
}
function onFormSubmit(e) {
try {
//Logger.log(JSON.stringify(e))
var folder;
var strEmail = e.namedValues.Email;
var strUID = e.namedValues['User ID'];
//Logger.log(strEmail)
//Logger.log(strUID)
var oldFile = DriveApp.getFileById(stremplateID);
var folders = oldFile.getParents();
while (folders.hasNext()) {
folder = folders.next();
break;
}
if ((typeof folder) != "object") {
folder = DriveApp.getRootFolder();
}
var bolFlag = false;
var bolFlag1 = false;
var i = 0;
var myRegexp = new RegExp('[^a-zA-Z0-9.-]','g');
var strProcUID=String(strUID).replace(myRegexp, "_");
//Logger.log(strProcUID)
var strFilename = strProcUID;
while (!bolFlag) {
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
if (file.getName() == strFilename) {
bolFlag1 = true;
}
}
if (!bolFlag1) {
bolFlag = true;
} else {
i = i + 1;
strFilename = strProcUID + i;
bolFlag1 = false;
}
}
var newFile = oldFile.makeCopy(strFilename, folder);
newFile.addEditors(strEmail);
var link = newFile.getUrl();
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var row = sh.getLastRow();
var col = sh.getLastColumn();
sh.getRange(row, col, 1, 1).setValue(link);
var body = 'Dear ' + strUID + ',\n' +
'Your request has been processed successfully.\n' +
'The file can be seen here:\n' +
link + '\n' +
'Regards,\n ' +
'Admin';
GmailApp.sendEmail(strEmail, 'Request Processed', body);
} catch (e) {
var body = '\n' +
'An error occurred while processing the request:\n' +
'User ID: ' + strUID + '\n ' +
'Email: ' + strEmail + '\n ' +
'Error: ' + e;
GmailApp.sendEmail(Session.getEffectiveUser().getEmail(), 'Error processing a request', body);
var body = 'Dear ' + strUID + ',\n' +
'Sorry, an error occurred while processing your request.\n' +
'Regards,\n ' +
'Admin';
GmailApp.sendEmail(strEmail, 'Error processing the request', body);
}
}
Perhaps this will be helpful to someone else. The things it does that I couldn't find was copying a copied/shared Google Sheet URL into a different sheet (for creating daughter shared documents for different projects, initiated by the project teams, still owned by the admin account, with internal fields readily accessible since we've got the URL). I hope that's clear and helpful.

Resources