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

I have a web page using CGI that needs to open a URL in a separate web page. The users of the CGI page will all be IE users if that helps.

There is a form on the page which allows the user to select an application to start. Submitting the form will kick off several processes (like weblogic, or app specific processes) and then sleep until these processes are complete and then start a browser with the chosen application's URL.

I've tried several ideas. But in each case, NOTHING HAPPENS. The originating CGI page reloads itself, but no new page.
system("start $SelectedAppURL") if $^O =~ /win/i;
And
use HTML::Display; my $browser = HTML::Display->new(); $browser->display(location => $SelectedAppURL);
And
use Win32::OLE; my $browser = new Win32::OLE 'InternetExplorer.Application'; $browser->Navigate($SelectedAppURL, 0, 'xyzzy');
And
use Win32::FileOp qw(ShellExecute); ShellExecute($SelectedAppURL);
The variable URL seems to work, but even if it didn't I'd expect IE to start and give me a 'Page Not Found' message. I have tried using a static URL in place for testing (www.yahoo for instance) with the same result. Ideas?

UPDATE
Another piece of info that should be helpful given the client/server responses: Everything here will be run on a vmware virtual machine. So the server and client are on the same machine for all uses. This is also why I can assume 100% IE, not that this really matters.

UPDATE 2
Given that this is an IIS session, it does seem harder than need be. I still think it's possible (and easier in a different environment), but ended up going the JavaScript route. Thanks to all the Monk's suggestions despite my hard headedness.

Do you believe in miracles? Yes!

Replies are listed 'Best First'.
Re: Open another IE browser window from CGI
by Joost (Canon) on Jan 23, 2008 at 22:12 UTC
    It looks like you don't understand the web at all.

    see this for a very short introduction.

    The CGI/whatever webserver code does not run on the browser, or the browser's system. It runs on whatever machine you've installed your CGI code on. In general the only code that will run on the browser itself is Javascript.

    In other words, you can't use $^O in server-side perl, since that checks the server's operating system, which will remain the same until you move the code to another machine yourself. update: and you definitely do not want to open a bunch of browser windows on the server either.

    What you want is to have the code that runs on the browser to behave in a certain way. For some reason you expect the users all to use IE, but that's immaterial. What you have to realize is that the behaviour of the browser is determined by whatever the browser receives. There are ways to open a new browser window. One is to use Javascript to open a new window with a new url. See window.open(). The other is to use a target attribute on a link.

      you have to run javascript on the client side.so your cgi script should output the following among others:
      <html> <head> <script language="JavaScript"> <!-- function open_new_window(url,name) { new_window = window.open('http://www.perlmonks.com','perlmonks','width +=300,height=200,left=100,top=30') } // --> </script> </head> <body onload="open_new_window()"> a perlmonks window should appear </body> </html>
      In this instance, the browser and server will always be on the same machine (a vmware image). So shouldn't this open a new browser session on the server side?
      Do you believe in miracles? Yes!
Re: Open another IE browser window from CGI
by olus (Curate) on Jan 23, 2008 at 21:40 UTC
    Why not give the HTML TARGET attribute a try?
    That attribute will allow to specify the target window where the contents are to be displayed.

    This is not a Perlish reply, but it would be my approach to the solution of the problem, instead of having Perl launching applications.
Re: Open another IE browser window from CGI
by moritz (Cardinal) on Jan 23, 2008 at 22:03 UTC
    Your last two examples look like you try to open an application on the server and somehow hope that the client will see it.

    It won't.

    Your only chance is to send some HTML (or whatever) code back to the client, that will in turn open another window.

Re: Open another IE browser window from CGI
by eric256 (Parson) on Jan 23, 2008 at 23:11 UTC

    Is the server in a seperate virtual machine? If so then the client virtual machine (or host pc) wont see what it opens.

    What you probably want is to make the link they click target _BLANK, then the browser will open a new window or tab, depending on its settings.


    ___________
    Eric Hodges
      The server and the client reside on the same vmware image. That makes me think there should be a way to open a new browser session.
      Do you believe in miracles? Yes!

        It still a rather odd way of trying to do it. Is there some reason you don't want to just have the link tell the browser to open a new window?


        ___________
        Eric Hodges
Re: Open another IE browser window from CGI
by digger (Friar) on Jan 24, 2008 at 15:40 UTC

    Since you are running this script under IIS, you only have the permissions that the IIS process has. CGI apps on IIS run using the IUSR_MachineName account, and have very limited rights. I believe that is why you aren't getting the results you expect.

    Try changing account used for Anonymous IIS access. Go to Start->Run and type inetmgr and hit enter. This will bring up the management console for IIS. Right click on the web site and select Properties, the go to the Directory Security tab. Change the account used for anonymous access to your user account, then try running your script.

    If this is for an intranet, and everyone will have a domain account, you could also enable Integrated Authentication.

    As everyone else has stated, this will not launch a browser on a separate client machine, but will work if, as you say, client and server are the same box.

    Tested on IIS5/WinXP/ActiveState Perl 5.8/IE8

      This certainly seemed promising, but no dice. I will look into other permission settings though just in case. I'm not much of an IIS whiz.
      Do you believe in miracles? Yes!

        First, you may have to give the user account the "Act as part of the operating system" right in the Local Security Settings snap-in. The Group Policy on the computer I am using right now doesn't allow me to test this, but the account I used has that right, and the error I received when using an account that didn't have that right seems to point at this issue.

        Second, you can get the error message from any Win32 calls pretty easily. Those messages are invaluable in tracking down solutions to problems like this. Often the message itself is worthless, but Googling it will give good answers. Here is the code I used to print the error message to the browser.

        use Win32::OLE; use Win32; use CGI; my $q = new CGI; print $q->header; my $browser = new Win32::OLE 'InternetExplorer.Application'; print Win32::FormatMessage( Win32::GetLastError() ); $browser->Navigate("http://www.apple.com", 0, 'xyzzy');

        If you run the above code using an account that doesn't have the "act as operating system" right, you should get the error "An attempt was made to reference a token that does not exist."

        Good Luck,
        digger

Re: Open another IE browser window from CGI
by roboticus (Chancellor) on Jan 25, 2008 at 12:02 UTC
    Olaf:

    You seem to be resisting the client/server arguments. One reason you might want to pay attention to them is reusability. If you ever decide to let others use your app, I doubt that you want their browser windows from showing up on your desktop (if you're hosting the app) or an unattended server (otherwise).

    Sure, you can get the behavior you want, but you're going to a good bit of trouble to avoid doing things in the conventional fashion.

    ...roboticus