Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Where is the Default Browser Command Line in Registry

4.67/5 (2 votes)
21 Jun 2013CPOL 28.1K  
This tip shows how to find the default browser command line in registry using Visual C++.

Introduction

This tip shows how to find the default browser command line in registry using Visual C++.

Background

Normally, you use ShellExecute() or ShellExecuteEx() to open a URL in the default browser.

But sometimes, you need to know the exact path to the executable. For example, when you want to launch Internet Explorer at low integrity level from a high integrity level process.

Using the Code

Copy the following code into your project: 

C++
//
// (c) 2013 Leonid Belousov http://www.mastercluster.com/
//
// DESCRIPTION
//        Finds current browser command line.
//        The command line includes a placeholder parameter %1 for a URL to open.
//
// INPUT
//        A pointer to an uninitialized string buffer variable.
//
// OUTPUT
//    true:
//        The browser path has been found and copied in to pszFilepath.
//        The function allocates a buffer of TCHARs for pszFilepath.
//        Caller must free the buffer by calling "delete [] var" on that buffer variable
//    false
//        The current browser path was not found, pszFilepath == 0.
//
// EXAMPLE
//    LPTSTR pszBrowserPath;
//    if (GetDefaultBrowserLaunchPath(&pszBrowserPath)) {
//        ...
//        delete [] pszBrowserPath;
//    }
//
bool GetDefaultBrowserLaunchPath(LPTSTR *pszFilepath)
{
    bool    bRes            = false;
    *pszFilepath            = 0;
    HKEY    hKey            = 0;
    TCHAR    szData[1024]    = {0};
    DWORD    dwDataSize        = 0;
    //
    // Vista+ case
    //
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT(
         "Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice"),
        0, KEY_QUERY_VALUE, &hKey))
    {
        //
        // Vista+ does not always have the registry entry we use in the WinXP case (?)
        // So we do a workaround:
        //        1. Read the current browser Progid value from HKCU (current user!)
        //        2. Use this Progid to get the browser command line from global HKCR
        ///          (as every browser in the system writes its command line into HKCR)
        //
        dwDataSize    = ARRAYSIZE(szData)*sizeof(szData[0]);
        if (ERROR_SUCCESS != RegQueryValueEx
        (hKey, TEXT("Progid"), 0, 0, (LPBYTE)&szData, &dwDataSize))
            goto Cleanup;
        if (!dwDataSize)
            goto Cleanup;
        RegCloseKey(hKey); hKey = 0;
        _tcscat_s(szData, ARRAYSIZE(szData), TEXT("\\shell\\open\\command"));
        if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szData, 
            0, KEY_QUERY_VALUE, &hKey))                                   // Using HKCR (!)
            goto Cleanup;
    }
    else
    {
        //
        // WinXP case
        //
        if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, TEXT(
                 "Software\\Classes\\http\\shell\\open\\command"), 
            0, KEY_QUERY_VALUE, &hKey))        // Using HKCU in WinXP (!)
            goto Cleanup;
    }

    if (ERROR_SUCCESS != RegQueryValueEx(hKey, 0, 0, 0, 0, &dwDataSize))
    // Get size in bytes of the default key's value
        goto Cleanup;

    DWORD nMaxSize    = dwDataSize/sizeof(TCHAR)    // Buf size in chars
        + 3            // +3 chars to reserve the space for an optional " %1" param
        + 1;        // +1 char for \0 terminator
    *pszFilepath    = new TCHAR[nMaxSize];
    if (ERROR_SUCCESS != RegQueryValueEx(hKey, 0, 0, 0, (LPBYTE)(*pszFilepath), &dwDataSize))
    {
        delete [] (*pszFilepath);
        *pszFilepath = 0;
        goto Cleanup;
    }
    if (!_tcsstr(*pszFilepath, TEXT("%1")))
        _tcscat_s(*pszFilepath, nMaxSize, TEXT(" %1"));
        // Add a URL placeholder (it is missing in IE) to the end of the command line
    bRes = true;
Cleanup:
    if (hKey)
        RegCloseKey(hKey);
    return bRes;
}    // GetDefaultBrowserLaunchPath

Here is how to use the code above:

C++
LPTSTR pszBrowserPath;
if (GetDefaultBrowserLaunchPath(&pszBrowserPath))
{
    MessageBox(0, pszBrowserPath, 0, MB_OK);
    // Make sure to release the memory allocated by GetDefaultBrowserLaunchPath!
    delete [] pszBrowserPath; 
}

If the function succeeds, it returns a command line including a %1 placeholder. You should replace this placeholder with a URL you want to show in the browser.

Points of Interest

The code uses different registry locations to find the default browser command line for WinXP and Vista+.

I would be happy to know if there is a more straightforward way to do the task this tip describes because there is surprisingly too little information on the Internet on how to achieve this.

Launching a low integrity level process from a high integrity level process is out of scope of this article, but there is a very good post on this topic.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)