home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 March / PCWorld_2003-03_cd.bin / Software / Topware / activeperl / Installer.bat < prev   
DOS Batch File  |  2002-12-01  |  13KB  |  428 lines

  1. @rem = '--*-Perl-*--
  2. @echo off
  3. if "%OS%" == "Windows_NT" goto WinNT
  4. ActivePerl\Perl\bin\perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
  5. goto endofperl
  6. :WinNT
  7. ActivePerl\Perl\bin\perl -x -S %0 %*
  8. if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
  9. if %errorlevel% == 9009 echo You do not have Perl in your PATH.
  10. if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
  11. goto endofperl
  12. @rem ';
  13. #!ActivePerl/Perl/bin/perl -w
  14. #line 15
  15. #
  16. # ActivePerl ZIP installer
  17. #
  18. # Copyright: ActiveState Tool Corp., 2000
  19. #
  20. # This program completes a simple installation of ActivePerl
  21. #
  22. # The intent of this program is to provide a "fail-safe" way of installing 
  23. # a fully-functional version of ActivePerl.  If there is a failure, this 
  24. # script should explain exactly what went wrong, and how to fix it.
  25. # If not, submit that as a bug.
  26. #
  27. # What is does:
  28. #     o Relocates Perl
  29. #     o Creates MSWin32 Shortcuts to the HTML documentation
  30. #     o Configures PPM
  31. #     o Configures lib/Config.pm for use with a development system
  32. #     o Creates ActivePerl registry entries
  33. #     o Updates the PATH environment variable
  34. #
  35. # Todo:
  36. #     o uninstall (pretty simple)
  37. #     o configure Perl for use with a Web Server
  38. #     o set up file associations on Win32
  39.  
  40. # The path we will be replacing
  41. my $replace = q[D:\p4\Apps\Gecko\MSI\data\ActivePerl\Perl];
  42.  
  43. # The ActivePerl version we are installing
  44. my $APVersion = Win32::BuildNumber();
  45.  
  46. # It should be safe to comment the following out on non-MSWin32 platforms
  47. use Win32;
  48. use Win32API::Registry (':ALL');
  49. use Win32::Shortcut;
  50.  
  51. use Cwd;
  52. use strict;
  53. no strict "subs";    # not my fault
  54.  
  55. $|=1; #disable buffering
  56.  
  57. (-d 'ActivePerl/Perl/bin' && -d 'ActivePerl/Perl/lib' && -d 'ActivePerl/Perl/site') 
  58.     || die "Error: you must run this script from the directory in which you unzipped ActivePerl into.\n";
  59.  
  60. my $temp = $ENV{'TEMP'} 
  61.     || die "You must set the 'TEMP' environment variable.\n";
  62.  
  63. my $cwd = cwd;
  64. $cwd =~ s#/#\\#g;
  65.  
  66. if (@ARGV && $ARGV[0] eq '--remove') {
  67.     remove_html_shortcuts();
  68.     print <<EOM;
  69.  
  70. ActivePerl uninstalled...you may now delete this directory and 
  71. its subdirectories.
  72.  
  73. EOM
  74.     exit;
  75. }
  76.  
  77. print <<EOM;
  78.     Welcome to ActivePerl.
  79.  
  80.     This installer can install ActivePerl in any location of your choice.
  81.     You do not need Administrator privileges.  However, please make sure 
  82.     that you have write access to this location.
  83.  
  84. EOM
  85.  
  86. my $whereto;
  87. do {
  88.     print 'Enter top level directory for install [c:\Perl]: ';
  89.     chomp($whereto=<>);
  90.     $whereto ||='c:\Perl';
  91.     
  92.     unless ($whereto =~/(^.:\\)|(\\\\)/) {
  93.     print "Error: You must include the drive letter or the full UNC PATH\n\n";
  94.     $whereto = undef;
  95.     }    
  96. } until defined $whereto;
  97.  
  98. if (-d $whereto) {
  99.     print <<EOM;
  100.     
  101. $whereto appears to already exist.
  102.  
  103.     WARNING: Install may fail if any existing files cannot be
  104.     overwritten.
  105. EOM
  106. }
  107.  
  108. if ($whereto =~ /[\s;,!|<>~\@\%\&\$\*\?\+]/) {
  109.     print <<EOM;
  110.  
  111.     Looks like you are trying to install Perl into a path that contains
  112.     spaces or other special characters.  Though the latest Windows
  113.     operating systems claim to support filenames with such special
  114.     characters, many existing utilities will have trouble with such
  115.     path names.  Chances are that you will find this is simply too
  116.     much of a bad idea to be worth it.
  117.  
  118. EOM
  119.     }
  120.  
  121. print <<EOM;
  122.  
  123.     The typical ActivePerl software installation requires 35 megabytes.
  124.     Please make sure enough free space is available before continuing.
  125.  
  126.     ActivePerl $APVersion will be installed into '$whereto'
  127. EOM
  128. print 'Proceed? [y] ';
  129. <> =~ /^\s*[y|\n]$/i or exit 1;
  130.  
  131. # Hint to MSWin32 users that devsys environment should be set before installing
  132. #
  133. if ((!defined($ENV{'INCLUDE'}) || !defined($ENV{'LIB'})) && $^O eq 'MSWin32') {
  134.     print <<EOM;
  135.  
  136.     If you have a development environment (e.g. Visual Studio) that you
  137.     wish to use with Perl, you should ensure that your environment (e.g.
  138.     %LIB% and %INCLUDE%) is set before installing, for example, by running 
  139.     vcvars32.bat first.
  140. EOM
  141.  
  142.     print 'Proceed? [y] ';
  143.     <> =~ /^\s*[y|\n]$/i or exit 1;
  144. }
  145.  
  146.     print "\nCreate shortcuts to the HTML documentation? [y] ";
  147.     (my $create_html_shortcuts = <>) =~ /^\s*[y|\n]$/i;
  148.  
  149.     print "\nAdd the Perl/bin directory to the PATH? [y] ";
  150.     (my $add_path = <>) =~ /^\s*[y|\n]$/i;
  151.  
  152. #alright, copy the files
  153. print <<EOM;
  154.  
  155.     Copying files...
  156. EOM
  157.  
  158. # disables prompting in newer versions of cmd.exe if there are
  159. # older files of the same name
  160. $ENV{COPYCMD} = "/y";
  161.  
  162. my $cmd = "xcopy /q /r /i /e ActivePerl\\Perl\\* \"$whereto\" ";
  163. system($cmd) && die "$!\n";
  164.  
  165. print "    Finished copying files...\n";
  166.  
  167. my $perl = "$whereto/bin/perl.exe";
  168.  
  169. system($perl, "$whereto/bin/reloc_perl", '-a', '-i', '-v', '-t', $whereto, $replace) == 0
  170.     or die "Couldn't run reloc_perl: $!";
  171.  
  172. if ($^O eq 'MSWin32') {
  173.     create_html_shortcuts() if $create_html_shortcuts;
  174.     create_registry_entries();
  175.     update_path() if $add_path;
  176.     configure_configpm();
  177. }
  178. configure_ppm();
  179. build_html();
  180.  
  181. print <<EOM;
  182.  
  183. This simplified installation program currently does *not*:
  184.  
  185.     o set up MSWin32 file associations
  186.     o configure Perl for use with a Web Server
  187.  
  188. Refer to your Operating System and/or Web Server documentation for
  189. details on how to to perform these modifications.
  190.  
  191. Thank you for installing ActivePerl!
  192.  
  193. EOM
  194.  
  195. if (Win32::IsWin95) {
  196.     sleep 5; #STDIN is dead
  197. }
  198. else {
  199.     print "Press return to exit.\n";
  200.     <>;
  201. }
  202.  
  203. exit;
  204.  
  205. sub configure_configpm
  206. {
  207.     my ($LIB, $INC);
  208.     print "\nConfiguring $whereto/lib/Config.pm for use in $whereto...\n\n";
  209.  
  210.     system($perl, "$whereto/bin/config.pl", $whereto) == 0
  211.         or die "Couldn't config $whereto/lib/config.pm: $!";
  212.  
  213.     # Create values for libpth and incpath in Config.pm
  214.     if (defined $ENV{'LIB'}) {
  215.         $LIB = '"' . join(q(" "), split(/;/, $ENV{'LIB'})) . '" ';
  216.     } else {
  217.         $LIB = '/lib /usr/lib /usr/local/lib '; 
  218.     }
  219.     $LIB .= qq("$whereto\\lib\\CORE");
  220.  
  221.     if (defined $ENV{'INCLUDE'}) {
  222.         $INC = '"' . join(q(" "), split(/;/, $ENV{'INCLUDE'})) . '" ';
  223.     } else {
  224.         $INC = '/usr/include /usr/local/include '; 
  225.     }
  226.     $INC .= qq("$whereto\\lib\\CORE");
  227.  
  228.     my @Config;
  229.     open (CONFIG, "<$whereto/lib/Config.pm") 
  230.         or die "Can't open $whereto/lib/Config.pm for reading: $!";
  231.     @Config = <CONFIG>;
  232.     close(CONFIG);
  233.     foreach(@Config) {
  234.         s@^libpth=.*$@libpth='$LIB'@g;
  235.         s@^incpath=.*$@incpath='$INC'@g;
  236.     }
  237.     unlink("$whereto/lib/Config.pm.old") if -f "$whereto/lib/Config.pm.old";
  238.     rename("$whereto/lib/Config.pm", "$whereto/lib/Config.pm.old") 
  239.         or die "Can't rename $whereto/lib/Config.pm to $whereto/lib/Config.pm.old: $!";
  240.  
  241.     open (CONFIG, ">$whereto/lib/Config.pm") 
  242.         or die "Can't open $whereto/lib/Config.pm for writing: $!";
  243.     print CONFIG @Config;
  244.     close(CONFIG);
  245. }
  246.  
  247.  
  248. sub configure_ppm
  249. {
  250.     print "\nConfiguring PPM for use in $whereto...\n\n";
  251.     
  252.     system($perl, "$whereto/bin/configPPM.pl", "$whereto/site/lib/ppm.xml",
  253.        $whereto, "$whereto/site/lib/ppm.xml~", $cwd) == 0
  254.         or die "Couldn't config $whereto/site/lib/ppm.xml: $!";
  255.  
  256.     system($perl, "$whereto/bin/ppm.bat", 'set', 'build', $temp) == 0
  257.         or die "Couldn't set ppm BUILDDIR: $!";
  258.  
  259.     print <<EOM;
  260.  
  261. If you are behind a firewall, you may need to set the following
  262. environment variables so that PPM will operate properly:
  263.  
  264.     set HTTP_proxy=address:port         [e.g. 192.0.0.1:8080]
  265.     set HTTP_proxy_user=username
  266.     set HTTP_proxy_pass=password
  267.     set HTTP_proxy_agent=agent          [e.g. "Mozilla/5.0"]
  268.  
  269. EOM
  270. }
  271.  
  272. sub build_html {
  273.     print "\nBuilding HTML documentation, please wait...\n\n";
  274.  
  275.     # Can't do this in-process because the by now modified Config.pm and
  276.     # %Config can't be reloaded easily
  277.     system($perl, "-MActivePerl::DocTools", "-e", "UpdateHTML('wait')") == 0
  278.     or die "Failed to build HTML documentation\n";
  279. }
  280.  
  281. sub create_html_shortcuts
  282. {
  283.     my ($key, $location);
  284.     $key = 'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\\'; 
  285.     $key .= Win32::IsWin95() ? 'Programs' : 'Common Programs';
  286.  
  287.     my $try = Get(HKEY_LOCAL_MACHINE, $key, \$location);
  288.     
  289.     unless ($try) {
  290.         $key = 'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Programs'; 
  291.         $location = undef;
  292.         $try = Get(HKEY_CURRENT_USER, $key, \$location);
  293.     }
  294.     
  295.     unless ($try) {
  296.         warn 'Read of shortcut dir failed: '. Win32::FormatMessage(Win32::GetLastError()) ."\n";
  297.         return undef;
  298.     }
  299.  
  300.     $location .= '/ActiveState ActivePerl';
  301.     mkdir($location, 0777) unless -d $location;
  302.  
  303.     my $link = new Win32::Shortcut();
  304.     # Stupid NT can't handle / path separator in the shortcut
  305.     ($link->{'Path'} = "$whereto\\html\\index.html") =~ s@/@\\@g;
  306.     ($link->{'WorkingDirectory'} = "$whereto\\html") =~ s@/@\\@g;
  307.     $link->{'Description'} = "ActivePerl Documentation in HTML format.";
  308.     $link->{'ShowCmd'} = SW_SHOWNORMAL;
  309.     $link->Save("$location\\Documentation.lnk");
  310. }
  311.  
  312. sub create_registry_entries
  313. {
  314.     # Attempt to set some registry entries.
  315.     (my $whereto = $whereto) =~ s@/@\\@g;
  316.  
  317.     Set(HKEY_LOCAL_MACHINE, 'SOFTWARE\ActiveState\ActivePerl\CurrentVersion', $APVersion, REG_SZ)
  318.     || warn "Couldn't make registry entry: $!\n";    
  319.  
  320.     Set(HKEY_LOCAL_MACHINE, "SOFTWARE\\ActiveState\\ActivePerl\\$APVersion\\", $whereto, REG_SZ)
  321.     || warn "Couldn't make registry entry: $!\n";    
  322.  
  323.     Set(HKEY_LOCAL_MACHINE, 'Software\Perl\\', $whereto, REG_SZ)
  324.     || warn "Couldn't make registry entry: $!\n";    
  325.  
  326.     Set(HKEY_LOCAL_MACHINE, 'Software\Perl\BinDir', $perl, REG_SZ)
  327.     || warn "Couldn't make registry entry: $!\n";    
  328. }
  329.  
  330. sub update_path
  331. {
  332.     if (Win32::IsWin95()) {
  333.     system($perl, "$whereto/bin/Windows9XPATH.pl") &&
  334.         warn "Couldn't update the PATH"; 
  335.     return;
  336.     }
  337.  
  338.     my $path;
  339.     (my $whereto = $whereto) =~ s@/@\\@g;
  340.     Get(HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Control\Session Manager\Environment\Path', \$path)
  341.     || warn "Unable to read PATH from registry: $!\n";
  342.     
  343.     $path = "$whereto\\bin;$path" unless $path =~ m#\Q$whereto\bin\E#; #quote the path to avoid Unicode errors
  344.  
  345.     Set(HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Control\Session Manager\Environment\Path', $path, REG_EXPAND_SZ)
  346.     || warn "Unable to update PATH in registry: $!\n";
  347. }
  348.  
  349. sub remove_html_shortcuts
  350. {
  351.     my ($key, $location);
  352.     $key = 'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\\'; 
  353.     $key .= Win32::IsWin95() ? 'Programs' : 'Common Programs';
  354.  
  355.     Get(HKEY_LOCAL_MACHINE, $key, \$location)
  356.     || warn 'Read of shortcut dir failed: '. Win32::FormatMessage(Win32::GetLastError()) ."\n";
  357.  
  358.     $location .= '/ActiveState ActivePerl';
  359.     unlink("$location/Online Documentation.lnk");
  360.     unlink($location);
  361. }
  362.  
  363. sub Get
  364. {
  365.     my ($root, $key, $data) = @_;
  366.  
  367.     if (defined $$data) {warn "\$data set in Get!"}
  368.     my $hkey;
  369.     my $type;
  370.     $key =~ s#(.*)\\(.*)$#$1#;
  371.     my $value = $2;
  372.  
  373.     Win32API::Registry::RegOpenKeyEx($root, $key, 0, KEY_READ, $hkey)
  374.     || return undef;
  375.  
  376.     Win32API::Registry::RegQueryValueEx( $hkey, $value, [], $type, $$data, [])
  377.     || return undef;
  378.  
  379.     return 1;
  380. }
  381.  
  382. sub Set
  383. {
  384.     my ($root, $key, $data, $type) = @_;
  385.     my $hkey;
  386.     $key =~ s#(.*)\\(.*)$#$1#;
  387.     my $value = $2;
  388.  
  389.     Win32API::Registry::RegCreateKeyEx($root, $key, 0, '', REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, [], $hkey, [])
  390.     || return undef;
  391.  
  392.     if (defined $data) {
  393.     my $olddata;
  394.  
  395.     if (! $type and Win32API::Registry::RegQueryValueEx($hkey, $value, [], $type, $olddata)) {
  396.         $type = REG_SZ; 
  397.         warn "assuming type REG_SZ\n";
  398.     }
  399.     Win32API::Registry::RegSetValueEx($hkey, $value, 0, $type, $data, 0)
  400.         || return undef;
  401.     }
  402.     else {
  403.     Win32API::Registry::RegDeleteValue($hkey, $value)
  404.         || return undef;
  405.     }
  406.     Win32API::Registry::RegCloseKey($hkey)
  407.     || return undef;
  408.  
  409.     return 1;
  410. }
  411.  
  412. sub can_write {
  413.     my $d = shift;
  414.     my $ok = 0;
  415.     my $file = $d;
  416.     if (-d $d) {
  417.     $file = "$d/foozle.$$";
  418.     }
  419.     $ok = open(TEST, ">", $file);
  420.     close TEST;
  421.     unlink($file) if $ok;
  422.     return $ok;
  423. }
  424.  
  425. __END__
  426. :endofperl
  427.