Using IELaunchURL in C# to launch a protected mode Internet Explorer 7 window

25 September 2008

By popular demand, here's the C# equivalent of the C/C++ program I posted earlier today. As things work in the Windows native code world, the C# equivalent takes about 80 lines of code (vs 30). Might be the XML comments though.

The main method to the program; if the URL is passed in as a parameter, it will be sent to IE.

class Program
{
    static int Main(string[] args)
    {
        string url = args.Length > 0 ? args[0] : null;
        return ProtectedModeHelper.LaunchInternetExplorer(url);
    }
}

Structures that need to be defined:

IELAUNCHURLINFO (can be found in the Windows SDK iepmapi.h header file)
PROCESS_INFORMATION (used by CreateProcess, found on PInvoke.net)

Safe native methods:

ieframe.dll: IELaunchURL

Here's the helper class and native methods that I came up with. The return value of LaunchInternetExplorer is the PID, or 0. If the machine is not running Windows Vista, then you'll receive a NotSupportedException.

ProtectedModeHelper.cs

using System;
using System.Runtime.InteropServices;

namespace YourNamespaceHere
{
    // Engineered from iepmapi.h in the Windows SDK
    [StructLayout(LayoutKind.Sequential)]
    internal struct IELAUNCHURLINFO
    {
        public int cbSize;
        public int dwCreationFlags;
    }

    // PInvoke.net
    // http://www.pinvoke.net/default.aspx/Structures/PROCESS_INFORMATION.html 
    [StructLayout(LayoutKind.Sequential)]
    internal struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    /// <summary>
    /// Native methods class.
    /// </summary>
    internal static class SafeNativeMethods
    {
        /// <summary>
        /// The Internet Explorer UI library.
        /// </summary>
        private const string InternetExplorerUILibrary = "ieframe.dll";

        /// <summary>
        /// Launch a URL with Internet Explorer. Works with IE's protected 
        /// mode.
        /// </summary>
        /// <param name="url">The URI to navigate to.</param>
        /// <param name="pProcInfo">Process information struct by reference 
        /// that will contain the opened process ID.</param>
        /// <param name="lpInfo">The launch information struct.</param>
        /// <returns>Returns a value indicating whether the native call was 
        /// successful.</returns>
        [DllImport(InternetExplorerUILibrary)]
        internal static extern bool IELaunchURL(
            [MarshalAs(UnmanagedType.LPWStr)] string url, 
            ref PROCESS_INFORMATION pProcInfo, 
            ref IELAUNCHURLINFO lpInfo);
    }

    /// <summary>
    /// Launch a protected mode IE and provide the process ID.
    /// </summary>
    public static class ProtectedModeHelper
    {
        /// <summary>
        /// Launch Internet Explorer and return the PID. Requires Vista; an 
        /// Exception will be thrown on platforms prior to it.
        /// </summary>
        /// <param name="url">The url to navigate to. Providing null will 
        /// navigate the browser to the user's homepage.</param>
        /// <returns>Returns the IE process ID if successful, or 0.</returns>
        public static int LaunchInternetExplorer(string url)
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                IELAUNCHURLINFO li = new IELAUNCHURLINFO();
                li.cbSize = Marshal.SizeOf(typeof(IELAUNCHURLINFO));
                return SafeNativeMethods.IELaunchURL(url, ref pi, ref li) ?
                    pi.dwProcessId : 0;
            }
            else
            {
                throw new NotSupportedException("Protected Mode requires Windows Vista or later.");
            }
        }

        /// <summary>
        /// Launch Internet Explorer and returns the PID.
        /// </summary>
        /// <returns>Returns the IE process ID if successful, or 0.</returns>
        public static int LaunchInternetExplorer()
        {
            return LaunchInternetExplorer(null);
        }
    }
}

Hope this helps!

Jeff Wilcox is a Software Engineer at Microsoft in the Open Source Programs Office (OSPO), helping Microsoft engineers use, contribute to and release open source at scale.

comments powered by Disqus