I try to read some outlook msg files with Microsoft.Office.Interop.Outlook Dll. I know Outlook must be installed on machine.
I use this code to read the msg file. This works fine.
Microsoft.Office.Interop.Outlook._Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem fld = (Microsoft.Office.Interop.Outlook.MailItem)app.Session.OpenSharedItem(filename);
But if I open the same msg-file an exception is thrown, becouse the file is already opened. I think the gc is not clearing the objects.
How can I release the objects?
Probably you solved your problem nowadays, but you could try this:
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(mailItem) != 0) { }
mailItem = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Related
I need some help.
My application works with Outlook files.
For example, I have a MSG format file is stored at my PC.
Let's imagine that I haven't got any running Outlook processes on my PC.
var myProcess = new Process { ProcessInfo = new ProcessStartInfo {FileName = targetPath}}
where targetPath is full path to my file.
Then I start process:
myProcess.Start();
At this moment Outlook runs at OS. Looking into TaskManager I see this process, and it's unique PID.
And there is my first question: why this PID is different from myProcess.Id ?
Moving on. I need to check is my file still opening at Outlook. I resolve this issue by trying to open this file in my application for a certain time.
var iterations = 3600;
while (iterations > 0 ) {
Thread.Sleep(1000);
var fInfo = new FileInfo(targetPath);
FileStream stream = null;
try {
stream = fInfo.Open(FileMode.Open, FileAccess.Read | FileAccess.Write, FileShare.None);
} catch {
//I expect if exception occurs then file is not lock and can send it to server.
}
finally{
if(stream != null)
stream.Close();
}
iteration--;
}
I think, while my MSG file is using by Outlook, I my application cant open file. In that way I decide that cant save my file and send it to server. But! If I add attachment but NOT close this e-mail at Outlook, my application CAN open this file. And I don't understand why Outlook change Read/Write attribute of this file? And how I can solve this issue?
Unfortunately, I haven't any idea why it happens and how to make it work.
I was looking on any info at web that can help to solve my issue, but has no result :(
Thank you for your time.
Firstly, Outlook is a singleton - if you start a new instance of outlook.exe, it will simply switch control to the already running instance and exit.
Outlook internally caches / references open MSG files, there is really northing you can do about that.
Please can someone help with a problem opening a Word2003 file in code using Microsoft.Office.Interop.Word?
My code is below. The document is created fine and if I pause the code after creating it I can open the file via explorer. The code freezes on the final line. At this point one can see a file locking metafile appear in explorer as well as the original. There is no error generated that I can see. Maybe there is an invisible dialog but otherwise I'm stumped.
Thanks in advance.
Firstly write a byte array to a file
var tmpFile = #"C:\donkey.doc";
File.WriteAllBytes(tmpFile, binary_document);
Open the file as a document object of some type
Application app = new Application();
Document CurrDoc = app.Documents.Open(#"C:\donkey.doc");
Solution to freeze was re-installing Word2003 although I have actually abandoned the approach altogether due to the server issues identified here http://support.microsoft.com/kb/257757. Thanks for all help.
Try this it may help you.
Create a new "Desktop" directory inside of "C:\Windows\SysWOW64\config\systemprofile\"
it works for me after a long long long day searching for the solution.
It seams to be a profile problem.
What I will check in same situation
Permission access
Create a file outside C# and only remain the file open part
When stuck at open command, task manager has Microsoft Word exe running?
Suggestion to Solve
1) Run as Console Application (those posts I mentioned they work well in Console)
2) Try to put CurrDoc.Activate() after CurrDoc = app.Documents.Open(#"C:\donkey.doc");
3) Try to declare byte[] binary_document = { 112 }; but not using your current array to let File.WriteAllBytes() finish its work faster.
4) Try Highest vote post of Interop.Word Documents.Open is null
5) Try Suggestion for XP (search "xp") in Word 2007 Documents.Open returns null in ASP.NET
6) Try catch the exception (but seem like your case is not exception)
try
{
CurrDoc = app.Documents.Open(tmpFile);
}
catch (Exception eX)
{
//MessageBox.Show(eX.ToString());
Console.WriteLine(eX);
}
Sorry hope I'm not confusing you.
Work For Me
Refer to #Mike Miller, the main point is app.Visible is not set to true; The app is active but Only it is NOT visible!! Learn something new. thanks.
I am using Microsoft Word 2010 and Windows 7 Home Premium 64 bit.
Document CurrDoc;
//avoid ambiguity so put in missing argument
object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Application app;
private void btnMakeandOpenDoc_Click(object sender, EventArgs e)
{
//put in some byte value into the array
byte[] binary_document = { 112, 132, 32, 33,231,125,87 };
var tmpFile = #"C:\donkey.doc";
File.WriteAllBytes(tmpFile, binary_document);
app = new Microsoft.Office.Interop.Word.Application();
CurrDoc = app.Documents.Open(#"C:\donkey.doc");
//main point
app.Visible = true;
}
//close the opening doc file also
private void btnCloseDoc_Click(object sender, EventArgs e)
{
CurrDoc.Close(ref missing, ref missing, ref missing);
app.Application.Quit(ref missing, ref missing, ref missing);
}
While debugging, if you manually open this file through explorer, the last line will also try and do the same thing. Now, I cannot remember Office 2003 behaviour any more but 2010 does prompt that you are trying to open same file again (or at least it does that to me). This could well be the reason.
Solution to freeze was re-installing Word2003 although I have actually abandoned the approach altogether due to the server issues identified here http://support.microsoft.com/kb/257757. Thanks for all help.
I created a desktop folder but in this folder: C:\Windows\System32\config\systemprofile and gave the service account access to the folder. Do not know if the access is neccessary but it worked.
I'm writing piece of code which will handle extraction of information from email stored in *msg Outlook file. The idea how to do it I took from C# Outlook interop and OpenSharedItem for opening MSG files. But when calling method OpenSharedItem a get such error System.AccessViolationException. Anyone know what's the problem?
Here is code causing error
Outlook._Application app = new Outlook.Application();
Outlook.NameSpace NS = app.GetNamespace("MAPI");
Outlook.MAPIFolder inboxFld = NS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MailItem fld = (Outlook.MailItem) app.Session.OpenSharedItem("E://Projects//C#//message1.msg");
Ok. In case anybody will face the same problem finally I've got an answer. First of all should be
Outlook.MailItem fld = (Outlook.MailItem) app.Session.OpenSharedItem("E:\\Projects\\C#\\message1.msg");
difference is in the slashes.
Then all you need to make it work is Outlook 2007 or newer. And that's it :]
I want to get all events from all calendars, how do i iterate thru all calendar folders and then all events for each calendar?
If I had to guess, though I'm just getting in to Outlook myself, I would suggest the following:
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace ns = app.GetNamespace("MAPI");
Outlook.MAPIFolder folder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
Then something along the lines of
foreach (outlook.MAPIFolder subFolder in folder.Folders)
{
// do something with subFolder
}
And you could probably create something recursive to exhaust all possibilities of the MAPIFolder.Folders property.
EDIT Ultimately, try stepping through in the debugger one you've gotten the default folder and see what you're left with. My guess is this will have the information you need.
I am using Ms Office Interop assemblies to create a MS Project file. To save the file created, I am using FileSaveAs method and it prompts a message saying that if you want to replace the existing file.
I want to suppress the message, and I didn't find any parameter in FileSaveAs method for this purpose.
Any Idea on this?
I'am using C# as my programming language.
I ran into this issue when working with Excel Interop. The best I've been able to find is to disable all Office alerts, like this:
Microsoft.Office.Interop.MSProject.Application msProjectApp = new Microsoft.Office.Interop.MSProject.Application();
msProjectApp.DisplayAlerts = false;
Never double dot COM objects, as they will not be released and this will leave excel open on your server. Unfortunately I have crashed servers because of this.
private void InitialiseExcel()
{
if (excelApp == null)
excelApp = new Excel.Application();
// Turn off User Prompts
excelApp.DisplayAlerts = false;
// Turn off screen updating so we do not get flicker
var app = excelApp.Application;
app.ScreenUpdating = false;
// Specifies the state of the window;
excelApp.WindowState = Excel.XlWindowState.xlMinimized;
Marshal.ReleaseComObject(app);
}