There are several Win32 registry functions provided with Perl for Win32. Check the win32mod document provided with Perl for Win32.
If you don't understand how the registry works, remember that a *key* is like a directory, and a *value* is like a file. There are several *top*level*keys*, and these are kind of like drives.
If you really don't get the registry, it's probably in your best
interest not to mess around with it.
Named pipes are a inter-process communcations mechanism, mainly
used with Microsoft operating systems (like Win32 platforms). A
named pipe can be addressed just like a file.
The name of a named pipe is a UNC (Universal Naming Convention)
name, and looks like "\\servername\pipe\pipename". "servername"
is the name of the server you're connecting to, or "." for the
current computer. "pipe" is a constant, and "pipename" is the
name of the pipe, such as "sql" for Microsoft SQL Server.
You can use open(), close(), read(), and print() on a named
pipe just like a file. However, you can't use sysread() or
syswrite() on one, because they aren't really files.
There's a program called Win32Pipe on the CPAN archive that
can be used to create a named pipe.
If you're starting from scratch, and you have a TCP/IP
infrastructure, consider using sockets rather than named pipes
for your IPC mechanism.
There are several examples of socket scripts that are distributed
with Perl for Win32. They're in the eg subdirectory of your
perl directory.
See question 8.5, by the way, about sockets servers.
Early versions of Perl for Win32 didn't allow you to read or
write to a socket as if it were a filehandle. The current
versions fully support this, and you shouldn't worry about it
too much. If the version that you're using doesn't work well,
get the latest build from ActiveWare (see question 1.4).
Contrary the ActiveWare FAQ (see question 3.7), you don't have
to specify USE_SOCKETS_AS_FILEHANDLES when building Perl for Win32
to get sockets to work like filehandles. It doesn't _hurt_, but
it's not necessary.
There's an example of a socket server, TCP-SERVER, in the eg
directory of your perl directory. In general, information on
socket programming for UNIX is applicable to Perl for Win32.
See especially the perlipc page of the documentation.
Note that using Perl for Win32 is *not* a good way to implement a
server, since you will only be able to service one client at once.
This is because a) Perl, the language, doesn't support threads, and
b) Perl for Win32 doesn't support the fork() function.
[Any new information here? -ESP]
There's an ftp.pl file in the lib directory of the perl subdirectory,
but it doesn't work, since it depends on alarm() and select() calls
that aren't available in Perl for Win32. Net::FTP, from the CPAN
archive, also appears not to work. [Anyone have better information?
-ESP]
Thus, you have several possibilities for doing FTP. You can fix the
ftp.pl script so that it works for Perl for Win32 [If you do, please
share it! -ESP]. You can get a copy of the FTP specification and hand-
code the module from scratch.
The quick-and-dirty solution is to compile a script for the FTP program
that comes with Windows NT [and Windows 95? -ESP]. You can then
execute the FTP program, passing this script as a parameter. See the
FTP program's help file for more details. Yes, I know, it's a real
ugly solution, but it works.
Aldo Calpini has developed a Perl for Win32 extension to do FTP and
HTTP using the WININET library. It's in alpha testing and is available
on his web page (see question 3.4).
Again, the CPAN solution would be to use libwww. However, to work under
Perl for Win32, libwww must be altered. See the information at this URL:
http://www.its.unimelb.edu.au:801/hma/pub/libwww/d009/0028.html
The HTTP protocol is pretty simple, and throw-away solutions can be
hand-coded pretty easily. See the HTTP protocol specification, and
the sockets examples, as mentioned above.
Aldo Calpini has developed a Perl for Win32 extension to do FTP and
HTTP using the WININET library. It's in alpha testing and is available
on his web page (see question 3.4).
There's an extension called Win32::NetAdmin distributed with Perl for
Win32. It has a pretty low-level interface, but it is very possible
to manage users and groups with this module.
Serial ports can be opened just like files in Perl for Win32. To
open COM1, just do this:
You should be able to read from and write to the file handle using
the standard I/O functions (read() and print()), but not the system
functions (sysread() and syswrite()). [Anyone done this? Does it
really work? Caveats? -ESP]
It has been noted (but not tested) that modems that use the Hayes
command set require a carriage return (\r) rather than a line feed
(\n) at the end of the command.
It does, in fact, work. However, people tend to use it incorrectly and
get bad results. To check for all the sub-directories in a directory,
try code like this:
It's a common mistake to leave out the $path from the -d check. If you
do this, perl thinks you're talking about files in the current directory.
Since the dirs don't -e in your current directory, they definitely don't
-d. Exceptions are "." and "..", which exist in every directory.
On Win32 platforms, there's a big difference between text files and
binary files. For text files, the "\r\n" characters are translated
into "\n" when read from disk, and the ^Z character is read as an
end-of-file marker. For binary files, no such translation is used.
Although this works great for text files, it really messes things up
when you're trying to read and write binary files. If the read or write
does not abort prematurely because a ^Z was found in the file, you will
almost definitely get incorrect bytes in the file due to \n -> \r\n
translation.
The problem is that Perl for Win32, and the C runtime library it uses,
open file in text mode by default. For each file handle you use
in Perl for binary data, you need to specify that the file handle is in
binary mode. Fortunately, there's a function, binmode, that does
just that. See the perlfunc documentation file for details.
This script copies one binary file to another. Note its use of binmode
to set the mode of the file handle.
Win32 platforms use the '\' character as a delimiter for paths in
a file name (C:\like\this). However, Perl uses the '\' character
as an escape code, to symbolize a special character like the
line feed character ("\n") or the tab character ("\t").
So, if you try and open a file like this:
you'll get an error. One solution is to replace each '\' with
a double-'\', to show that you really mean to use that character,
not an escape:
Another solution is to use non-interpolating single quote strings,
which lets Perl know not to use any special characters:
See the perlop documentation page for more information on the
differences between single quotes (') and double quotes (").
This is a weird error that occurs when your string terminator is on
the last line of your script. With a script like:
perl is looking for the word "END" on a line by itself, followed by
a line-feed character ("\n"). If the "END" is the last line of your
script, you have to remember to hit <Enter> after the word "END", so
that Perl can recognize it as the string terminator.
Most UNIX text editors will do this automatically. Most Windows text
editors won't. Thus the problem.
Note that this can also cause a problem with Perl formats, since these
are terminated with a single "." on a line by itself. However, it's
much more rare, since programmers often specify the format for output
at the top rather than at the bottom of a file.
8.2. How do I read from/write to a named pipe?
8.3. How do I write socket scripts?
8.4. What's all this I hear about not being able to use a socket as a filehandle?
8.5. How do I write a sockets server in Perl for Win32?
8.6. How do I send or receive files by FTP?
8.7. How do I send or receive files by HTTP?
8.8. How do I manage user accounts with Perl for Win32?
8.9. How do I read from and write to serial ports?
open( PORT, "+>COM1" ) or die "Can't open COM1: $!";
8.10. Why doesn't the -d operator work?
$path = shift;
$path = "." unless $path;
opendir( DIR, $path )
or die "Can't open $path: $!";
while ( $entry = readdir( DIR ) )
{
$type = ( -d "$path\\$entry" ) ? "dir" : "file"; # $path is crucial!
print "$type\t$entry\n";
}
closedir( DIR );
8.11. Reading from and writing to files mysteriously fails. What's wrong?
open( INFILE, "<$infile" );
open( OUTFILE, ">$outfile" );
binmode( INFILE ); binmode( OUTFILE ); # crucial for binary files!
while ( read( INFILE, $buffer, 1024 ) )
{
print OUTFILE $buffer;
}
close( INFILE ); close( OUTFILE );
8.12. When I try to open a file, I get a "bad argument" error. What gives?
open( MYFILE, "C:\temp\newfile.txt" );
open( MYFILE, "C:\\temp\\newfile.txt" );
open( MYFILE, 'C:\temp\newfile.txt' );
8.13. Why do I get an error using Perl's "here-doc" syntax (<<), that says "Can't find string terminator anywhere before EOF"?
print <<"END";
The snake is old, and his skin is cold.
END