in reply to Re: Perl Directive
in thread Perl Directive

In Windows NT/2000/XP, it actually works the same way as Unix, that is, by looking for magic numbers in the file.

There are actually 3 parts of the system that work together -- the NT kernel, the Windows Shell (aka explorer.exe), and the Command Prompt (aka cmd.exe).

When you click on a file in the Shell or type its name into the Prompt, the API function ShellExecute() is called, which looks up the file association in the registry and starts the right program to open that file.

The NT kernel does not care about the file's name. The Kernel is accessed by the API call CreateProcess(), which starts the program by looking for magic numbers (.exe format files start with MZ, .com format files have no magic numbers in them). (The kernel function is actually called NtCreateProcess, but programs should only call CreateProcess because Windows 9x had a different Kernel than the NT family has.)

You can see this in action by renaming helloworld.exe to helloworld. You will not be able to run it from the Command Prompt, but Perl can still run it with system("helloworld"). If you rename it to helloworld.com, it will still work even though the extension is wrong, because the Kernel does not use the file's name.

Replies are listed 'Best First'.
Re: Perl Directive
by jonadab (Parson) on Dec 14, 2004 at 15:04 UTC
    You can see this in action by renaming helloworld.exe to helloworld. You will not be able to run it from the Command Prompt, but Perl can still run it with system("helloworld"). If you rename it to helloworld.com, it will still work even though the extension is wrong, because the Kernel does not use the file's name.

    Interesting. However, if you rename it helloword.txt and double-click it, Explorer will try to open it in Notepad (by default). So Explorer is still using the old filename mechanism to determine whether it's executable or should open with another program such as Notepad or Perl. But once it determines that it's directly executable (exe, com, or whatever), it then uses another mechanism, different from what Win9x uses. This is actually not surprising, but it's interesting. It's also interesting that Perl's system bypasses the former mechanism, assumes the thing's executable, and jumps straight to the execution system call. One supposes this means that using system in a Perl script to call up a document will not launch the associated application. (One also supposes there's a Win32:: module that will allow you to do that, however, if it's what you want to do. I'm guessing, though.)

    It's also useful in certain edge cases. For example, you can rename an .sxw file to .zip, open it as a Compressed Folder, make a minor change to the XML (e.g., removing an unwanted paragraph, which the OOo UI in certain cases won't let you do, e.g., the only paragraph before or after a table), rename it back, doubleclick it, and it opens in OOo again. On *nix you'd just use the command-line zip/unzip to do this, but that's more cumbersome on Windows, so the ability to manipulate the associations is a nice compensation.

    Out of curiousity, what if you rename an EXE with a .bat extension and double-click it?


    "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68
      One supposes this means that using system in a Perl script to call up a document will not launch the associated application.

      No, it will. The behavior I observe is that it will first try to start the file as a program (CreateProcess), and if that fails to work, then try again with file associations (ShellExecute). You only see this when you have a exe file renamed to something like html. Perl will execute the program like an exe file, but clicking on it will start your web browser and display the binary data. However, if you have a html file with html actually in it, Perl will start the web browser on it too. This might create a security hole if a program is running system($filename) on untrusted files. So don't do that.

      Out of curiousity, what if you rename an EXE with a .bat extension and double-click it?

      .bat files are actually text files which are input to cmd.exe. So if you do this, you will start up a cmd.exe and try to feed the binary data into it, which will not work very well.

        .bat files are actually text files which are input to cmd.exe

        Yeah, I know what they *are*. (I cut my teeth on PC-DOS 3.3, so I've written a couple of batch files. I once joked about writing interactive fiction as a series of DOS3 batch files for an abuse-of-language contest. Of course, Zarf's threat to do one in PostScript was a bit more impressive...) But the registry assocation that Explorer uses is set up (at least in Win9x/Me, by default) exactly the same way as for EXE files:

        @="\"%1\" %*"

        That is, they're directly executable. And there's obviously no magic number in them— they don't even have to have the trailing ^Z (EOF) any more in Windows. So I was wondering how the API can determine that they're batch files, if not by looking at the extension _again_ after Explorer has handed off to CreateProcess.


        "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68