I/O redirection

Perl can't run external commands.

Chances are, you've got something like:
$var = `$cmd`; # backticks
or
open(PIPE, "$cmd|");	# popen
@data = ;

You may also have noticed that the scripts run fine from the command-line, but not when invoked by the web server.

The problem here is that IIS4 runs processes without a console, and for some reason, this prevents Perl from redirecting I/O. You'll probably find that the external commands are running, but Perl is failing to receive output from them.

Under IIS2 and IIS3, the fix for this was quite simple: add the registry setting:

and set it to one. Naturally, since we've learned about this one, Microsoft have changed it. Now:

  1. It's called CreateCGIWithNewConsole instead;
  2. It's not in the registry anymore.

In their wisdom, Microsoft moved all the registry settings for IIS4 out of the registry into the metabase. Uh-huh. So how'd you change it? Well:

  1. Make sure that you've got Windows Scripting Host installed as part of Option Pack 4. You can verify this, because it should install the file C:\winnt\system32\cscript.exe.
  2. Fire up a command line, go to C:\winnt\system32\inetsrv\adminsamples.
  3. Run this:
    adsutil.vbs SET W3SVC/1/CreateCGIWithNewConsole 1
    
    It'll say that CScript isn't set up to handle this. That's ok.
  4. Click Ok.
  5. Click yes, you want to register.
  6. Run it again.
  7. Restart the web site.
(if, when you run this, it just says Boolean: TRUE, you're already configured for running things with Cscript, so this is ok too.)

You should now be able to run Perl scripts that do redirection, and they should work.

Note: if you've got more than one instance of W3SVC (because you're hosting multiple sites), then replace the W3SVC/1 with W3SVC/n, where n is the instance number you want to change. You'll have to make the change for all the instance you're running Perl on.

I can't start a background command from perl

This is where your script contains something like:
system('start \path\to\cmd.exe');
(Remember, watch those backslashes).

It seems that this returns control to the script immediately from the command-line, but hangs when invoked by a browser.

The problem is that you've got filehandles open which aren't doing anything, but they're still causing problems. Close the ones you don't need:

close(STDERR); # Assuming you don't really need STDERR for the rest of the script.
open(FHANDLE,qq{start "Window_Title" "command.exe"|});
close(FHANDLE);

It doesn't work when Perl is embedded in a C program

This is where the web server calls a C executable, and that program invokes PerlIS using the perl_parse()/perl_run() APIs.

The problem is that PerlIS is linked statically, and has its own instance of STDOUT, so doesn't see redirections done in/for your C program. Change the Perl's STDOUT structure to point to point to the same stream as your C program, so it sees the pipe set up by the Web server.

My script isn't producing any output.

There are several likely reasons for this:
  1. Check that you've got working IO redirection.
  2. Your script is barfing before the headers are getting flushed.
In the second case, first of all, turn off buffering on output with the following:
$| = 1;
(this works on the currently-selected output filehandle, so it'll only work if you haven't select()ed any other filehandle)

Personally, I also find that it's best to redirect stderr to a file in C:\temp, right at the start of the script. At least, then when errors occur, I've got a reasonable chance of seeing any error messages. If anyone knows how to see stderr output with IIS4 normally, I'd like to know about it.

I've also had at least one person who's reported that their scripts don't produce output when the .pl script itself is on a mapped (network) drive. Well, this is a new one on me, and due to time constraints, haven't been able to verify it. But you might like to try moving your scripts to a local drive, to see if this is part of the problem.

The registry settings don't work anymore.

Well, no, they don't. ScriptMap settings are now done in property sheets, and CreateProcessWithNewConsole is now in the metabase.
Steve Kilbane. Whitecrow home.