I'm trying to connect to a Public Folder in Outlook 2010 with C# (Visual Studio 2010).
I copied following code from a Microsoft Website:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// TODO: Add code here to start the application.
Outlook._Application olApp = new Outlook.ApplicationClass();
Outlook._NameSpace olNS = olApp.GetNamespace("MAPI"); Outlook._Folders oFolders;
oFolders = olNS.Folders;
Outlook.MAPIFolder oPublicFolder = oFolders["Public Folders"];
oFolders = oPublicFolder.Folders;
Outlook.MAPIFolder oAllPFolder = oFolders["All Public Folders"];
oFolders = oAllPFolder.Folders;
Outlook.MAPIFolder oMyFolder = oFolders["My Public Folder"];
Console.Write(oMyFolder.Name);
}
}
}
My problem is that "ApplicationClass" is redlined and I don't know what I've forgotten or done wrong.
Here's a screenshot with the error message.
You need to use interface
Microsoft.Office.Interop.Outlook.Application outlook = new Microsoft.Office.Interop.Outlook.Application()
or disable embedding of Interop types for this assembly (References -> Microsoft.Office.Interop.Outlook (right click) -> Properties -> Set 'Embed Interop Types' to False)
Change the line
Outlook._Application olApp = new Outlook.ApplicationClass();
to
Outlook._Application olApp = new Outlook._Application();
Related
I am trying to access the macros inside of an Access database (accdb).
I tried using:
using Microsoft.Office.Interop.Access.Dao;
...
DBEngine dbe = new DBEngine();
Database ac = dbe.OpenDatabase(fileName);
I found a container["Scripts"] that had a document["Macro1"] which is my target. I am struggling to access the contents of the document. I also question if the Microsoft.Office.Interop.Access.Dao is the best reference for what I am trying to achieve.
What is the best way to view the content of the macros and modules?
You can skip the DAO part, it's not needed in this case. Macros are project specific, so in order to get them all, you would need to loop through your projects. In my example, i just have one project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Access;
namespace Sandbox48
{
public class Program
{
public static void Main(string[] args)
{
Microsoft.Office.Interop.Access.Application oAccess = null;
string savePath = #"C:\macros\";
oAccess = new Microsoft.Office.Interop.Access.Application();
// Open a database in exclusive mode:
oAccess.OpenCurrentDatabase(
#"", //filepath
true //Exclusive
);
var allMacros = oAccess.CurrentProject.AllMacros;
foreach(var macro in allMacros)
{
var fullMacro = (AccessObject)macro;
Console.WriteLine(fullMacro.Name);
oAccess.SaveAsText(AcObjectType.acMacro, fullMacro.FullName, $"{savePath}{ fullMacro.Name}.txt");
}
Console.Read();
}
}
}
I am trying to automate Outlook using COM, and we are having terrible problems with Outlook crashing at arbitrary points when trying to use MAPI methods (eg Outlook.Recipient r = MAPI.CreateRecipient("me#there.com")).
One solution that has been suggested is to use Marshal.GetActiveObject() instead of new Outlook.Application().
This appears to work fine, however I have run into a very strange issue - the code fires up a copy of outlook and tries to get the application object, but calls to Marshal.GetActiveObject throw a System.Runtime.InteropServices.COMException exception while Outlook is the active application (Has the focus).
If I run the below code, the try keeps failing over and over.
However, if I hit ALT-TAB or click anywhere such that Outlook is no longer the active application, the code INSTANTLY succeeds.
Any ideas why? Failing that, does anyone have code that will de-focus outlook, so the code succeeds?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
namespace MAPI_Repro
{
class FakeTest
{
public Outlook.Application oApp;
public Outlook.NameSpace MAPI;
public void DoTest(){
if (Process.GetProcessesByName("OUTLOOK").Count() == 0)
{
var process = Process.Start(new ProcessStartInfo("outlook.exe"));
}
while (Process.GetProcessesByName("OUTLOOK").Count() == 0)
{
Thread.Sleep(100);
}
bool success = false;
while (!success)
{
Debug.WriteLine("Waiting for Marshal.GetActiveObject");
try
{
// This FAILS while Outlook is the active application.
// As soon as you hit ALT-TAB or click another app, this succeeds.
oApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
success = true;
Debug.WriteLine("SUCCESS");
}
catch (System.Runtime.InteropServices.COMException exp)
{
Debug.WriteLine("FAILED " + exp);
}
Thread.Sleep(100);
}
MAPI = oApp.GetNamespace("MAPI");
MAPI.Logon("", "", Missing.Value, Missing.Value);
}
}
}
I already have a C#-based Outlook Addin application which may or may not be installed on my clients versions of Outlook. Is it possible to determin whether the addin is installed and enabled from an external C# application, running on the same client's machine? And if so, how?
Many thanks in advance!
John
If you are installing via MSI, you can check if it has been installed with the Windows Installer API (see MSDN for more, P/Invoke.net has a C# example).
In the end, the following code solved my problem:
using System.Reflection;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Core;
...
public static bool IsOutlookAddinEnabled(string addinName)
{
bool isEnabled = false;
Outlook.Application outlookApp = null;
if (System.Diagnostics.Process.GetProcessesByName("OUTLOOK").Length > 0)
{
outlookApp = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
outlookApp = new Outlook.Application();
Outlook.NameSpace nameSpace = outlookApp.GetNamespace("MAPI");
nameSpace.Logon("", "", Missing.Value, Missing.Value);
nameSpace = null;
}
try
{
COMAddIn addin = outlookApp.COMAddIns.Item(addinName);
isEnabled = addin.Connect;
}
catch { }
return isEnabled;
}
Many thanks to Mitch for his quick response.
I have been following the example below to send email using C# code with success:
MSDN Mail Message
However, I would like the code to display the composed email message on user machine, so that user can have a final check before hitting send button on outlook.
In the VBA world, I can use mail.Display in place of mail.Send.
Can anyone provide some advice to achieve that in C#?
Thanks.
How about this...
private void btnEmail_Click(object sender, EventArgs e)
{
string command = "mailto:somebody#domain.com?subject=The Subject&bcc=another#codegaim.com&body=Hi,I found this website and thought you might like it http://www.geocities.com/wowhtml/";
Process.Start(command);
}
Found a great solution to my problem i.e. to use Microsoft Office Interop Outlook instead of System.Net.MailMessage
followed this:
How to send a mail using Microsoft.Office.Interop.Outlook.MailItem by specifying the From Address
//using Microsoft.Office.Interop.Outlook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Outlook;
namespace ConsoleApplication1
{
using Outlook = Microsoft.Office.Interop.Outlook;
public static class Program
{
static void Main(string[] args)
{
SendUsingAccountExample();
}
private static void SendUsingAccountExample()
{
var application = new Application();
var mail = (_MailItem)application.CreateItem(OlItemType.olMailItem);
mail.Body = "Hello";
mail.Subject = "Good Bye";
mail.To = "hello#google.com";
// Next 2 lines are optional. if not specified, the default account will be used
Outlook.Account account = Application.Session.Accounts["MyOtherAccount"];
mail.SendUsingAccount = account;
mail.Display(false); // To Display
//mail.Send(); // To Send
}
}
}
I programmed a wpf application that sends an outlook mail through the default logged in user.
This is my code:
using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
namespace FileOrganizer
{
class Program
{
private void CreateMailItem()
{
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mailItem = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
mailItem.Subject = "This is the subject";
mailItem.To = "someone#example.com";
mailItem.Body = "This is the message.";
mailItem.Attachment.Add(logPath);//logPath is a string holding path to the log.txt file
mailItem.Importance = Microsoft.Office.Tools.Outlook.OlImportance.olImportanceHigh;
mailItem.Display(false);
}
}
}
I saw this post:
How to send a mail using Microsoft.Office.Interop.Outlook.MailItem by specifying the From Address
But i can't find the Outlook.Accounts option in my project. It just doesn't appear.
Does anyone have a solution for this problem?
My main goal of course is to send my mail using different user.