http://www.perlmonks.org?node_id=9724

httptech has asked for the wisdom of the Perl Monks concerning the following question:

I want to do something very simple; launch the default browser in Win32 to go to a specified URL.

I've tried all the methods below; however, none seems to be a perfect solution.

For instance, I can use the easiest method, which is simply: system("start http://www.perlmonks.org/") but that opens a console window, and this is a GUI app, so that's an undesirable result. Plus, there is a delay of at least 10-15 seconds in launching Netscape. I'm not sure if there would be the same delay with IE or another browser, but it seems to take forever. Maybe this is a bug in Win32 but I can't just accept this solution.

I can use Win32:Process to avoid the console window opening, but the delay is still there. Note that using the "start" command from the MS-DOS window does not have a delay; it's only when I call it from perl.

I can get rid of the delay by calling the browser executable directly. To do that I use Win32::Registry to get the path to the browser:

use Win32::Process; use Win32::Registry; my $browsekey; my %vals; $main::HKEY_CLASSES_ROOT->Open('HTTP\shell\open\command', $browsekey) +|| die "Open f]ailed: $!"; $browsekey->GetValues(\%vals); my $default_browser = $vals{''}[2]; $default_browser =~ s/\.exe\s*(.*)/\.EXE/i; my $browser; Win32::Process::Create($browser, $default_browser, "$default_browser "http://www.perlmonks.org", 0, NORMAL_PRIORITY_CLASS, ".") || return 0;
This works on my system, but when I sent this to a friend it did not work on hers. I didn't really like this method anyway, there has to be an easier way.

So, I used the Win32:OLE example from Learning Perl on Win32:

use Win32::OLE; my $browser = CreateObject OLE "InternetExplorer.Application.1" || r +eturn 0; $browser->{'Visible'} = 1; $browser->Navigate("http://www.perlmonks.org/");
This works fine, except I'm now forcing the user to use IE instead of Netscape. And it's possible (not likely I realize) that they don't even have IE. So what happens then?

So, is there a generic way to call the default browser on Win32 that is guaranteed to work properly on any normal system?

Replies are listed 'Best First'.
Re:
by httptech (Chaplain) on Apr 30, 2000 at 19:40 UTC
    The wisdom of the anonymous monk led me on a quest to seek out the mysteries of Win32::API. However, I couldn't seem to make that work, but luckily I stumbled upon Win32::Shell, which solved all my problems:
    use Win32::Shell; Win32::Shell::Execute("open", "http://www.perlmonks.org", undef, undef +, "SW_SHOWNORMAL");
    It started the default browser opened to the correct URL, with no delay, and no console window.

    Do I get extra XP for answering my own question? :)

      I tried to find Win32::Shell, and I cannot find it. I looked in
      CPAN and I did not see it listed. Where did you find it? Thanks..
        Hi, I used the Win32::Shell to open the default browser, but is it possible to open two different windows from the same Perl App? So that one button opens Browser A and another button opens Browser B. Then is it possible to Send different URL's to browser A and Browser B? Regards Marty <Martin.Moss@excite.com>
Re:
by blackwolf (Sexton) on Apr 30, 2000 at 10:01 UTC

    The following is a modified version of a Java function I borrowed from one of the Javaworld tips to fire up the default browser at a particular URL in Windows:

    $url = ...;
    $cmd = "rundll32 url.dll,FileProtocolHandler $url";
    unless ( fork ) { exec $cmd; }
    
    I'm not on a Windows box now, so I don't know the ramifications of using Perl's fork() under Win32, and I haven't tested this code. Of course, there should be a bit of error checking here and there, but you get the general idea. The tech tips can be found off Javaworld at http://www.javaworld.com/ - just search for 'browser' on the tips page (they also have code for kicking off a browser in Unix).
      I came across this thread several years after the original post, and would like to confirm that this rundll32 solution works perfectly. It is also much better than the Win32::Shell solution, because it doesn't require a module install.

      Before finding the answer here, I had tried extracting the http handler program from the registry and calling it directly. That seemed fine until I tried to switch my default browser to Internet Explorer. The exe lives in "C:\Program Files\Internet Explorer\iexplore.exe" so exec() cannot be used because of the spaces in the path. system() worked, but the script doesn't return until the Explorer window is closed.

      I have now

      my $url = $baseurl . join("&", map {"$_=$params{$_}"} keys %params); my $cmd = qq{rundll32 url.dll,FileProtocolHandler "$url"}; exec $cmd;
      which works reliably.

      The next question will be how to achieve the same thing on Mac and Linux to have a multi-platform script, but that will be in another thread.

      Sorry I can't be more technical here but I just don't have the technical details to hand.

      There is a Windows API function called ShellExecute which I think is what you are looking for. Look in the Win32 modules, and you should find more details. This should avoid the problem that you mention about the console window.

      As for the delay, maybe the console approach is slower, I don't know. I've done this through VB (with the API function) and it takes just as long as Netscape or IE would normally take to open up.

      Hope this helps

Re: How do I launch my browser in Win32 to go to a specified URL?
by Intrepid (Deacon) on Jun 29, 2000 at 12:10 UTC
     buzzcutbuddha wrote on Mon May  1 2000 at 09:47
     I tried to find Win32::Shell, and I cannot find it.  I looked in CPAN and I did not see it listed.  Where did you find it?

    Thanks..

    I know this is an old message ... but I'll answer anyway because I was so glad to read this information. To get Win32::Shell I just fired up ppm (I use ActivePerl) and installed it. So, its on ppm. Why it wouldn't be on CPAN I do not know.

    HTH,
    Intrepid

    Q: What is the sound of several hundred Perler-dogs chasing cool code?
    A: YAPC - YAPC - YAPC .. ! :)