batee.com

 

The Stories of My Life Gallery Projects Friends and Family Web Log Contact

 

Perl Code Samples for use in Application Installation

By Bryan A. Thompson

Created 2/2003

Last Updated 4/27/2003

 

Note:  Parts of this page were contributed by Ryan Lantzer.

 

Typical Install Script written in Perl

use Win32::Registry;

# Note - for reference, this is line 3

# Do not edit anything above this line-----------------------------------------------------------------------

# Change the reference to "ftp" in line 15 to the directory where your product is to be stored on the local drive. This must be a subdirectory of the C:\Source Files directory for file permissions to be correct.

# Change the reference to "wsle_450" in line 16 to the name of your MSI file. Do not enter the file extension (the ".msi" part of this filename).

$msidir="ftp";

$msiname="wsle_450";

# Do not change anything below this line--------------------------------------------------------------------

# Note: This part determines the current directory (where update.pl is located)

# This allows the script and MSI to be moved from location to location without editing the script

$cwd=$0;

@cwd=split(/\\/,$cwd,-1);

$#cwd=$#cwd-1;

$cwd=join("\\",@cwd);

# Note: This changes the current directory to the C: drive.

chdir ("c:\\");

# Note: This part adds the following information to the install log.

print"******************************\n";

print"Installing Custom Application $msiname.msi \n";

print"******************************\n";

print "\n";

print " ********************\n";

print " Copying Source Files\n";

print " ********************\n";

print "\n";

# Note - this part deletes any old MSI that may reside in this location. Then it creates or recreates the directory on the local drive where the MSI file is kept so that the app can self-repair even when detached from the network. Then the MSI file is copied to the new location.

$sourcefilesdir="C:\\Source Files\\$msidir";

system("rmdir \"$sourcefilesdir\" /s /q");

system("mkdir \"$sourcefilesdir\"");

system("xcopy \"$cwd\\*.msi\" \"$sourcefilesdir\"");

# Note - this part adds more info to the install log files

print " **************\n";

print " Installing MSI\n";

print " **************\n";

# This part install the MSI file from the C:\Source Files\<whatever> directory

$sourcefilesmsi="$sourcefilesdir\\$msiname.msi";

$logfile='C:\winnt\system32\umrinst\applogs\\'."$msiname.txt";

$msiproperties='ALLUSERS="1" COMPANYNAME="UMR" USERNAME="UMR" ROOTDRIVE="C:\"';

system("msiexec /qn /i \"$sourcefilesmsi\" /l* \"$logfile\" $msiproperties");

# Note - This part creates the product key required for AFS/ADS login scripts to run

$productlistkey="SOFTWARE\\UMR\\INSTALL\\Product_List";

$productkey="msi_$msiname";

$HKEY_LOCAL_MACHINE->Open("$productlistkey",$hkey);

if ($hkey)

{

$hkey->Create($productkey,$skey);

$skey->Close();

$hkey->Close();

}

 

Additional Code Samples

 

Adding Files

The following code can be used to copy all files in a directory to a local drive:

system("xcopy /Q \"$cwd\\*.*\" \"C:\\Source Files\\mcafee451\"");

The above script will not work if the directory is an AFS volume containing an Oldfiles directory. If this situation arises, copy the files to a subdirectory, then run the above script.  An alternative is using the copy command instead of the xcopy command.

 

Adding Shortcuts

Since shortcuts are files, this is similar to adding a file. Create the shortcut file on a test machine. Then follow the procedure above to copy the file through the install script.

 

Adding Directories

system ('mkdir C:\temp');

 

Deleting Files and Shortcuts

This code will check to see if the file specified in the $file_to_delete variable exists, and if it does, the script will delete that file. Since shortcuts are files (they have a hidden .lnk file extension), this will work for shortcuts, too:

$file_to_delete='C:\Documents and Settings\all users\desktop\Acrobat Reader 4.0.lnk';

if (-f $file_to_delete)

{

system("del \"$file_to_delete\"");

}

 

Deleting Directories

This code will delete the directory C:\UMRINST and any subdirectories, and will suppress any system prompts:

system ('rmdir /s /q "C:\umrinst\"');

 

Moving Files and Directories

This will move the contents of the folder C:\UMRINST\ Boot to the folder C:\WINNT\SYSTEM32\UMRINST:

system ('move /y "C:\umrinst\boot" "C:\winnt\system32\umrinst"');

 

Changing File Permissions

Some products require certain file permissions to be changed in order to allow the product to work correctly for users who are not administrators or power users. The following code changes permissions on the folder C:\Program Files\AutoCAD 2002 to give the group "everyone" full access to this directory and all subdirectories:

system ("echo y|cacls.exe \"c:\\Program Files\\AutoCAD 2002\" /t /c /e /g everyone:f >NUL");

 

Changing File Attributes

This code changes the file attributes on the file C:\hiberfile.sys:

system ('attrib -r -s -h c:\hiberfil.sys');

 

Conditional Installation

Some products depend on other products being installed. In this case, an application script that depends on Oracle checks the registry to see if Oracle client has been installed, and fails to execute if it hasn’t:

$oracle_installed=0;

$reg="Software\\UMR\\INSTALL\\Product_List\\msi_Oracle8i";

$HKEY_LOCAL_MACHINE->Open($reg,$hkey);

if ( $hkey )

{

$oracle_installed=1;

$hkey->Close();

}

$reg="Software\\UMR\\INSTALL\\Product_List\\msi_Oracle9i";

$HKEY_LOCAL_MACHINE->Open($reg,$hkey);

if ( $hkey )

{

$oracle_installed=1;

$hkey->Close();

}

if ($oracle_installed eq 1)

{

#Insert Code to be installed if the

} else {

print "\nThis installation failed because the Oracle client has not been\n";

print "installed.\n";

}

This code will check to see if a machine is a CLC install, and if so, run the application install script:

$HKEY_LOCAL_MACHINE->Open($Register,$hkey)|| die $!;

$hkey->GetKeys(\@key_list);

foreach $key (@key_list)

{

if ($key eq "clc") {

#Insert code to install product here

}

}

$hkey->Close();

 

Adding Registry Keys

The simplest way to do this is to make the changes to the registry manually on a test machine, then export that key using the export feature of regedit. Save the file with the .reg extension. The contents of the reg file will appear as shown below:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system]

"dontdisplaylastusername"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]

"ShowLogonOptions"=dword:00000000

 

To install this .reg file, use the following command in the application install script. This command adds the contents of the .reg file to the system registry, overwriting anything that might already be in the locations specified in the .reg file:

system ('regedit /s c:\winnt\system32\umrinst\whatever.reg');

It’s also possible to add a registry key using Perl directly. This method doesn’t require that a .reg file be created first:

$productkey="msi_visual_studio_7";

$HKEY_LOCAL_MACHINE->Open("$productlistkey",$hkey);

if ($hkey)

{

$hkey->Create($productkey,$skey);

$skey->Close();

$hkey->Close();

}

 

Changing Registry Permissions

This code modifies a list of registry permissions for the keys associated with AutoCAD:

# Grants Everyone full access to Autocad registry keys and files

use Win32::Registry;

$prefix="\\Registry\\Machine";

# 1 Administrators full

# 5 Creator full

# 7 World full

# 17 System Full

$perms="[1 5 7 17]";

$tempfile='c:\temp\t_perms.ini';

@regkeys=(

'SOFTWARE\Classes\AutoCAD.Drawing',

'SOFTWARE\Classes\AutoCAD.Drawing.15',

'SOFTWARE\Classes\CLSID\{83836783-4E7A-11D3-8300-0060B0EF5B11}',

'SOFTWARE\Classes\CLSID\{8E75D913-3D21-11d2-85C4-080009A0C626}',

'SOFTWARE\Autodesk',

);

sub find_keys

# Sends all subkeys (inclusive) of passed parameter to OUTFIL in specified format

{

my($hkey);

my($regkey);

my($i);

my(@key_list);

($regkey)=@_;

$HKEY_LOCAL_MACHINE->Open($regkey,$hkey);

# Some keys may be unopenable; do not include these

if ($hkey)

{

unless ("$prefix\\$regkey" =~ /=/)

# regini has problems with the char '=' in key names

{

print OUTFIL "$prefix\\$regkey $perms\n";

$hkey->GetKeys(\@key_list);

$hkey->Close();

for ($i=0;$i<@key_list;$i++)

{

find_keys($regkey."\\".$key_list[$i]);

}

}

}

}

 

Changing the System Path and other Environment Variables

This code adds a directory to the end of the System Path environment variable:

# Add a directory to the end of the Machine Path

use Win32::Registry;

$path_to_add='C:\Program Files\Common Files\macromedia';

$environmentkey='System\CurrentControlSet\Control\Session Manager\Environment';

$pathvalue='path';

$HKEY_LOCAL_MACHINE->Open("$environmentkey",$hkey);

if ($hkey)

{

$hkey->GetValues(\%values);

foreach $value (keys %values)

{

if (uc $value eq uc $pathvalue)

{

$oldpath=$values{$value}->[2];

$newpath="$oldpath;$path_to_add";

print "Adding path to Local Machine Path environment variable\n";

undef $undefined;

$hkey->SetValueEx($value,$undefined,REG_EXPAND_SZ,$newpath);

}

}

$hkey->Close();

}

else

{

print "Could not open environment.\n";

}

 

Changing Local Groups on NT/2000/XP

Sometimes it becomes necessary to add "everyone" to a group to allow an application to function:

system ('net localgroup "Debugger Users" everyone /add');

 

Changing Windows Service Startup Characteristics

This involves editing a registry key in each case, then rebooting. It is necessary to know the name of the service.

1) Go to the Windows/Control Panel/Services dialog (located in different locations for different OSes).

2) Find the service you wish to start or stop, and double-click it. The service name is shown as "AvSynMgr".

3) To Disable a service at boot (nothing can start this service, even manually), copy this text into a .reg file:

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]

"Start"=dword:00000004

4) To Start a Service at boot, copy this text into a .reg file:

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]

"Start"=dword:00000002

5) To set the service to manual at boot (not started, but can be started manually or by another process), copy this text into a .reg file:

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AvSynMgr]

"Start"=dword:00000002

To install this .reg file, use the following command in the application install script. This command adds the contents of the .reg file to the system registry, overwriting anything that might already be in the locations specified in the .reg file:

system ('regedit /s c:\winnt\system32\umrinst\whatever.reg');

 

Starting and Stopping Windows Services

Sometimes it is necessary to stop an application before it can be updated. The following code will stop a service, execute a script, then start the service again:

system ("net stop avsynmgr");

# Insert script to be run while service is stopped here

system ("net start avsynmgr");

 

Unless otherwise specified, the text and images in this page are the copyrighted property of Bryan A. Thompson, 1996-2008.  All Rights Reserved.