1

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

Dean Harry
  • 277
  • 1
  • 3
  • 13
  • Are you writing some sort of virus? – BoltBait Feb 16 '12 at 00:54
  • 3
    I can think of 5 reasons off the top of my head that this code might not be working. Thus, and for other reasons, this is really not the best way of sending an email from a .NET application. Investigate the `System.Net.Mail` namespace and see if you can't find a better alternative. – Cody Gray - on strike Feb 16 '12 at 00:59
  • I don't actually want to send the email, just open a new email window. I am working on some voice recognition stuff and want the app to do many other things, opening a new email window is just one example. – Dean Harry Feb 16 '12 at 02:49

3 Answers3

1

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

Community
  • 1
  • 1
Bernard
  • 7,908
  • 2
  • 36
  • 33
  • I have had a look at that before and it will probably work for sending a new message, but that's only the start of what I am trying to do, I also want to do things like Reply, Reply All, Forward etc... I'll have a read through the IPA, thanks :) – Dean Harry Feb 16 '12 at 01:49
1

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 = "anonymous@somedomain.com";
// ... 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);
Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
-1

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

Bobby Tables
  • 2,953
  • 7
  • 29
  • 53
  • The problem is bringing the window on top... I can't get that to work. – Dean Harry Feb 16 '12 at 01:50
  • Ok then have a look at this:`[DllImport("User32.dll", EntryPoint = "SetForegroundWindow")] public static extern bool SetForegroundWindow(IntPtr hWnd);` – Bobby Tables Feb 16 '12 at 08:55
  • yes, I have look at that before, it works fine for Notepad, and Calculator and most other programs, just not for Outlook... I am starting to think that it has something to do with child windows perhaps... – Dean Harry Feb 16 '12 at 08:58
  • Just tried it with my Outlook and it works, another suggestion would be to try adding a Thread.Sleep(100) if you're the one lunching Outlook – Bobby Tables Feb 16 '12 at 09:01
  • Trying to solve any problem with Thread.Sleep is usually a really bad idea – LostSalad Jun 26 '14 at 09:14