How to find the Internet Explorer binary

For some reason, some people go to enormous lengths to locate the Internet Explorer binary so they can launch it with some options.

The way to do this is not to do it.

If you just pass "IEXPLORE.EXE" to the ShellExecute function [link fixed 9:41am], it will go find Internet Explorer and run it.

ShellExecute(NULL, "open", "iexplore.exe",
             "", NULL,

The ShellExecute function gets its hands dirty so you don't have to.

(Note: If you just want to launch the URL generically, you should use

ShellExecute(NULL, "open", "",
             NULL, NULL, SW_SHOWNORMAL);

so that the web page opens in the user's preferred web browser. Forcing Internet Explorer should be avoided under normal circumstances; we are forcing it here because the action is presumably being taken response to an explicit request to open the web page specifically in Internet Explorer.)

If you want to get your hands dirty, you can of course do it yourself. It involves reading the specification from the other side, this time the specification on how to register your program's name and path ("Registering Application Path Information").

The document describes how a program should enter its properties into the registry so that the shell can launch it. To read it backwards, then, interpret this as a list of properties you (the launcher) need to read from the registry.

In this case, the way to run Internet Explorer (or any other program) the same way ShellExecute does is to look in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE (substituting the name of the program if it's not Internet Explorer you're after). The default value is the full path to the program and the the "Path" value specifies a custom path that you should prepend to the environment before launching the target program.

When you do this, don't forget to call the ExpandEnvironmentStrings function if the registry value's type is REG_EXPAND_SZ. (Lots of people forget about REG_EXPAND_SZ.)

Of course, my opinion is that it's much easier just to let ShellExecute do the work for you.

Comments (45)
  1. Cooney says:

    Hey Raymond,

    Your sidebar looks all borked in Mozilla, FYI.

  2. Looks fine here, using Firefox 0.9.3

  3. Stephane Rodriguez says:

    A topic revolving around ShellExecute ("http://xxxx"“>http://xxxx") that I have seen covered nowhere : if any COM application is running in the system, then depending on its health it might provide a Ctrl+R ShellExecute("http://xxxx"“>http://xxxx") from showing an Internet Explorer window at all, or very slowly (1 minute for instance to wait before the window pops up). And vice versa.

  4. Note: If you just want to launch the URL generically, you should use

    ShellExecute(NULL, "open", "",


    … For some reason if you do this and your default is internet explorer and you already have a internet explorer browser open then the shell will open it in that browser. I find this very annoying. Why is it so? Why not a new internet explorer.

  5. Cooney says:

    I must have failed to load the stylesheet or something. It’s back to normal, now.

  6. Nekto says:

    Tools -> Options -> Advanced -> Reuse Windows for lunch shortcuts

  7. David Candy says:

    In AppPaths there appear to be several undocumented features.

    One semi documented (and only recently) is the path value. This appends (or prepends) the directory to the Path for that process (and for years I thought it set the current directory).

    There is also OpenURL. And more recently SaveURL appeared. OpenURL seemed to indicate it could work with URL paths and presumbably daveURL is similar. Though what effect this has I don’t know.

    There is also UseShortName.

    It would be good to see actual definitions for these rather than guessing based on their name.

    Now if they only made cmd as smart as shellexecute.

    There are two others.

    Block on TS Non Install mode



    Presumbably these are meant for terminal server and setup/install programs.

    Also one MS component and some third party are storing configuration info here. Such as AVG (it stores the local language that appears on the context menu that it’s faulty context menu extension uses). Also cmmgr32.exe (I think is MS but I don’t actually have the file) uses




    I presume these are app specific.

  8. Raymond Chen says:

    cmd is intentionally not as "smart" as ShellExecute. cmd is for raw low-level stuff. Imagine if you went to cmd.exe and typed "dir" and you didn’t get a directory listing but rather some "filtered pretty version" that the shell "decided" you should see. Imagine if you set your environment variables just right and then ran a command from cmd.exe and cmd.exe went and changed your environment "to help you out".

  9. Raymond Chen says:

    Stephane: It’s called DDE. I’ll write about it later.

  10. Paul Roub says:

    The "some reason", in this case (IE View, linked at the top of your article), is that ShellExecute() was not available to me (at least not with parameters) via the standard XUL libraries.

    Since this was a weekend hack (at best), I didn’t see myself building custom DLLs to get at ShellExecute(); there might be an easier way to get at it, but I’m busy preparing to flee Hurricane Frances, so I probably won’t get to it for a while.


  11. Merle says:

    I don’t think a lot of people know about the "App Paths" key.

    I love it, because I like the apple-R (pause) (type short word) to start an app. And I keep all sorts of little apps scattered around, not in the path.

    But another reason might be that they just don’t trust paths. Which is not totally without reason. Suppose Wily Virus Writer puts an iexplore.exe somewhere high in the path? (on the other hand, I would not even attempt to locate it, because I’m one of those freaks who installs Windows on a drive other than C: and lets nothing live in "Program Files"…)

    BTW, Raymond, your ‘ShellExecute’ hyperlink has an extra %22 at the end of it that breaks it.

  12. Jonathan says:

    Ah yes, the DDE delay… Happens pretty rarely, but just often enough to make it annoying. Nothing like pressing Windows-E only to have your taskbar freeze for a minute.

    I don’t think I’ve noticed it since I installed SP2… but it could still be there.

    I also had something similar with WMP 8 on XP. When I had been playing a CD, but stopped it and ejected it and left the CD drive open, then pressing Windows-E (or any similar DDE request) would cause WMP to bring up an "Error – no disk in drive" message. Gotta love DDE.

  13. runtime says:

    Since we are discussing IE and DDE, I just wanted to spread the word about a known IE/DDE crash on Windows ME. Here is a comment from my product’s code. <:)


    // If an instance of the default browser is not already running when

    // we try to use DDE WWW_OpenURL, Windows ME will launch a new browser

    // process but the browser will occasionally crash in DDEML.DLL. This

    // is a bug in Windows ME and affects both IE and Netscape. This

    // workaround was borrowed from Dreamweaver 4.01.


    // For more information, see the following Macromedia Tech Notes:


    // "Windows ME crashes using Help or Publish Preview"



    // "Dreamweaver, and other programs that make browser calls,

    // sometimes crash when Previewing in Browser on Windows ME."



  14. ATZ Man says:

    I think by now the only people using Windows ME are developers who have it running on an expendable machine to test/debug for ME-compatibility. <font="wingdings">J</font>

  15. Raymond Chen <a href="; title=""How to find the Internet Explorer binary">takes "some people" to task</a> for "[going] to enormous lengths to locate the Internet Explorer binary". The linked poster-child? <a href="">IE View</a>.

  16. Justin Wood (Callek) says:


    The issue with IEView is that as an XUL extension, there can be no compiled code (without much more work) in the extension. IEView is meant to be a simple, compact codelet (which it is) to allow those who use Mozilla Products to open pages that would otherwise be broken to them. (Provided they have IE).

    Mozilla Components do not expose shellExecute because mozilla XUL is intended to be cross OS, and exposing an OS specific function is not usually a nice solution.

    So instead of going through the hurdles of adding a new component to Mozilla for himself, the developer of ieview just added a few rutines to find IE on the users system. If you want to allow it otherwise, the "openwith" extension lets you open the "target" of a URL with any application (you can specify)…so if the syntax ieview uses to find IE doesnt work, the latter will!

    I understand your use for explaining the syntax here, but imo degrading "ieview" without knowing its reasons/design construct (albeit very passively degrading) is not a good course of action.

    But in the end, keep up your wonderfully enlightening blog!

  17. darwou says:

    One thing that bothers me is that cmd.exe will run executables that are named as non-executables.

    For example if you rename "notepad.exe" to "notepad.doc" and enter it at the cmd.exe prompt (using "notepad.doc" or "start notepad.doc"), notepad will come up, not notepad.doc opened in Word.

    However the shell will do the right thing (via ShellExecute) and launch Word with notepad.doc.

    If you enter "document.doc" or "start document.doc", cmd.exe does the right thing, and opens document.doc in Word like Shell does.

    I’d expect cmd.exe to do what Shell does in both cases, or check the filename against %PATHEXT% and reject notepad.doc as an invalid executable.

    I understand this quirk is due to the way CreateProcess works (it grovels the file header to determine if it’s an executable) vs ShellExecute, but it seems like rather dangerous behavior — cmd.exe can accidently launch an executable instead of a document file, and there no way short of inspecting the file before running it to know which it is.

  18. Raymond Chen says:

    Because cmd.exe is doing what you said, even if what you said isn’t what you meant. Cmd.exe is the ultimate power tool – it doesn’t second-guess you. It does exactly what you tell it. You should not operate it carelessly, because there are no safety interlocks and no do-overs.

  19. David Candy says:

    How does create process tell if a file is a bat file, com file or not an executable (assuming it tests the headers first and has concluded it’s not an exe).

  20. asdf says:

    Yeah seriously, I’m with darwou here, I thought the PATHEXT environment variable was supposed to specify which extensions to use as an executable.

  21. Pavel Lebedinsky says:

    CreateProcess looks at the first two bytes of the file and if they are ‘MZ’ it tries to launch it as an executable.

    Try this little experiment: create a file named test.txt and type some text in it starting with MZ, for example "MZasdasdasdasd". Then try to launch it from cmd. On my machine I get an error like this:


    16 bit MS-DOS Subsystem


    C:WINNTsystem32cmd.exe – test.txt

    The NTVDM CPU has encountered an illegal instruction.

    CS:0588 IP:016e OP:ff e9 ff fe 80 Choose ‘Close’ to terminate the application.


    Close Ignore


    CreateProcess noticed that the file starts with MZ, but it didn’t look like a valid PE executable. So CreateProcess decided that it must be a 16-bit program, and launched it inside ntvdm.

  22. Aarrgghh says:

    Raymond: Speaking of dusty old stuff like DDE, what the heck was OLE1, exactly, implementation-wise?

    I’ve found one or two references to it in MSDN, but they were essentially fossil index entries; the actual information was no longer there[1]. It’s not that I have any *use* for the information; just curiosity. Do you do requests? It seems like a good candidate for the Raymond Chen Treatment.

    [1] For example:

  23. Ah yes, the old "How about you make it configurable" option.

    So how do we make this registry switch discoverable? For 99% of the cases, content sniffing will do the right thing for you – the only time you’ll have a problem is if you have a program that’s renamed to be a document. If the thing you’re launching really is a document then cmd.exe will work correctly.

    So you’re looking for a registry switch to control a 1% behavior. If we put in a switch, we need to have a test case for the switch. And that means resources that don’t get spent on other features.

    Is this feature important enough to enough users to justify the expense?

  24. Merle says:

    DDE delays? Happen daily for me. StarTeam 4.2 suffers from them. StarTeam, connected to a server far away down a slow link, can delay your win-E keypress from happening for *minutes*.

    Aarrgghh: didn’t you save every MSDN library CD since the early 90s? I just assumed they would not republish "obsolete" information…

  25. darwou says:

    > it doesn’t second-guess you.

    > It does exactly what you tell it.

    In that case, why does "del *.*" ask "Are you sure (Y/N)?", unless you explicitly tell it not to?

  26. name says:

    If you want to get your hands dirty, you can of course do it yourself. It involves reading the specification from the other side, this time the specification on how to register your program’s name and path ("Registering Application Path Information").

    General issue with reading specs from the other side: As you’ve taught us, Windows implementers often can’t stop when Windows fulfills its part of the contract; their code has to guess what to do when someone breaks the spec. If someone registers an application in a slightly screwy way, ShellExecute may work whereas your version of it may not. If that’s not true of ShellExecute, surely it’s true of other contracts.

    Even more generally, you don’t want to reinvent the wheel unless you must — since lots of hours were put into making the old wheel sturdy.

  27. Jordan Russell says:

    Larry Osterman wrote:

    "For 99% of the cases, content sniffing will do the right thing for you – the only time you’ll have a problem is if you have a program that’s renamed to be a document. If the thing you’re launching really is a document then cmd.exe will work correctly."

    Imagine if Windows Explorer exhibited the same behavior as cmd.exe — if it did the right thing in "99% of cases" but in the remaining cases ran malicious executables disguised under document extensions. Don’t you think people would be exploiting this left and right? Would this not be deemed a "security vulnerability" and fixed in a heartbeat?

    Most of the time I use the command line in place of Explorer. Why should I (and others like me) be exposed to potential trojans disguised as .doc files, while Explorer users are immune to them? Why can’t a file with a .doc extension always be treated as a .doc file, instead of just "99%" of the time?

    I realize, of course, that there could be apps out there that rely on the present behavior. Hence the suggestion to make this "configurable". Regardless, I think this is an issue that deserves attention due to the potential security ramifications.

  28. Jordan Russell says:

    > It does exactly what you tell it.

    Except in this case you can’t tell it what you *want* it to do with the file; cmd.exe chooses one of two behaviors itself based on file’s contents.

    Can’t this be made configurable (e.g. via a registry tweak)? I launch documents from the command line all the time and would prefer that they always open in their associated applications.

  29. Gavin Greig says:

    While recognising what you said about cmd being intentionally not as smart as ShellExecute, why don’t AppPaths work from the command line as well as the Run dialog?

    It’s great that we’re getting a lot more command line tools appearing for Windows developers, but it’s frustrating that there doesn’t seem to be a good mechanism for making them all easily available from the command line. You soon fill your PATH to bursting point, or have to create a single folder location to cram lots of tools that expect their own folders into – or do both.

  30. David Candy says:

    Explorer can do content sniffing. However it’s the third choice used (after file extensions, clsid in compound docs, then sniffing) which is a different order to that which COM uses.

    The byte matching patterns are stored here


    And the docs for it are in the COM part of the SDK.

    So if you rename doc extension to nothing or an unregistered extension it will still open in word from the CLSID stored in the file.

    BIFF files (and I’ve not ever seen one) is one type that is content sniffed. From memory on 95 there were no entries as standard but XP has 10 or so.

    I used to set a match with <html> so html files without extensions would still show in IE.

  31. Dru Nelson says:

    Here is the real issue. What if I just want the browser to start in a *new window*. What if the user isn’t running IE.

    then you have to get down and dirty in the registry to find the appropriate handler for http and shell execute that.

    Starting IE is easy, this is a little more work. For example, Mozilla/Firefox will use quotes differently.

  32. Raymond Chen says:

    If you say "start iexplore" then cmd.exe will fall back to ShellExecute and then all the magic AppPaths stuff happens.

  33. Peter Smith says:

    Getting back to the original comment from Raymond (you know, about finding the IExplore comment….): part of the problem with the solution is the documentation from MSDN. Here’s the part of it that talks about the ‘lpFile’ parameter (which Raymond says should be ‘iexplore.exe’)



    [in] Pointer to a null-terminated string that specifies the file or object on which to execute the specified verb. To specify a Shell namespace object, pass the fully qualified parse name. Note that not all verbs are supported on all objects. For example, not all document types support the "print" verb.


    Who could guess from the aboe that the lpFile doesn’t have to have a path? Or that Shell will do something different from cmd? Raymond, you claim that Shell will find iexplore.exe all by itself: can you back that up with actual written documentation from Microsoft?

    Interestingly, I’ve just looked at the pointer you had to the "Design Specifications and Guidelines – Integrating with the System" section on the AppPath. Did you know that it was wrong? It claims that the AppPath data is directly off of HKLM. Who knew (other than you, of course) that it’s really somewhere else completely?

    As an extra aside, the AppPath documentation doesn’t say that Shell will use the AppPath and cmd won’t; it just says that "the system" will use the AppPath data.

    Part of the fun of writing for Windows is that some undocumented behaviour needs to be shunned, and some undocumented behaviour is encouraged, and some documented behavious is documented incorrectly.

  34. David Candy says:

    Everyone knows about the AppPath key. It was in windows 95 and every program I’ve written has added itself, and repairs at every startup. This has been since 95/NT4 (so 9 years). It’s been a tip on my web site for years.

    To prove it type iexplore in Start Run.

    The shell does not ALWAYS use the apppath key. It uses it if you type in Start Run or shellexecute from a program. If you double click a file it is NOT used (and it should be). From memory it is also the last resort means of finding the file. It is implemented by the shell not create process. Create Process doesn’t use it.

  35. Jeremy Davis says:

    There are those of us who *prefer* cmd not to second-guess us. Frankly, if you’re working from a commandline you ought to know what you’re trying to execute. If you want "friendly" extension-based behavior, explorer and the run dialog are right there for you. Beyond that, if you want your .doc to open in word, there’s always "pathtowinword.exe your.doc". cmd does what you tell it witout question, and it’s one of a very small number of things in Windows that do. Leave it be.

  36. David Candy says:

    You can always use Doskey.

    doskey wipedisk=c:somefolderwipedisk $1

    and set cmd to load a bat on startup to load your doskey definitions.

    One thing I’ve always been curious about is the GUI order of search. Leaving out the non duplicated parts – system32 is searched, then windows, then the path (which is system32 then windows). Does windows really search system32 twice?

  37. Norman Diamond says:

    9/2/2004 12:57 AM Jordan Russell

    > Imagine if Windows Explorer exhibited the

    > same behavior as cmd.exe — if it did the

    > right thing in "99% of cases" but in the

    > remaining cases ran malicious executables

    > disguised under document extensions. Don’t

    > you think people would be exploiting this

    > left and right? Would this not be deemed

    > a "security vulnerability"

    Hear, hear.

    > and fixed in a heartbeat?

    Cynics might guess differently.

    9/2/2004 2:50 AM David Candy

    > Explorer can do content sniffing. […]

    > So if you rename doc extension to nothing or

    > an unregistered extension it will still open

    > in word from the CLSID stored in the file.

    Hmm, so Explorer DOES have a security vulnerability almost as bad as cmd.exe. Fortunately Explorer gives priority to the file’s extension so it will invoke the expected application if it is associated. But if Explorer falls back to a CLSID, a security viewpoint says that Explorer should ask the user if the user wants to run a particular application, where the recommended application is whatever. In some cases Explorer already puts up these prompts, so this just needs to be expanded to cover cases important to security as well.

    By the way,

    9/1/2004 8:13 AM Nekto

    > Tools -> Options -> Advanced ->

    > Reuse Windows for lunch shortcuts

    Does anyone know the rules for when Internet Explorer will obey this setting vs. when Internet Explorer will ignore this setting? I always set it, and the setting always appears to stick (i.e. if I go to Tools – Internet Options again later, it is not cleared), but at random times it doesn’t get obeyed.

    One time recently I clicked on a link in one IE window. The target didn’t open in the same window, and the target didn’t open in a new window, the target opened in a sub-frame of some other existing and unrelated IE window.

    Actually some cases are not completely random. If I click on a link in an OE message, then usually it reuses an existing IE window. (Why do I click on links in OE messages? Well if I have e-mailed a link to myself then I have a tendency to trust it. If anyone wants to phish for me, they’ll have to fake me as the sender and persuade me that the link is one that I e-mailed to myself.)

  38. Gavin Greig says:

    I’ve come across the same documentation issues as Peter Smith regarding AppPaths – thanks to him for jogging my memory.

    Using "start" is OK for launching GUI programs from the command line, but it’s inappropriate for "real" command line use, as the command will be processed in a new command window which may close or not, depending on whether it’s a cmd command, a batch file or a console application that you’ve tried to run.

    To give a trivial example: say I want to be able to use "dir" and "ls" interchangeably to produce directory listings, and I have a console application that provides ls behaviour. If I do "start dir", a new command window appears, containing a directory listing, and stays open until I dismiss it. If I do "start ls", a new command window opens, presumably containing a directory listing, but it disappears again before I can see what’s there.

    Although there might well be circumstances in which you’d want to use a command that runs another command in a new window (as start does), neither of the above behaviours are sensible *default* behaviours for command line programs, which should do their thing, whatever it may be, in the same command window they are launched from.

    If using start is the only way to benefit from AppPaths on the command line, it’s not very satisfactory. As things stand, AppPaths are impractical for console applications and it comes back to having a bloated and maxed-out PATH variable and/or maintaining a bloated common directory for command line tools.

    It would be interesting to hear why this is so.

  39. ATZ Man says:

    N Diamond,

    Browsers open/re-use windows differently than the shell does. You say "I clicked on a link in one IE window. The target didn’t open in the same window, and the target didn’t open in a new window, the target opened in a sub-frame [somewhere]." (By the way, I feel your pain.) A link can have a target attribute, e.g. "<a href="" target="peach">click here</a>" and if there is a frame named peach accessible to the page you clicked on, it will have its document replaced with If said frame does not exist, the doc will open in a new window called "peach".

    The OE thing is some other quirk altogether. Moz TBird does the same thing to Firefox. And I often use "copy link location" to manually transfer the URL from the email to the one instance or tab of Firefox I want to view the link with.

  40. Norman Diamond says:

    9/3/2004 7:07 PM ATZ Man

    > if there is a frame named peach accessible

    > to the page you clicked on, it will have its

    > document replaced

    Oh neat. Odds are that the target frame was some nice unique name like "frame1" that no other web site designer would ever think of using so this kind of collision wouldn’t occur. OK, so this one isn’t IE’s fault.

    > The OE thing is some other quirk altogether.

    > Moz TBird does the same thing to Firefox.

    But OE is part of IE, right? OE is intentionally violating the user’s setting.

    Are TBird and Firefox part of the same program? Can one exist without the other? Can Linux exist without them? Anyway, it sounds likely to also be a bug, maybe an intentional bug-for-bug workalike.

  41. Dana Epp says:

    OMG. PLEASE don’t do this. Just because it’s easy doesn’t mean you want to do this. (I am referring to jamming in document extensions and letting ShellExecute figure out what to execute).

    Most developers use ShellExecute. It seems harmless enough as in the docs it is explained as a wrapper around the CreateProcess() API call. But thats wrong. It might wrap the CreateProcess() call, but it does so in a way that exposes your code to the potential of tainted data injection, or more to the point misdirection threats.

    ShellExecute() uses the built in file association data stored in the registry to determine which process will be passed to CreateProcess. So if you feed it *.DOC file and Word is installed, it will execute Word accordingly. Some of you pointed this out already. The real problem with this is that an attacker could modify the association and point it to their malicious program. In doing so, you increase the attack surface of your application as you have untrusted data determining your code execution path. Very bad. Very bad indeed.

    A more secure way to do this is to call CreateProcess() directly. But I wouldn’t even recommend that. What I would recommend would be to use the the CreateProcessAsUser() API. It is similar to CreateProcess() but you can force the new process to run in the security context of the user you truely want to execute as. You can create a security descriptor to tie this down even further, and even use a restricted token to ensure this new process has only the required access to do its task. Remember, all code execution should be ran with least privilege whereever possible. Even if all you are doing is launching a browser. Well, maybe its even MORE important when launching a browser these days! :)

    If you need to spawn secondary processes in Windows, forget using ShellExecute(). Instead, use CreateProcessAsUser(). Looking at the unneccesary risk at blindly calling out untrusted code, its very little extra work to actually find the binary you want and ensuring you load it in a safe context with the minimum amount of privileges to do its work.

  42. It would be beautiful if I didn’t have to emulate the whole of ShellExecute in my program; but unfortunately it seems to be necessary.

    If you use ShellExecuteEx in a multithreaded apartment (MTA), it works as long as you don’t try to use it to open "; (or some other URL). If you do, it fails with ERROR_ACCESS_DENIED.

    Some experiments with bouncing the command through to my process’s main STA led to unexplained 35-second delays during which the whole of Windows XP was completely unresponsive… so I’ve ended up having to parse all the registry entries myself.

  43. Raymond Chen says:

    The delay is most likely wedged DDE. If you reimplemented ShellExecute you’d run into the same problem. (Assuming you implemented the DDE part.)

  44. Stefan Kanthak says:

    Raymond wrote:

    > When you do this, don’t forget to

    > call the ExpandEnvironmentStrings

    > function if the registry value’s

    > type is REG_EXPAND_SZ. (Lots of

    > people forget about REG_EXPAND_SZ.)

    Will you write a few words why it’s not used throughout windows?

    Can you write a few words why so many DLLs and EXEs are referenced in the registry without their full path?

    Take 269049 for example: no fix would have been necessary if the full path was given.

    With XP it was, but in braindead manner: while the HIVESFT.INF writes it as REG_EXPAND_SZ=%SystemRoot%system32userinit.exe, some "wise" guy decided to replace this during setup with REG_SZ=c:windowssystem32userinit.exe.

    What follows can be read in Q249321, and the security hole is open again?!

Comments are closed.