3

Using: Visual Studio 2017 (Language: C#)

I have a similar function written below in PowerShell script, but I need the C# version of it to execute on the click of a button within Visual Studio:

Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$outlook = new-object -comobject outlook.application

$namespace = $outlook.GetNameSpace("MAPI")

dir “$env:userprofile\Documents\Outlook Files\*.pst” | % { $namespace.AddStore($_.FullName) }

Any insight or examples of code would be much appreciated.

NineBerry
  • 26,306
  • 3
  • 62
  • 93
Josh Pulda
  • 45
  • 5

2 Answers2

2

You can do that the following way:

In your project, right click on "References" and add a reference to the assembly "Microsoft.Office.Interop.Outlook".

Then you can use the following code:

/// <summary>
/// Get a reference to an already running or a newly started Outlook instance
/// </summary>
Microsoft.Office.Interop.Outlook.Application GetOutlookApp()
{
    Microsoft.Office.Interop.Outlook.Application app = null;

    // Try to get running instance
    try
    {
        app = Marshal.GetActiveObject("Outlook.Application") as Microsoft.Office.Interop.Outlook.Application;
    }
    catch(Exception)
    {
        // Ignore exception when Outlook is not running
    }

    // When outlook was not running, try to start it
    if(app == null)
    {
        app = new Microsoft.Office.Interop.Outlook.Application();
    }

    return app;
}

private void button1_Click(object sender, EventArgs e)
{
    const string fileName = @"D:\MyDings.pst";

    var app = GetOutlookApp();
    var nameSpace = app.GetNamespace("MAPI");

    nameSpace.AddStore(fileName);

    MessageBox.Show("Done");
}
NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • Is there a way I can specify to pull all of the PSTs from “$env:userprofile\Documents\Outlook Files\*.pst” where you set const string fileName = @"D:\MyDings.pst"; ? – Josh Pulda Mar 29 '18 at 16:23
  • 1
    List the files with the extension from that directory and call AddStore for each file (That is what the Powershell code does as well). This is outside the scope of this question, but look at https://stackoverflow.com/questions/13301053/directory-getfiles-of-certain-extension – NineBerry Mar 29 '18 at 16:29
  • On how to get the folder path to the user profile, see for example https://stackoverflow.com/questions/9993561/c-sharp-open-file-path-starting-with-userprofile – NineBerry Mar 29 '18 at 16:30
  • Your answer works great for specifying a single .pst file! Is there a way that I can AddStore all of my PSTs without specifying each of their file names? Like a foreach that AddStore's each .pst within a folder or directory..? – Josh Pulda Mar 29 '18 at 17:11
  • @JoshPulda See my previous comments. You have to find the files and then call AddStore for each file. But the PowerShell code does nothing else. – NineBerry Mar 29 '18 at 17:49
  • Thanks! Your original code was working fine, but now I keep getting this error: System.Runtime.InteropServices.COMException: 'Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).' – Josh Pulda Mar 29 '18 at 18:33
  • 2
    CO_E_SERVER_EXEC_FAILURE means your app and Outlook are running in different contexts. Is either app running with elevated privileges (Run As Administrator)? How is your app invoked? – Dmitry Streblechenko Mar 30 '18 at 14:23
0

I'm not 100% sure if it is possible without extra packages. So I would just do a shell command executing the powershell script, since you already have that. Bit of a hack but seems the easiest option.

using System.Diagnostics;
Process.Start("powershell.exe " + scriptLocation);
Tom Dee
  • 2,516
  • 4
  • 17
  • 25