Determine the default browser

By: Matthias Thoma

Abstract: This article describes how to determine the default browser and its version.

Determine the default browser


The WinAPI provides an excellent function for this purpose: FindExecutable. This function returns the application associated with the given file. The application associated with a .htm file is the default browser.

The prototype is

function FindExecutable(FileName, Directory: PChar; Result: PChar): HINST;

Unfortunately this function needs an existent file. For this reason it is necessary  to create a temporary one.

Basic function

The basic function performs the following steps
  • Determine the temp directory
  • Create a file with ".htm" extension.
  • Use FindExecutable
  • Delete the temporary file

type
  TBrowserInformation = record
    Name     : String;
    Path     : String;
    Version  : String;
  end;


function GetDefaultBrowser : TBrowserInformation;
var
  tmp : PChar;
  res : PChar;

begin
  tmp := StrAlloc(255);
  res := StrAlloc(255);

  try
    GetTempPath(255,tmp);
    FileCreate(tmp+'htmpl.htm');
    FindExecutable('htmpl.htm',tmp,Res);
    Result.Name := ExtractFileName(res);
    Result.Path := ExtractFilePath(res);
    SysUtils.DeleteFile(tmp+'htmpl.htm');
  finally
    StrDispose(tmp);
    StrDispose(res);
  end;
end;

Long File Name

Now, if you run that function you will notice that there is a small inconvenience: The function returns the location of the default browser as short path. The next function will try to convert it to the long format.

function LongPathName(ShortPathName: string): string;
var
  PIDL: PItemIDList;
  Desktop: IShellFolder;
  WidePathName: WideString;
  AnsiPathName: AnsiString;

begin
  Result := ShortPathName;
  if Succeeded(SHGetDesktopFolder(Desktop)) then
  begin
    WidePathName := ShortPathName;
    if Succeeded(Desktop.ParseDisplayName(0, nil, PWideChar(WidePathName),
      ULONG(nil^), PIDL, ULONG(nil^))) then

    try
      SetLength(AnsiPathName, MAX_PATH);
      SHGetPathFromIDList(PIDL, PChar(AnsiPathName));
      Result := PChar(AnsiPathName);

    finally
      CoTaskMemFree(PIDL);
    end;
  end;
end;

Version Information

The next step is to extend the basic function with error handling and the ability to get the default browsers version.

function GetDefaultBrowser : TBrowserInformation;
var
  tmp : PChar;
  res : PChar;
  Version : Pointer;
  VersionInformation : Pointer;
  VersionInformationSize : Integer;
  Dummy : Integer;


begin
  tmp := StrAlloc(255);
  res := StrAlloc(255);

  Version := Nil;

  try
    GetTempPath(255,tmp);

    if FileCreate(tmp+'htmpl.htm') <> -1 then
    begin
      if FindExecutable('htmpl.htm',tmp,res) > 32 then
      begin
        Result.Name := ExtractFileName(res);
        Result.Path := LongPathName(ExtractFilePath(res));

         // Try to determine the Browser Version

        VersionInformationSize := GetFileVersionInfoSize(Res,Dummy);

        if VersionInformationSize > 0 then
        begin
          GetMem(VersionInformation,VersionInformationSize);
          GetFileVersionInfo(Res,0,VersionInformationSize,VersionInformation);

          VerQueryValue(VersionInformation,('StringFileInfo040904E4ProductVersion'),
          Pointer(Version),Dummy);

          if Version <> Nil then
            Result.Version := PChar(Version);

          FreeMem(VersionInformation);
        end;
     end
      else
        raise EGetDefaultBrowser.Create('Can''t determine the executable.');

      SysUtils.DeleteFile(tmp+'htmpl.htm');
    end
    else
      raise EGetDefaultBrowser.Create('Can''t create temporary file.');

  finally
    StrDispose(tmp);
    StrDispose(res);
  end;
end;

The complete source code can be found at Code Central.
Delphi: DefaultBrowser.pas (ID: 15308)

Server Response from: BDN10A

 
© Copyright 2008 Embarcadero Technologies, Inc. All Rights Reserved. Contact Us   Site Map   Legal Notices   Privacy Policy   Report Software Piracy