Dean Harry
Dean Harry

Reputation: 267

How do you bring Outlook into focus and send it keystrokes in C#?

In my application I am trying to bring Outlook 2010 into focus and send it a CTRL-N (new email).

I have tried many different iterations of ShowWindow, FindWindow, SetFocus, SetForegroundWindow and SendMessage and can't seem to get any of them to work.

It works fine for Notepad, but not for Outlook... My code is:

    using System.Runtime.InteropServices;
    using System.Diagnostics;

    const int kKeyDown = 0x0100;
    const int kKeyUp = 0x0101;
    const int kCtrl = 0x11;
    const int kN = 0x4e;

    Process[] prcOutlook = System.Diagnostics.Process.GetProcesses();
      foreach (System.Diagnostics.Process prcTempProc in prcOutlook)
      {
          if (prcTempProc.ProcessName == "OUTLOOK")
          {
              IntPtr windowToFind = prcTempProc.MainWindowHandle;
              if (ShowWindow(windowToFind, 1))
              {
                  SetFocus(wHndle);
                  int result = SendMessage(windowToFind, kKeyDown, kCtrl, 0);
                  result = SendMessage(windowToFind, kKeyDown, kN, 0);
                  result = SendMessage(windowToFind, kKeyUp, kCtrl, 0);
                  result = SendMessage(windowToFind, kKeyUp, kN, 0);
              }
          }
      }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

The code runs fine, it just never brings Outlook to focus to get the keystrokes...

Where am I going wrong?

Regards, Dean

Upvotes: 1

Views: 2340

Answers (3)

Christophe Geers
Christophe Geers

Reputation: 8962

Don't try to control Outlook (or any other external application) by sending it keystrokes as if you are simulating a real user.

For Outlook you can use COM interop.

A quick guide:

  1. Start a new project, a console application for instance.
  2. Open the Add Reference dialog and select the COM tab
  3. Search for the Microsoft Outlook X Object Library (where X is the version)
  4. Add a reference to it.
  5. Add the namespace "Microsoft.Office.Interop.Outlook" to your using clauses.

You can then execute the following code:

var application = new Application();
var mail = (_MailItem) application.CreateItem(OlItemType.olMailItem);

mail.To = "[email protected]";
// ... other mail properties ...

mail.Display(true);

First you start a new Outlook application. Then you create a new mail item (_MailItem). Use this object to configure the e-mail you want to send (to, from, subject...etc.) and then call its Display(...) method to show the Outlook new mail editor window.

If you want to retrieve the e-mails from your inbox then execute the following code:

var ns = application.GetNamespace("MAPI");
MAPIFolder inbox = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
for (int i = 1; i <= inbox.Items.Count; i++)
{
    var item = (MailItem) inbox.Items[i];
    Console.WriteLine("Subject: {0}", item.Subject);
    //...
}

Let's take the first mail we find in the inbox:

var mailItem = (MailItem) inbox.Items[1];

You can then reply to the sender as follows:

var reply = mailItem.Reply();
reply.Display(true);

As you can see this is very similar to creating a new e-mail.

A reply all is equally simple:

var replyAll = mailItem.ReplyAll();
replyAll.Display(true);

Upvotes: 1

Bobby Tables
Bobby Tables

Reputation: 3013

Try using SendKeys.Send(^N) after you bring you window on top

Upvotes: -1

Bernard
Bernard

Reputation: 7961

Have a look at this question for a different approach to achieving the same result. You should also familiarize yourself with the Outlook PIA.

Upvotes: 1

Related Questions