6

Is there a common method/api to list all web browsers (name, executable, default yes/no) installed on my machine (and per user), and how to find out which is the default web browser?

I have seen this question: How to find all the browsers installed on a machine

And on MSDN: How to Register an Internet Browser or Email Client With the Windows Start Menu which states that web-browsers should register themselves under HKLM\SOFTWARE\Clients\StartMenuInternet (and HKCU)

Is that really the common/correct approach? (And if yes, any solid implementation out there?)


My goal is to create a drop-down menu with a list of all web-browsers installed on user's machine (indicating the default), and allow the user to browse his HTML file/URLs with one of the external web-browser available.

Community
  • 1
  • 1
kobik
  • 21,001
  • 4
  • 61
  • 121
  • 1
    You can probably get the default browser, based on whatever's set up to handle .url files and http/https urls, but there's nothing in windows that'll say "this app is a browser" or "this app embeds a browser" – Marc B Mar 23 '12 at 15:06
  • @David, I'm looking for a solid answer from programmers (who might have also *implemented* the above). please leave the tags as is. – kobik Mar 23 '12 at 16:10
  • Well, I don't see what the question has to do with specific programming languages. Do you mean that you don't want to hear from an informed C# programmer? – David Heffernan Mar 23 '12 at 16:13
  • 1
    @kobik The thing is Delphi is not mainstream and I think you may turn away potentially good answerers who run and hide from anything that says Delphi. Anyway, that's just my opinion and I respect yours also. – David Heffernan Mar 23 '12 at 17:16
  • Check this: http://www.rhizohm.net/irhetoric/post/2009/04/03/0a-Finding-All-Installed-Browsers-in-Windows-XP-and-Vista-ndash3b-beware-64bit!0a-.aspx – SepehrM Apr 28 '14 at 18:33

2 Answers2

7

You could do something like

procedure ListRegisteredBrowsers(List: TStrings);
var
  reg: TRegistry;
  ki: TRegKeyInfo;
  i: Integer;
  keyname: string;
  len: DWORD;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if not Reg.KeyExists('\SOFTWARE\Clients\StartMenuInternet') then Exit;
    if not Reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet', false) then
      raise Exception.Create('ListRegisteredBrowsers: Could not open registry key.');
    if not reg.GetKeyInfo(ki) then
      raise Exception.Create('ListRegisteredBrowsers: Could not obtain registry key information.');
    List.Clear;
    SetLength(keyname, len);
    for i := 0 to ki.NumSubKeys - 1 do
    begin
      len := ki.MaxSubKeyLen + 1;
      if RegEnumKeyEx(reg.CurrentKey, i, PChar(keyname), len, nil, nil, nil, nil) <> ERROR_SUCCESS then
        RaiseLastOSError;
      if reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet\' + keyname, false) then
        List.Add(reg.ReadString(''));
      Reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet', true);
    end;
  finally
    reg.Free;
  end;
end;

and

function GetDefaultBrowser: string;
var
  reg: TRegistry;
begin
  result := '';
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet', false) then
      result := reg.ReadString('')
    else
    begin
      reg.RootKey := HKEY_LOCAL_MACHINE;
      if Reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet', false) then
        result := reg.ReadString('')
    end;
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SOFTWARE\Clients\StartMenuInternet\' + result, false) then
      result := reg.ReadString('');
  finally
    reg.Free;
  end;
end;

Test it:

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
  i: Integer;
  DefBrw: string;
begin
  DefBrw := GetDefaultBrowser;
  sl := TStringList.Create;
  try
    ListRegisteredBrowsers(sl);
    Memo1.Lines.BeginUpdate;
    for i := 0 to sl.Count - 1 do
      if SameText(sl[i], DefBrw) then
        Memo1.Lines.Add(sl[i] + ' (Default)')
      else
        Memo1.Lines.Add(sl[i]);
    Memo1.Lines.EndUpdate;
  finally
    sl.Free;
  end;
end;
Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • Thanks. I can't test the code just yet. but I see that there is no `HKCU` in the `ListRegisteredBrowsers`, and in the `GetDefaultBrowser` you give priority to `HKCU`. any reason for that decision? – kobik Mar 23 '12 at 16:45
  • 1
    My understanding is that the list of installed browsers is found in HKLM, only. In both HKLM and HKCU you can find the default browser, though (of course -- this is a per-user setting). – Andreas Rejbrand Mar 23 '12 at 16:51
  • Your code was really helpful and gave me a good starting point. Thanks a lot :) – kobik Mar 25 '12 at 19:43
6

That method finds all the browsers that are registered as Start Menu Internet Applications. In practice that will suffice since all the major browsers register themselves in this way. If a browser fails to register itself as a Start Menu Internet Applications then it has no chance of Windows noticing it and offering that browser to the user.

The MSDN topic that explains it all is here: http://msdn.microsoft.com/en-us/library/windows/desktop/dd203067.aspx

The Start menu in Windows XP and Windows Vista contains reserved slots for the default Internet (browser) and E-mail (mail) clients, together commonly known as Start Menu Internet Applications. Applications which register as Start Menu Internet Applications do so across the entire system (per-machine). In Windows Vista, the user may use the Default Programs feature to set a per-user default.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks for the answer. I have included that MSDN topic in my initial question, and it does looks pretty much a reliable way. Have you implemented that in practice? – kobik Mar 23 '12 at 15:20
  • 3
    @kobik No, but all my browsers are listed in the registry exactly as described. After the massive EU lawsuit I think it's safe to say that all mainstream browsers, and probably most non-mainstream browsers will register themselves there. – David Heffernan Mar 23 '12 at 15:26