Beefy Boxes and Bandwidth Generously Provided by pair Networks chromatic writing perl on a camel
XP is just a number

"Porting" scripts to Win32

by b10m (Vicar)
on Feb 20, 2004 at 13:32 UTC ( #330532=perlquestion: print w/ replies, xml ) Need Help??
b10m has asked for the wisdom of the Perl Monks concerning the following question:

A couple of days ago, I tried to run one of my scripts on a win32 (win98 in this case) machine using ActiveState Perl. After using ppm to grab some modules, it did work (duh), but I noticed some errors, for I "hard-coded" some paths into the script, like $HOME and /tmp/.

Now I could probably figure out the OS of the user (right?) and specify a different path for the files, but I have no knowledge of the directory structure of a win32 system. Where do Windows people usually store config files (and I refuse to use the infamous registry! ;), like the good old ~/.[app-name]/ on *NIX systems? And what is the "default" temp directory on such systems?

Are there other things I should pay attention to in this process of "porting" the script to win32?


All code is usually tested, but rarely trusted.

Comment on "Porting" scripts to Win32
Re: "Porting" scripts to Win32
by pelagic (Curate) on Feb 20, 2004 at 13:58 UTC
    For the basic things like concateneting path parts a.s.o. consult File::Spec.

    I can resist anything but temptation.
Re: "Porting" scripts to Win32
by punkish (Priest) on Feb 20, 2004 at 14:04 UTC
    I routinely use perl on a Win XP box at work (at home I run Mac OS X) so I can offer a few pointers.

    Unfortunately, just like the different versions/vendors/flavors/variants of Unix, Windows directory layout also varies from OS version to version. But, it is mostly quite predictable. And most system directories can be addressed by variables. I have never used Windows system variables in perl scripts, but it would be interesting to see if they work... they are usually surrounded by % signs such as %TEMP% or %SYSTEM% etc.

    The ~/.app-name is actually followed, but it is not OS mandated but application specific. Of course, directories or files starting with a . are not invisible.

    On Win XP there is a convolutedly named "Documents and Settings" folder on the C root where such things get stored usually, and under that folder is also an Application Data (I think that is what it is called) folder where app specific detritus can be stored such as mozilla prefs, etc.

    You don't really have to hack the registry as it is mostly for system specific things such as asscoiating all .pl or .plx extension files with the perl binary so you can actually run those files by double-clicking on them.

    Most config files get stored under the Winnt directory and they usually end with the .ini suffix.

    Hope some of this helps. But you definitely will have to explore the various versions of Windows to figure out if your scripts are going to be affected. Alternatively you could run a config script that asks the user a few questions and makes its settings, but most users are not likely to know what goes where. Or, you could just make up your own tmp directory, store stuff there, and blow it away when the script is done (or not, if you want the settings to persist).

    Since I have never needed to mess with those kind of things, I have found that my scripts run mostly without any changes and without any problems (except for changing the shebang line, of course when moving from Mac OS X to Win and back. If I have to store anything, I usually create a directory under my scripts directory where I can write stuff.

      I can't help but reply to some of this.

      %TEMP% and %SYSTEMROOT% will work only from the shell. To access these in perl, use $ENV{TEMP} and $ENV{SYSTEMROOT}.

      Yes, the "Appliation Data" directory under "Documentions and Settings" is the right thing to use for DATA if you're on Win2k or XP, but it doesn't exist on other versions of Windows. To play it safe, use the Win32::GetFolderPath() function, which will always return the proper path regardless of which OS you're on, what changes the network admin has made, or what the user's preferences are. (Try CSIDL_APPDATA or CSIDL_PERSONAL)

      The registry is NOT just for system-specific things. Almost Every application on your computer uses the registry to store its configuration info. It was designed to alleviate the problems of having thousands of configuration files scattered all over the machine, each with a different syntax.

      To summarize, DATA (like large files) should go in whatever path Win32::GetFolderPath() gives you, and CONFIG (like simple settings) should go in the registry.

      Most appliations do NOT use INI files under Winnt. This was common in the Windows 3.1 days, but not any more. The files there are only for legacy compatibility. (And "Winnt" doesn't even exist in the newer OSes like XP)


        I would just like to add that while you are correct that the registry "was designed to alleviate the problems of having thousands of configuration files scattered all over the machine, each with a different syntax", Microsoft has now realized that it's design did not accomplish that well. They have decided that application specific configuration files are a better approach. They recommend them for all .NET applications and it is how ASP.NET applications are configured (for features such as Authentication, Session State, Application Variables, etc). The config files are in an XML format and are easily parsed using classes in the "System.Configuration" namespace.

        In response to the OP: Most open source applications I have installed on my W2K box are ports of linux apps. They store their information in config files under "\Documents and Settings\username\appname\" or "\Documents and Settings\username\Application Data\appname\". Most people familiar with the linux apps ported to windows will expect one of those two methods.

Re: "Porting" scripts to Win32
by thunders (Priest) on Feb 20, 2004 at 14:04 UTC
    Typically \WINNT\Temp is availible for Windows NT/2000/XP. I think Windows 95/98/ME have a \Windows\Temp folder. To figure out exactly which version of windows you are on, you'll need to check the registry or use Win32::GetOSVersion()
      Typically \WINNT\Temp is availible for Windows NT/2000/XP.
      No. Windows XP uses c:\WINDOWS for the Windows directory by default, not c:\WINNT. And you probably don't want to hardcode the default, so rely on %WINDIR%.
Re: "Porting" scripts to Win32
by meetraz (Hermit) on Feb 20, 2004 at 14:05 UTC
    To determine the user's OS, use the $^O variable.

    You can still use $ENV{TEMP} for the temp directory on windows.

    If you want to avoid the registry, I would recommend using XML or INI files to store settings. You can use the Win32::GetFolderPath() function to obtain the proper locations to store the files.

    There are a number of traditional perl constructs that work poorly or not at all on Windows, especially the ancient Windows 98. The first things that come to mind are signals, forking, alarm, using binmode(), missing built-in commands and compilers, no make, different shell conventions, and more.

    You should probably read "perldoc perlwin32".

Re: "Porting" scripts to Win32
by inman (Curate) on Feb 20, 2004 at 14:06 UTC
    On my Windows 2000 PC (and XP), the environment variable HOMEDRIVE combined with HOMEPATH appear to be set to my 'c:\Documents and Settings\userid' folder. This folder appears to contain any number of directories and files that have been created by apps ported from UNIX.
Re: "Porting" scripts to Win32
by Corion (Pope) on Feb 20, 2004 at 14:07 UTC

    I wonder why nobody brought this up yet, but File::Temp is the thing to use for your temporary files and directories.

Re: "Porting" scripts to Win32
by Biker (Priest) on Feb 20, 2004 at 14:09 UTC

    "And what is the "default" temp directory on such systems?"

    That's a default so unsecure that you should never trust it to be something specific.

    Look for a TEMP environment variable. If you find one (in most cases you do) then take the liberty to write your temp files in the directory indicated in TEMP.

    Everything went worng, just as foreseen.
Re: "Porting" scripts to Win32
by elwarren (Curate) on Feb 20, 2004 at 14:20 UTC
    The closest thing you had to a HOME folder back in 98 was the "My Documents" folder, which I believe was still stored inside the windows folder, usually (but not always) "C:\Windows\My Documents" Everyone was still doing it their own different ways in 98, things got increasingly better (er, more organized anyway) with NT/2000/XP.

    The safest/cleanest way is to just create a directory for your app and then store your config and your own temp directory beneath it. This way you don't have to parse spaces in pathnames and it's transportable across most platforms.
Re: "Porting" scripts to Win32
by Abigail-II (Bishop) on Feb 20, 2004 at 14:23 UTC
    I once write a large, complicated shell/awk/isql program, of about 2500 lines. I developed it on Solaris, but it had to run under Windows NT, and HP-UX as well. We had a Unix toolkit running on Windows, and the entire scripted needed a single change to run under Windows: the location of the tmp directory. Getting it to run under HP-UX required more changes, most of them due to different switches of tools like grep.

    So, my limited experience says that if you have a good Unix toolkit, porting shouldn't be much of a problem. Read perlport, and remember that the main difference between Perl under Unix and Perl under Windows is that the latter doesn't support everything the former does. Although you might increase your changes if you compile Perl on Windows using Unix emulation libraries.


Re: "Porting" scripts to Win32
by mattr (Curate) on Feb 20, 2004 at 15:59 UTC
    My Win98 Second Edition (Japanese OS) laptop:
    C:\Windows\TEMP - has lots of stuff in it, dates to 2000
    C:\Temp - made it in 2003 and this is very popular
    /tmp - in Cygwin, actually /cygdrive/c/cygwin/tmp
    base/conf - a folder I usually make off the base of my projects.

    Meanwhile, at the far end of the Sagittarius Arm..
    Hey Luke! How the heck do we compile Wx on cygwin??? It's much harder than those moisture evaporators..

    Doing this on a slow 64mb machine which runs out of memory often may be part of it. But when I compile wxwindows on cygwin I get a dll, but when I try to make Wx it fails. And the ppm says it wants a later Windows version which has Unicode.. Anybody every do this right on cygwin in Win98?

    <i?Update: I have though been using the win32 code, but Wx warns about not finding the unix libs..

Re: "Porting" scripts to Win32
by Anonymous Monk on Feb 20, 2004 at 15:59 UTC

    In general, windows apps tend to keep all their files in one place. Either in the applications subdirectory, or in subdirectories underneath it. It's a different philosophy from the unix "spread yourself all over the disk" approach which I never quite understood.

      <MontyPython>Fud Fud Fud Fud Fud Fud Fud Fud...</MontyPython>

      You have "files" in %WINDIR%, %SYSTEMDIR%, the registry, the application files, the menu structure, the quicklaunch folder and other places in Windows.

      • It does not matter upon which OS your application is installed on, but how your application is designed. For example, you could just have one configuration variable in %OS_OF_CHOICE_CONFIG_AREA%, and have that point to your application directory. Now you just have to get your executable able to be accessed through some sort of a user interface ($PATH, %PATH%, menu structure, etc).

      • In addition, Windows is based on the model of including all functionality you need for your application in one executable (shared libs / dlls as an exception), whereas Unix is build on the reusable tools model. There are more interdependancies, so you either need to have a fixed location for common tools, or you need to have some infrastructure to be able to find the tools you need. The re-use model requires that you be able to find the tools.

      Of course, I am probably just falling for a troll :)


Re: "Porting" scripts to Win32
by Koosemose (Pilgrim) on Feb 21, 2004 at 01:24 UTC

    As far as determining OS goes, you will, of course have to use $^O, as meetraz mentions, but since there are signifigant differences between flavor's of Windows, as to where files of various sorts are stored, you will also need to Use Win32::GetOSName() or Win32::GetOSVersion(), as suggested by perldoc perlvar, under $^O, to determine your flavor of Windows.

Re: "Porting" scripts to Win32
by fstat(pipe) (Scribe) on Feb 24, 2004 at 00:37 UTC
    Probably a little off-topic but, why the registry prejudice? Until recently I was a solid UNIX coder and admin. I have been dragged into creating a perl application for Win32 and find it very handy (and easy) to store static application variables in the registry using the Win32::TieRegistry module.
    Another nice thing is that if you have some standard reg values you can export them to a .reg file (use REGEDIT4 format); when you want them installed on another system you can manualy double click the file and the entries will be added. I find this solution works better for me than the .ini file.
      "why the registry prejudice?"

      I have a few things that I don't like about the approach, althought they are mostly out of a user's perspecitve.

      2. Unreadable
      3. Multi platform problem

      1. With text files, it's easy to comment a certain value out. This way, you will keep the old value, while you can try a new value. Besides the altering, I like some explanation in configuration files anyway: "This value is used for yadayadayada". With the registry approach, you can of course alter values too, but either you should have a good memory, or write every old value down somewhere, in case you ever want to return to the old value.

      2. Maybe it's just me, but I find it terribly hard to find where exactly an app. stores its configuration, due to the massive ammount of data that is all located in one place. It can take quite a bit of time to finally locate the "folder" (or whatever it is called) with the configuration options.

      3. As I stated, I already have a working app. targeted for *NIX systems, which don't have a registry. Hacking the registry support in, would make no sense for the *NIX systems and only add problems (if I decide to add one option to the config file, I would have to make sure the registry would get that change too, which I am likely to forget, for I don't use a win32 system myself).


      All code is usually tested, but rarely trusted.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://330532]
Approved by bassplayer
Front-paged by broquaint
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (11)
As of 2014-04-17 05:26 GMT
Find Nodes?
    Voting Booth?

    April first is:

    Results (439 votes), past polls